From 15bb9b405125242b8dc1a195a1ce8e080ead07a0 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:22:05 +0200 Subject: [PATCH] feat: Improve CustomRecordingNotificationsScreen behavior; Add save support (wip) --- .../java/app/myzel394/alibi/db/AppSettings.kt | 11 ++++ .../atoms/LandingElement.kt | 3 +- .../molecules/NotificationPresetsRoulette.kt | 3 +- .../organisms/NotificationEditor.kt | 21 +++++-- .../CustomRecordingNotificationsScreen.kt | 58 ++++++++++++++++--- 5 files changed, 82 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt index a91b4ab..236d2e6 100644 --- a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt +++ b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt @@ -28,6 +28,10 @@ data class AppSettings( return copy(audioRecorderSettings = audioRecorderSettings) } + fun setNotificationSettings(notificationSettings: NotificationSettings?): AppSettings { + return copy(notificationSettings = notificationSettings) + } + fun setHasSeenOnboarding(hasSeenOnboarding: Boolean): AppSettings { return copy(hasSeenOnboarding = hasSeenOnboarding) } @@ -418,6 +422,7 @@ data class AudioRecorderSettings( data class NotificationSettings( val title: String, val message: String, + val iconID: Int, val showOngoing: Boolean, val preset: Preset? = null, ) { @@ -428,6 +433,7 @@ data class NotificationSettings( val showOngoing: Boolean, val iconID: Int, ) { + @Serializable data object Default : Preset( R.string.ui_audioRecorder_state_recording_title, R.string.ui_audioRecorder_state_recording_description, @@ -435,6 +441,7 @@ data class NotificationSettings( R.drawable.launcher_monochrome_noopacity, ) + @Serializable data object Weather : Preset( R.string.ui_audioRecorder_state_recording_fake_weather_title, R.string.ui_audioRecorder_state_recording_fake_weather_description, @@ -442,6 +449,7 @@ data class NotificationSettings( R.drawable.ic_cloud ) + @Serializable data object Player : Preset( R.string.ui_audioRecorder_state_recording_fake_player_title, R.string.ui_audioRecorder_state_recording_fake_player_description, @@ -449,6 +457,7 @@ data class NotificationSettings( R.drawable.ic_note, ) + @Serializable data object Browser : Preset( R.string.ui_audioRecorder_state_recording_fake_browser_title, R.string.ui_audioRecorder_state_recording_fake_browser_description, @@ -456,6 +465,7 @@ data class NotificationSettings( R.drawable.ic_download, ) + @Serializable data object VPN : Preset( R.string.ui_audioRecorder_state_recording_fake_vpn_title, R.string.ui_audioRecorder_state_recording_fake_vpn_description, @@ -470,6 +480,7 @@ data class NotificationSettings( title = "", message = "", showOngoing = preset.showOngoing, + iconID = preset.iconID, preset = preset, ) } diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/atoms/LandingElement.kt b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/atoms/LandingElement.kt index 08cebaa..ae45bf1 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/atoms/LandingElement.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/atoms/LandingElement.kt @@ -36,6 +36,7 @@ import app.myzel394.alibi.ui.utils.openNotificationsSettings @Composable fun LandingElement( modifier: Modifier = Modifier, + onOpenEditor: () -> Unit, ) { val context = LocalContext.current @@ -82,7 +83,7 @@ fun LandingElement( style = MaterialTheme.typography.bodySmall, ) Button( - onClick = {}, + onClick = onOpenEditor, colors = ButtonDefaults.filledTonalButtonColors(), ) { Icon( diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/molecules/NotificationPresetsRoulette.kt b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/molecules/NotificationPresetsRoulette.kt index 81bd4bc..9f019fd 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/molecules/NotificationPresetsRoulette.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/molecules/NotificationPresetsRoulette.kt @@ -24,7 +24,7 @@ import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.atoms @OptIn(ExperimentalFoundationApi::class) @Composable fun NotificationPresetsRoulette( - onClick: (String, String, Int, Boolean) -> Unit, + onClick: (String, String, Int, Boolean, NotificationSettings.Preset) -> Unit, ) { val state = rememberLazyListState() @@ -62,6 +62,7 @@ fun NotificationPresetsRoulette( presetDescription, preset.iconID, preset.showOngoing, + preset, ) }, preset = preset, diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/organisms/NotificationEditor.kt b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/organisms/NotificationEditor.kt index 3396077..edf34bc 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/organisms/NotificationEditor.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/organisms/NotificationEditor.kt @@ -37,6 +37,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf 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.Alignment @@ -56,6 +57,7 @@ import app.myzel394.alibi.ui.BIG_PRIMARY_BUTTON_SIZE import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.atoms.NotificationPresetSelect import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.molecules.EditNotificationInput import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.molecules.NotificationPresetsRoulette +import kotlinx.coroutines.newFixedThreadPoolContext val HORIZONTAL_PADDING = 16.dp; @@ -63,7 +65,7 @@ val HORIZONTAL_PADDING = 16.dp; @Composable fun NotificationEditor( modifier: Modifier = Modifier, - scrollState: ScrollState, + onNotificationChange: (String, String, Int, Boolean, NotificationSettings.Preset?) -> Unit, ) { val defaultTitle = stringResource(R.string.ui_audioRecorder_state_recording_title) val defaultDescription = stringResource(R.string.ui_audioRecorder_state_recording_description) @@ -80,8 +82,10 @@ fun NotificationEditor( var icon: Int by rememberSaveable { mutableIntStateOf(R.drawable.launcher_monochrome_noopacity) } + var preset: NotificationSettings.Preset? by remember { + mutableStateOf(null) + } - // TODO: Add Preview functionality Column( modifier = Modifier .fillMaxSize() @@ -150,16 +154,25 @@ fun NotificationEditor( verticalArrangement = Arrangement.spacedBy(32.dp), ) { NotificationPresetsRoulette( - onClick = { presetTitle, presetDescription, presetIcon, presetShowOngoing -> + onClick = { presetTitle, presetDescription, presetIcon, presetShowOngoing, newPreset -> title = presetTitle description = presetDescription icon = presetIcon showOngoing = presetShowOngoing + preset = newPreset } ) Button( - onClick = { /*TODO*/ }, + onClick = { + onNotificationChange( + title, + description, + icon, + showOngoing, + preset, + ) + }, modifier = Modifier .fillMaxWidth() .padding(horizontal = HORIZONTAL_PADDING) diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/CustomRecordingNotificationsScreen.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/CustomRecordingNotificationsScreen.kt index a574751..c6c9008 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/screens/CustomRecordingNotificationsScreen.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/screens/CustomRecordingNotificationsScreen.kt @@ -22,7 +22,13 @@ import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext @@ -35,9 +41,11 @@ import app.myzel394.alibi.R import app.myzel394.alibi.dataStore import app.myzel394.alibi.db.AppSettings import app.myzel394.alibi.db.NotificationSettings +import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.atoms.LandingElement import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.atoms.NotificationPresetSelect import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.molecules.EditNotificationInput import app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.organisms.NotificationEditor +import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -47,7 +55,6 @@ fun CustomRecordingNotificationsScreen( val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior( rememberTopAppBarState() ) - val scrollState = rememberScrollState() val dataStore = LocalContext.current.dataStore val settings = dataStore @@ -55,6 +62,16 @@ fun CustomRecordingNotificationsScreen( .collectAsState(initial = AppSettings.getDefaultInstance()) .value + var showEditor: Boolean by rememberSaveable { + mutableStateOf(false) + } + + LaunchedEffect(settings.notificationSettings) { + if (settings.notificationSettings != null) { + showEditor = true + } + } + Scaffold( topBar = { TopAppBar( @@ -75,13 +92,38 @@ fun CustomRecordingNotificationsScreen( modifier = Modifier .nestedScroll(scrollBehavior.nestedScrollConnection) ) { padding -> - if (settings.notificationSettings == null) { + if (showEditor) { + val scope = rememberCoroutineScope() + + NotificationEditor( + modifier = Modifier + .padding(padding) + .padding(vertical = 16.dp), + onNotificationChange = { title, description, icon, showOngoing, preset -> + scope.launch { + dataStore.updateData { settings -> + settings.setNotificationSettings( + if (preset == null) { + NotificationSettings( + title = title, + message = description, + iconID = icon, + showOngoing = showOngoing, + ) + } else { + NotificationSettings.fromPreset(preset) + } + ) + } + } + } + ) + } else { + LandingElement( + onOpenEditor = { + showEditor = true + } + ) } - NotificationEditor( - modifier = Modifier - .padding(padding) - .padding(vertical = 16.dp), - scrollState = scrollState, - ) } } \ No newline at end of file