Skip to content

Commit

Permalink
Chore: Unify PushNoficationSettingsScreen and NotificationSettingsU…
Browse files Browse the repository at this point in the history
…i & unsaved changes dialog (#287)
  • Loading branch information
julian-wls authored Jan 17, 2025
1 parent fdcb16a commit faf48d4
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 211 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import de.tum.informatics.www1.artemis.native_app.feature.login.register.Registe
import de.tum.informatics.www1.artemis.native_app.feature.login.saml2_login.Saml2LoginScreen
import de.tum.informatics.www1.artemis.native_app.feature.login.saml2_login.Saml2LoginViewModel
import de.tum.informatics.www1.artemis.native_app.feature.login.service.ServerNotificationStorageService
import de.tum.informatics.www1.artemis.native_app.feature.push.ui.PushNotificationSettingsScreen
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -175,8 +176,9 @@ fun NavGraphBuilder.loginScreen(
}

LoginScreenContent.NOTIFICATION_SETTINGS -> {
NotificationSettingsUi(
PushNotificationSettingsScreen(
modifier = Modifier.fillMaxSize(),
isInitialNotificationSettingsScreen = true,
onDone = {
scope.launch {
serverNotificationStorageService.setHasDisplayed(
Expand Down

This file was deleted.

5 changes: 0 additions & 5 deletions feature/login/src/main/res/values/account_ui_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,4 @@
<string name="login_saml_screen_login_response_unexpected_error">An unexpected error occurred. Please try again or use a different login method.</string>
<string name="login_saml_screen_login_webview_loading">Loading authentication website…</string>
<string name="login_saml_screen_login_webview_try_again">Reload now</string>

<!-- Push notification settings -->
<string name="push_notification_settings_title">Notification configuration</string>
<string name="push_notification_settings_fab_text_with_save">Save &amp; Continue</string>
<string name="push_notification_settings_fab_text_without_save">Continue</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package de.tum.informatics.www1.artemis.native_app.feature.push.ui

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.material.icons.filled.Save
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import de.tum.informatics.www1.artemis.native_app.core.ui.compose.JobAnimatedFloatingActionButton
import de.tum.informatics.www1.artemis.native_app.core.ui.compose.NavigationBackButton
import de.tum.informatics.www1.artemis.native_app.feature.push.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel

/**
* Displays the notification settings screen.
* Contains PushNotificationSettingsUi and is used in the settings screen and after login.
*/
@Composable
fun PushNotificationSettingsScreen(
modifier: Modifier = Modifier,
isInitialNotificationSettingsScreen: Boolean = false,
onDone: () -> Unit
) {
val viewModel: PushNotificationSettingsViewModel = koinViewModel()
val isDirty by viewModel.isDirty.collectAsState(initial = false)

var saveJob: Job? by remember { mutableStateOf(null) }
var displaySyncFailedDialog: Boolean by rememberSaveable { mutableStateOf(false) }
var displayUnsavedChangesDialog: Boolean by rememberSaveable { mutableStateOf(false) }

val onNavigateBack: () -> Unit = {
if (isDirty) {
displayUnsavedChangesDialog = true
} else {
onDone()
}
}
val saveChanges: () -> Unit = {
saveJob = viewModel.saveSettings()
CoroutineScope(Dispatchers.Main).launch {
try {
val isSuccessful = (saveJob as Deferred<Boolean>).await()
if (isSuccessful) {
onDone()
} else {
displayUnsavedChangesDialog = false
displaySyncFailedDialog = true
}
} catch (e: Exception) {
displayUnsavedChangesDialog = false
displaySyncFailedDialog = true
}
}
}

BackHandler {
onNavigateBack()
}

Scaffold(
modifier = modifier,
topBar = {
TopAppBar(
navigationIcon = {
if (isInitialNotificationSettingsScreen) return@TopAppBar

NavigationBackButton(onNavigateBack = {
onNavigateBack()
})
},
title = {
if (isInitialNotificationSettingsScreen) {
Text(text = stringResource(id = R.string.initial_push_notification_settings_title))
} else {
Text(text = stringResource(id = R.string.settings_push_notification_settings_screen_title))
}
}
)
},
floatingActionButton = {
if (isInitialNotificationSettingsScreen) {
ExtendedFloatingActionButton(
onClick = {
// If changes have been made, these need to be synced first.
if (isDirty) saveChanges() else onDone()
},
text = {
Text(
text = stringResource(
id =
if (isDirty) R.string.initial_push_notification_settings_fab_text_with_save
else R.string.initial_push_notification_settings_fab_text_without_save
)
)
},
icon = {
Icon(
imageVector = if (isDirty) Icons.Default.Save else Icons.AutoMirrored.Filled.ArrowForward,
contentDescription = null
)
}
)
} else {
JobAnimatedFloatingActionButton(
enabled = isDirty,
startJob = { viewModel.saveSettings() },
onJobCompleted = { isSuccessful ->
if (!isSuccessful) {
displaySyncFailedDialog = true
}
}
) {
Icon(imageVector = Icons.Default.Save, contentDescription = null)
}
}
}
) { padding ->
PushNotificationSettingsUi(
modifier = Modifier
.fillMaxSize()
.padding(top = padding.calculateTopPadding())
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState())
.padding(
bottom = WindowInsets.systemBars
.asPaddingValues()
.calculateBottomPadding()
),
viewModel = viewModel
)

if (displaySyncFailedDialog) {
PushNotificationSyncFailedDialog {
displaySyncFailedDialog = false
}
}

if (displayUnsavedChangesDialog) {
PushNotificationUnsavedChangesDialog(
onDismissRequest = {
displayUnsavedChangesDialog = false
onDone()
},
onSaveChanges = saveChanges
)
}

if (saveJob != null && isInitialNotificationSettingsScreen) {
PushNotificationSyncChangesDialog(
onDismissRequest = {
saveJob?.cancel()
saveJob = null
}
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,19 @@ fun PushNotificationSyncFailedDialog(onDismissRequest: () -> Unit) {
onPressPositiveButton = onDismissRequest,
onDismissRequest = onDismissRequest
)
}

@Composable
fun PushNotificationUnsavedChangesDialog(
onDismissRequest: () -> Unit,
onSaveChanges: () -> Unit
) {
TextAlertDialog(
title = stringResource(id = R.string.push_notification_settings_unsaved_changes_dialog_title),
text = stringResource(id = R.string.push_notification_settings_unsaved_changes_dialog_message),
confirmButtonText = stringResource(id = R.string.push_notification_settings_unsaved_changes_dialog_positive),
dismissButtonText = stringResource(id = R.string.push_notification_settings_unsaved_changes_dialog_negative),
onPressPositiveButton = onSaveChanges,
onDismissRequest = onDismissRequest
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,15 @@
<string name="push_notification_settings_sync_failed_dialog_title">Syncing failed!</string>
<string name="push_notification_settings_sync_failed_dialog_message">Something went wrong while syncing your settings.</string>
<string name="push_notification_settings_sync_failed_dialog_positive">@android:string/ok</string>

<string name="push_notification_settings_unsaved_changes_dialog_title">You have unsaved changes!</string>
<string name="push_notification_settings_unsaved_changes_dialog_message">Would you like to save your changes before continuing?</string>
<string name="push_notification_settings_unsaved_changes_dialog_positive">Save</string>
<string name="push_notification_settings_unsaved_changes_dialog_negative">Discard</string>

<string name="settings_push_notification_settings_screen_title">Notification settings</string>

<string name="initial_push_notification_settings_title">Notification configuration</string>
<string name="initial_push_notification_settings_fab_text_with_save">Save &amp; Continue</string>
<string name="initial_push_notification_settings_fab_text_without_save">Continue</string>
</resources>
Loading

0 comments on commit faf48d4

Please sign in to comment.