From a6a5fb5e958548d318054063dc3d37405cdd7337 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Mon, 15 May 2023 14:11:55 +0200 Subject: [PATCH] Add public profile --- .../public_profile/PublicProfileScreen.kt | 178 ++++++++++++++++++ .../public_profile/PublicProfileUiState.kt | 5 + .../public_profile/PublicProfileViewModel.kt | 60 ++++++ .../public_profile/SelectedProfileState.kt | 12 ++ 4 files changed, 255 insertions(+) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileUiState.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileViewModel.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/SelectedProfileState.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileScreen.kt new file mode 100644 index 0000000..41e33c5 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileScreen.kt @@ -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, + val getAmountOfFriends: () -> Flow, + 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 } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileUiState.kt new file mode 100644 index 0000000..537fed9 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileUiState.kt @@ -0,0 +1,5 @@ +package be.ugent.sel.studeez.screens.profile.public_profile + +data class PublicProfileUiState( + var userId: String = "" +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileViewModel.kt new file mode 100644 index 0000000..6cf22d9 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/PublicProfileViewModel.kt @@ -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 { + uiState.value = uiState.value.copy( + userId = userId + ) + return userDAO.getUserDetails( + userId = uiState.value.userId + ) + } + + fun getAmountOfFriends( + userId: String + ): Flow { + return friendshipDAO.getFriendshipCount( + userId = userId + ) + } + + fun onViewFriendsClick( + open: (String) -> Unit + ) { + open(StudeezDestinations.FRIENDS_OVERVIEW_SCREEN) + } + + fun sendFriendRequest( + userId: String + ): Boolean { + return friendshipDAO.sendFriendshipRequest(userId) + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/SelectedProfileState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/SelectedProfileState.kt new file mode 100644 index 0000000..4226d65 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/public_profile/SelectedProfileState.kt @@ -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() +} \ No newline at end of file