From 3900e3c18a4f3d81fb27e301a677409695152ca5 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Sun, 16 Apr 2023 13:02:09 +0200 Subject: [PATCH 1/5] #18 add edit profile button --- .../composable/PrimaryScreenComposable.kt | 14 ++++++++++++-- .../sel/studeez/screens/home/HomeScreen.kt | 17 ++++++++++++++++- .../studeez/screens/profile/ProfileScreen.kt | 18 +++++++++++++++++- app/src/main/res/values/strings.xml | 4 ++++ 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt index 5983d37..009281f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt @@ -1,8 +1,10 @@ package be.ugent.sel.studeez.common.composable import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.RowScope import androidx.compose.material.* import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Menu import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope @@ -20,6 +22,7 @@ fun PrimaryScreenTemplate( title: String, open: (String) -> Unit, openAndPopUp: (String, String) -> Unit, + action: @Composable RowScope.() -> Unit, content: @Composable (PaddingValues) -> Unit ) { val scaffoldState: ScaffoldState = rememberScaffoldState() @@ -39,7 +42,8 @@ fun PrimaryScreenTemplate( contentDescription = resources().getString(R.string.menu) ) } - } + }, + actions = action ) }, drawerContent = { @@ -62,7 +66,13 @@ fun PrimaryScreenPreview() { PrimaryScreenTemplate( "Preview screen", { _ -> {}}, - { _, _ -> {}} + { _, _ -> {}}, + { IconButton(onClick = { /*TODO*/ }) { + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Edit" + ) + }} ) {} } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index e8c88c1..7ca2559 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -1,5 +1,9 @@ package be.ugent.sel.studeez.screens.home +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Person import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.hilt.navigation.compose.hiltViewModel @@ -18,10 +22,21 @@ fun HomeScreen( PrimaryScreenTemplate( title = resources().getString(R.string.home), open = open, - openAndPopUp = openAndPopUp + openAndPopUp = openAndPopUp, + action = { FriendsAction() } ) { BasicButton(R.string.start_session, Modifier.basicButton()) { viewModel.onStartSessionClick(open) } } +} + +@Composable +fun FriendsAction () { + IconButton(onClick = { /*TODO*/ }) { + Icon( + imageVector = Icons.Default.Person, + contentDescription = resources().getString(R.string.friends) + ) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt index 56568c4..05cf490 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt @@ -1,5 +1,9 @@ package be.ugent.sel.studeez.screens.profile +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Edit import androidx.compose.runtime.* import androidx.hilt.navigation.compose.hiltViewModel import be.ugent.sel.studeez.R @@ -22,8 +26,20 @@ fun ProfileScreen( PrimaryScreenTemplate( title = resources().getString(AppText.profile), open = open, - openAndPopUp = openAndPopUp + openAndPopUp = openAndPopUp, + action = { EditAction() } ) { Headline(text = (username ?: resources().getString(R.string.no_username))) } +} + +@Composable +fun EditAction() { + IconButton(onClick = { /*TODO*/ }) { + Icon( + imageVector = Icons.Default.Edit, + contentDescription = resources().getString(AppText.edit_profile) + ) + + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1f23152..f189ea6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,10 @@ Profile Unknown username + Edit profile + + + Friends Log out From 3ff4f8229859a4056c3bb8deb3b048625c621fce Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Sun, 16 Apr 2023 13:23:51 +0200 Subject: [PATCH 2/5] #18 Move to edit screen on click --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 16 ++++++++-- .../studeez/navigation/StudeezDestinations.kt | 3 ++ .../screens/navbar/NavigationBarViewModel.kt | 1 - .../screens/profile/ProfileEditScreen.kt | 31 +++++++++++++++++++ .../studeez/screens/profile/ProfileScreen.kt | 8 +++-- .../screens/profile/ProfileViewModel.kt | 16 +++------- app/src/main/res/values/strings.xml | 1 + 7 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index fb3aeb2..29f0761 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -20,6 +20,7 @@ import be.ugent.sel.studeez.common.snackbar.SnackbarManager import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.home.HomeScreen import be.ugent.sel.studeez.screens.log_in.LoginScreen +import be.ugent.sel.studeez.screens.profile.EditProfileScreen import be.ugent.sel.studeez.screens.profile.ProfileScreen import be.ugent.sel.studeez.screens.sign_up.SignUpScreen import be.ugent.sel.studeez.screens.splash.SplashScreen @@ -77,12 +78,16 @@ fun resources(): Resources { fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { - val openAndPopUp: (String, String) -> Unit = { - route, popUp -> appState.navigateAndPopUp(route, popUp) + val goBack: () -> Unit = { + appState.popUp() } val open: (String) -> Unit = { - route -> appState.navigate(route) + route -> appState.navigate(route) + } + + val openAndPopUp: (String, String) -> Unit = { + route, popUp -> appState.navigateAndPopUp(route, popUp) } composable(StudeezDestinations.SPLASH_SCREEN) { @@ -110,4 +115,9 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { // TODO Timers screen // TODO Settings screen + + // Edit screens + composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { + EditProfileScreen(goBack) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index a042da1..7b606ca 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -12,4 +12,7 @@ object StudeezDestinations { // const val TIMERS_SCREEN = "timers" // const val SETTINGS_SCREEN = "settings" + + // Edit screens + const val EDIT_PROFILE_SCREEN = "edit_profile" } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt index 1814d84..75613d5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt @@ -2,7 +2,6 @@ package be.ugent.sel.studeez.screens.navbar import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.LogService -import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt new file mode 100644 index 0000000..41fe91e --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt @@ -0,0 +1,31 @@ +package be.ugent.sel.studeez.screens.profile + +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate +import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.ui.theme.StudeezTheme + +@Composable +fun EditProfileScreen( + goBack: () -> Unit +) { + SecondaryScreenTemplate( + title = resources().getString(R.string.editing_profile), + popUp = goBack + ) { + Text(text = "TODO") + } +} + +@Preview +@Composable +fun EditProfileScreenComposable() { + StudeezTheme { + EditProfileScreen { + {} + } + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt index 05cf490..6ec4a01 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt @@ -27,15 +27,17 @@ fun ProfileScreen( title = resources().getString(AppText.profile), open = open, openAndPopUp = openAndPopUp, - action = { EditAction() } + action = { EditAction { viewModel.onEditProfileClick(open) } } ) { Headline(text = (username ?: resources().getString(R.string.no_username))) } } @Composable -fun EditAction() { - IconButton(onClick = { /*TODO*/ }) { +fun EditAction( + onClick: () -> Unit +) { + IconButton(onClick = onClick) { Icon( imageVector = Icons.Default.Edit, contentDescription = resources().getString(AppText.edit_profile) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileViewModel.kt index 1f6b1a2..e24defd 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileViewModel.kt @@ -1,20 +1,10 @@ package be.ugent.sel.studeez.screens.profile -import androidx.compose.runtime.rememberCoroutineScope -import androidx.lifecycle.viewModelScope -import be.ugent.sel.studeez.R import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.UserDAO -import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn - import javax.inject.Inject @HiltViewModel @@ -27,4 +17,8 @@ class ProfileViewModel @Inject constructor( return userDAO.getUsername() } + fun onEditProfileClick(open: (String) -> Unit) { + open(StudeezDestinations.EDIT_PROFILE_SCREEN) + } + } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f189ea6..5edd3b1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,6 +40,7 @@ Profile Unknown username Edit profile + Editing profile Friends From 8ad82dda43f729a2ce994d3977b9da95cc791dab Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Sun, 16 Apr 2023 21:49:56 +0200 Subject: [PATCH 3/5] #18 Basic structure of editing profile screen --- .../common/composable/TextFieldComposable.kt | 15 +++++++++ .../screens/profile/ProfileEditScreen.kt | 30 +++++++++++++++--- .../screens/profile/ProfileEditUiState.kt | 5 +++ .../screens/profile/ProfileEditViewModel.kt | 31 +++++++++++++++++++ app/src/main/res/values/strings.xml | 7 ++++- 5 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditUiState.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt index 5766607..0a0765d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation +import be.ugent.sel.studeez.common.ext.fieldModifier @Composable fun BasicField( @@ -36,6 +37,20 @@ fun BasicField( ) } +@Composable +fun LabelledInputField( + value: String, + onNewValue: (String) -> Unit, + @StringRes label: Int +) { + OutlinedTextField( + value = value, + onValueChange = onNewValue, + label = { Text(text = stringResource(id = label)) }, + modifier = Modifier.fieldModifier() + ) +} + @Composable fun UsernameField( value: String, diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt index 41fe91e..3b5b029 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt @@ -1,22 +1,44 @@ package be.ugent.sel.studeez.screens.profile +import androidx.compose.foundation.layout.Column +import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.viewmodel.compose.viewModel import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.BasicButton +import be.ugent.sel.studeez.common.composable.BasicTextButton +import be.ugent.sel.studeez.common.composable.LabelledInputField import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate +import be.ugent.sel.studeez.common.ext.textButton import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.ui.theme.StudeezTheme @Composable fun EditProfileScreen( - goBack: () -> Unit + goBack: () -> Unit, + viewModel: ProfileEditViewModel = hiltViewModel() ) { + val uiState by viewModel.uiState + SecondaryScreenTemplate( title = resources().getString(R.string.editing_profile), popUp = goBack ) { - Text(text = "TODO") + Column { + LabelledInputField( + value = uiState.username, + onNewValue = viewModel::onUsernameChange, + label = R.string.username + ) + + BasicTextButton(text = R.string.save, Modifier.textButton()) {} // TODO + BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) {} // TODO + } } } @@ -24,8 +46,8 @@ fun EditProfileScreen( @Composable fun EditProfileScreenComposable() { StudeezTheme { - EditProfileScreen { + EditProfileScreen ( {} - } + ) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditUiState.kt new file mode 100644 index 0000000..9ecaba3 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditUiState.kt @@ -0,0 +1,5 @@ +package be.ugent.sel.studeez.screens.profile + +data class ProfileEditUiState ( + val username: String = "" +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt new file mode 100644 index 0000000..5f71016 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt @@ -0,0 +1,31 @@ +package be.ugent.sel.studeez.screens.profile + +import androidx.compose.runtime.mutableStateOf +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class ProfileEditViewModel @Inject constructor( + logService: LogService +) : StudeezViewModel(logService) { + + var uiState = mutableStateOf(ProfileEditUiState()) + private set + + private val username + get() = uiState.value.username + + fun onUsernameChange(newValue: String) { + uiState.value = uiState.value.copy(username = newValue) + } + + fun onSaveClick() { + // TODO + } + + fun onDeleteClick() { + // TODO + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5edd3b1..6590aa3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,11 +7,15 @@ Repeat password Something wrong happened. Please try again. Please insert a valid email. - Cancel Try again Go back Menu + + Confirm + Save + Cancel + Create account Your password should have at least six characters and include one digit, one lower case letter and one upper case letter. @@ -41,6 +45,7 @@ Unknown username Edit profile Editing profile + Delete profile Friends From f263b34c12ece3e635d7438a15a3bf9d47f11c9a Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Sun, 16 Apr 2023 22:08:35 +0200 Subject: [PATCH 4/5] #18 Working update username --- .../common/composable/ButtonComposable.kt | 1 + .../common/composable/TextFieldComposable.kt | 3 +++ .../screens/profile/ProfileEditScreen.kt | 12 +++++----- .../screens/profile/ProfileEditViewModel.kt | 22 +++++++++++++++---- app/src/main/res/values/strings.xml | 9 +++++--- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index e174ef2..64c7352 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -8,6 +8,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.sp @Composable + fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit) { TextButton(onClick = action, modifier = modifier) { Text(text = stringResource(text)) } } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt index 0a0765d..93c0463 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt @@ -1,6 +1,7 @@ package be.ugent.sel.studeez.common.composable import androidx.annotation.StringRes +import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Icon import androidx.compose.material.IconButton @@ -14,8 +15,10 @@ import androidx.compose.runtime.* import be.ugent.sel.studeez.R.string as AppText import be.ugent.sel.studeez.R.drawable as AppIcon import androidx.compose.ui.Modifier +import androidx.compose.ui.input.key.Key import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt index 3b5b029..38fa4cf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt @@ -1,16 +1,12 @@ package be.ugent.sel.studeez.screens.profile import androidx.compose.foundation.layout.Column -import androidx.compose.material.Button -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.viewmodel.compose.viewModel import be.ugent.sel.studeez.R -import be.ugent.sel.studeez.common.composable.BasicButton import be.ugent.sel.studeez.common.composable.BasicTextButton import be.ugent.sel.studeez.common.composable.LabelledInputField import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate @@ -36,8 +32,12 @@ fun EditProfileScreen( label = R.string.username ) - BasicTextButton(text = R.string.save, Modifier.textButton()) {} // TODO - BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) {} // TODO + BasicTextButton(text = R.string.save, Modifier.textButton()) { + viewModel.onSaveClick() + } + BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) { + viewModel.onDeleteClick() + } } } } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt index 5f71016..6a31516 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt @@ -1,31 +1,45 @@ package be.ugent.sel.studeez.screens.profile import androidx.compose.runtime.mutableStateOf +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.snackbar.SnackbarManager +import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.domain.UserDAO import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel class ProfileEditViewModel @Inject constructor( + private val accountDAO: AccountDAO, + private val userDAO: UserDAO, logService: LogService ) : StudeezViewModel(logService) { var uiState = mutableStateOf(ProfileEditUiState()) private set - private val username - get() = uiState.value.username + init { + launchCatching { + uiState.value = uiState.value.copy(username = userDAO.getUsername()!!) + } + } fun onUsernameChange(newValue: String) { uiState.value = uiState.value.copy(username = newValue) } fun onSaveClick() { - // TODO + launchCatching { + userDAO.save(uiState.value.username) + SnackbarManager.showMessage(R.string.save_success) + } } fun onDeleteClick() { - // TODO + launchCatching { + accountDAO.deleteAccount() + } } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6590aa3..41083e7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,9 +5,6 @@ Email Password Repeat password - Something wrong happened. Please try again. - Please insert a valid email. - Try again Go back Menu @@ -16,6 +13,12 @@ Save Cancel + + Saved successfully! + Try again + Something wrong happened. Please try again. + Please insert a valid email. + Create account Your password should have at least six characters and include one digit, one lower case letter and one upper case letter. From 5e2c8de521900ad1551074cc63e8f855a0d7ac5b Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Sun, 16 Apr 2023 22:40:43 +0200 Subject: [PATCH 5/5] #18 Edit and delete profile implemented --- .../main/java/be/ugent/sel/studeez/StudeezApp.kt | 2 +- .../common/composable/TextFieldComposable.kt | 7 ++----- .../be/ugent/sel/studeez/domain/AccountDAO.kt | 1 + .../java/be/ugent/sel/studeez/domain/UserDAO.kt | 6 ++++++ .../domain/implementation/FirebaseUserDAO.kt | 16 ++++++++-------- .../studeez/screens/profile/ProfileEditScreen.kt | 6 ++++-- .../screens/profile/ProfileEditViewModel.kt | 9 ++++++--- .../studeez/screens/sign_up/SignUpViewModel.kt | 5 +---- app/src/main/res/values/strings.xml | 5 +++-- 9 files changed, 32 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 29f0761..3f1e371 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -118,6 +118,6 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { // Edit screens composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { - EditProfileScreen(goBack) + EditProfileScreen(goBack, openAndPopUp) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt index 93c0463..2c0b450 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextFieldComposable.kt @@ -1,7 +1,6 @@ package be.ugent.sel.studeez.common.composable import androidx.annotation.StringRes -import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Icon import androidx.compose.material.IconButton @@ -12,17 +11,15 @@ import androidx.compose.material.icons.filled.Email import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Person import androidx.compose.runtime.* -import be.ugent.sel.studeez.R.string as AppText -import be.ugent.sel.studeez.R.drawable as AppIcon import androidx.compose.ui.Modifier -import androidx.compose.ui.input.key.Key import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import be.ugent.sel.studeez.common.ext.fieldModifier +import be.ugent.sel.studeez.R.drawable as AppIcon +import be.ugent.sel.studeez.R.string as AppText @Composable fun BasicField( diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/AccountDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/AccountDAO.kt index 96ecb74..c813ec6 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/AccountDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/AccountDAO.kt @@ -29,5 +29,6 @@ interface AccountDAO { suspend fun sendRecoveryEmail(email: String) suspend fun signUpWithEmailAndPassword(email: String, password: String) suspend fun deleteAccount() + suspend fun signOut() } diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/UserDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/UserDAO.kt index 8b6f357..b96cf17 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/UserDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/UserDAO.kt @@ -4,4 +4,10 @@ interface UserDAO { suspend fun getUsername(): String? suspend fun save(newUsername: String) + + /** + * Delete all references to this user in the database. Similar to the deleteCascade in + * relational databases. + */ + suspend fun deleteUserReferences() } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseUserDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseUserDAO.kt index 8ac779b..3158b88 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseUserDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseUserDAO.kt @@ -1,19 +1,13 @@ package be.ugent.sel.studeez.domain.implementation -import androidx.compose.runtime.rememberCoroutineScope +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.snackbar.SnackbarManager import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.UserDAO import com.google.firebase.firestore.DocumentReference import com.google.firebase.firestore.FirebaseFirestore -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.tasks.await import javax.inject.Inject -import kotlin.coroutines.coroutineContext class FirebaseUserDAO @Inject constructor( private val firestore: FirebaseFirestore, @@ -34,4 +28,10 @@ class FirebaseUserDAO @Inject constructor( companion object { private const val USER_COLLECTION = "users" } + + override suspend fun deleteUserReferences() { + currentUserDocument().delete() + .addOnSuccessListener { SnackbarManager.showMessage(R.string.success) } + .addOnFailureListener { SnackbarManager.showMessage(R.string.generic_error) } + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt index 38fa4cf..eb12ac7 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt @@ -17,6 +17,7 @@ import be.ugent.sel.studeez.ui.theme.StudeezTheme @Composable fun EditProfileScreen( goBack: () -> Unit, + openAndPopUp: (String, String) -> Unit, viewModel: ProfileEditViewModel = hiltViewModel() ) { val uiState by viewModel.uiState @@ -36,7 +37,7 @@ fun EditProfileScreen( viewModel.onSaveClick() } BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) { - viewModel.onDeleteClick() + viewModel.onDeleteClick(openAndPopUp) } } } @@ -47,7 +48,8 @@ fun EditProfileScreen( fun EditProfileScreenComposable() { StudeezTheme { EditProfileScreen ( - {} + {}, + {_, _ -> {}} ) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt index 6a31516..cb270be 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditViewModel.kt @@ -6,6 +6,7 @@ import be.ugent.sel.studeez.common.snackbar.SnackbarManager import be.ugent.sel.studeez.domain.AccountDAO 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 javax.inject.Inject @@ -33,13 +34,15 @@ class ProfileEditViewModel @Inject constructor( fun onSaveClick() { launchCatching { userDAO.save(uiState.value.username) - SnackbarManager.showMessage(R.string.save_success) + SnackbarManager.showMessage(R.string.success) } } - fun onDeleteClick() { + fun onDeleteClick(openAndPopUp: (String, String) -> Unit) { launchCatching { - accountDAO.deleteAccount() + userDAO.deleteUserReferences() // Delete references + accountDAO.deleteAccount() // Delete authentication } + openAndPopUp(StudeezDestinations.SIGN_UP_SCREEN, StudeezDestinations.EDIT_PROFILE_SCREEN) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt index dacb7db..91dde13 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt @@ -13,11 +13,8 @@ import be.ugent.sel.studeez.navigation.StudeezDestinations.LOGIN_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.SIGN_UP_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.take -import be.ugent.sel.studeez.R.string as AppText import javax.inject.Inject +import be.ugent.sel.studeez.R.string as AppText @HiltViewModel class SignUpViewModel @Inject constructor( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 41083e7..0f3f21b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,16 +5,17 @@ Email Password Repeat password - Go back Menu Confirm Save Cancel + Go back + Next - Saved successfully! + Success! Try again Something wrong happened. Please try again. Please insert a valid email.