Add public profile

This commit is contained in:
Tibo De Peuter 2023-05-15 14:11:55 +02:00
parent bc7753fce5
commit a6a5fb5e95
4 changed files with 255 additions and 0 deletions

View file

@ -0,0 +1,178 @@
package be.ugent.sel.studeez.screens.profile.public_profile
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MailOutline
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.Headline
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
import be.ugent.sel.studeez.common.composable.drawer.DrawerEntry
import be.ugent.sel.studeez.data.local.models.User
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.screens.profile.AmountOfFriendsButton
import be.ugent.sel.studeez.ui.theme.StudeezTheme
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import be.ugent.sel.studeez.R.string as AppText
data class PublicProfileActions(
val getUserDetails: () -> Flow<User>,
val getAmountOfFriends: () -> Flow<Int>,
val onViewFriendsClick: () -> Unit,
val sendFriendRequest: () -> Boolean
)
fun getPublicProfileActions(
viewModel: PublicProfileViewModel,
open: (String) -> Unit
): PublicProfileActions {
return PublicProfileActions(
getUserDetails = { viewModel.getUserDetails(viewModel.uiState.value.userId) },
getAmountOfFriends = { viewModel.getAmountOfFriends(
userId = viewModel.uiState.value.userId
) },
onViewFriendsClick = { viewModel.onViewFriendsClick(open) },
sendFriendRequest = { viewModel.sendFriendRequest(
userId = viewModel.uiState.value.userId
) }
)
}
@Composable
fun PublicProfileRoute(
popUp: () -> Unit,
open: (String) -> Unit,
viewModel: PublicProfileViewModel
) {
PublicProfileScreen(
publicProfileActions = getPublicProfileActions(
viewModel = viewModel,
open = open
),
popUp = popUp
)
}
@Composable
fun PublicProfileScreen(
publicProfileActions: PublicProfileActions,
popUp: () -> Unit
) {
val user = publicProfileActions.getUserDetails().collectAsState(initial = User())
val amountOfFriends = publicProfileActions.getAmountOfFriends().collectAsState(initial = 0)
SecondaryScreenTemplate(
title = stringResource(id = AppText.profile),
popUp = popUp,
barAction = {
PublicProfileEllipsis(
sendFriendRequest = publicProfileActions.sendFriendRequest
)
}
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(15.dp)
) {
item {
Headline(text = user.value.username)
}
item {
Row(
horizontalArrangement = Arrangement.spacedBy(5.dp),
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(align = Alignment.CenterHorizontally)
) {
AmountOfFriendsButton(
amountOfFriends = amountOfFriends.value
) {
publicProfileActions.onViewFriendsClick()
}
}
}
item {
Text(
text = user.value.biography,
textAlign = TextAlign.Center,
modifier = Modifier.padding(48.dp, 0.dp)
)
}
}
}
}
@Preview
@Composable
fun PublicProfilePreview() {
StudeezTheme {
PublicProfileScreen(
publicProfileActions = PublicProfileActions(
getUserDetails = {
flowOf(User(
id = "someid",
username = "Maxime De Poorter",
biography = "I am a different student and this is my public profile"
))
},
getAmountOfFriends = { flowOf(113) },
onViewFriendsClick = {},
sendFriendRequest = { true }
),
popUp = {}
)
}
}
@Composable
fun PublicProfileEllipsis(
sendFriendRequest: () -> Boolean
) {
var expanded by remember { mutableStateOf(false) }
IconButton(
onClick = { expanded = true }
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_more_horizontal),
contentDescription = resources().getString(AppText.view_more),
modifier = Modifier.fillMaxSize()
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
DropdownMenuItem(onClick = { expanded = false }) {
DrawerEntry(
icon = Icons.Default.MailOutline,
text = stringResource(id = AppText.send_friend_request)
) {
sendFriendRequest()
}
}
}
}
@Preview
@Composable
fun PublicProfileEllipsisPreview() {
StudeezTheme {
PublicProfileEllipsis(
sendFriendRequest = { true }
)
}
}

View file

@ -0,0 +1,5 @@
package be.ugent.sel.studeez.screens.profile.public_profile
data class PublicProfileUiState(
var userId: String = ""
)

View file

@ -0,0 +1,60 @@
package be.ugent.sel.studeez.screens.profile.public_profile
import androidx.compose.runtime.mutableStateOf
import be.ugent.sel.studeez.data.local.models.User
import be.ugent.sel.studeez.domain.FriendshipDAO
import be.ugent.sel.studeez.domain.LogService
import be.ugent.sel.studeez.domain.UserDAO
import be.ugent.sel.studeez.navigation.StudeezDestinations
import be.ugent.sel.studeez.screens.StudeezViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.selects.select
import javax.inject.Inject
@HiltViewModel
class PublicProfileViewModel @Inject constructor(
private val userDAO: UserDAO,
private val friendshipDAO: FriendshipDAO,
selectedProfileState: SelectedProfileState,
logService: LogService
): StudeezViewModel(logService) {
val uiState = mutableStateOf(
PublicProfileUiState(
userId = selectedProfileState.selectedUserId
)
)
fun getUserDetails(
userId: String
): Flow<User> {
uiState.value = uiState.value.copy(
userId = userId
)
return userDAO.getUserDetails(
userId = uiState.value.userId
)
}
fun getAmountOfFriends(
userId: String
): Flow<Int> {
return friendshipDAO.getFriendshipCount(
userId = userId
)
}
fun onViewFriendsClick(
open: (String) -> Unit
) {
open(StudeezDestinations.FRIENDS_OVERVIEW_SCREEN)
}
fun sendFriendRequest(
userId: String
): Boolean {
return friendshipDAO.sendFriendshipRequest(userId)
}
}

View file

@ -0,0 +1,12 @@
package be.ugent.sel.studeez.screens.profile.public_profile
import be.ugent.sel.studeez.domain.UserDAO
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SelectedProfileState @Inject constructor(
userDAO: UserDAO
) {
var selectedUserId: String = userDAO.getCurrentUserId()
}