diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/models/NotificationViewModel.kt b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/models/NotificationViewModel.kt new file mode 100644 index 0000000..93629f7 --- /dev/null +++ b/app/src/main/java/app/myzel394/alibi/ui/components/CustomRecordingNotificationsScreen/models/NotificationViewModel.kt @@ -0,0 +1,67 @@ +package app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.models + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import app.myzel394.alibi.R +import app.myzel394.alibi.db.NotificationSettings + +class NotificationViewModel : ViewModel() { + // We want to show the actual translated strings of the preset + // in the preview but don't want to save them to the database + // because they should be retrieved in the notification itself. + // Thus we save whether the preset has been changed by the user + private var _presetChanged = false + + private var _title = mutableStateOf("") + val title: String + get() = _title.value + private var _description = mutableStateOf("") + val description: String + get() = _description.value + + var showOngoing: Boolean by mutableStateOf(true) + var icon: Int by mutableIntStateOf(R.drawable.launcher_monochrome_noopacity) + + // `preset` can't be used as a variable name here because + // the compiler throws a strange error then + var notificationPreset: NotificationSettings.Preset? by mutableStateOf(null) + + private var _hasBeenInitialized = false; + + + fun setPreset(title: String, description: String, preset: NotificationSettings.Preset) { + _presetChanged = false + + _title.value = title + _description.value = description + showOngoing = preset.showOngoing + icon = preset.iconID + this.notificationPreset = preset + } + + fun setTitle(title: String) { + _presetChanged = true + _title.value = title + } + + fun setDescription(description: String) { + _presetChanged = true + _description.value = description + } + + fun initialize( + title: String, + description: String, + ) { + if (_hasBeenInitialized) { + return + } + + _title.value = title + _description.value = description + _hasBeenInitialized = true + } +} 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 9f019fd..0852cf3 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, NotificationSettings.Preset) -> Unit, + onClick: (String, String, NotificationSettings.Preset) -> Unit, ) { val state = rememberLazyListState() @@ -60,8 +60,6 @@ fun NotificationPresetsRoulette( onClick( presetTitle, presetDescription, - preset.iconID, - preset.showOngoing, 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 edf34bc..62a04bf 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 @@ -1,13 +1,9 @@ package app.myzel394.alibi.ui.components.CustomRecordingNotificationsScreen.organisms import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.ScrollState import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.FlingBehavior -import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -17,47 +13,31 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.CheckCircle -import androidx.compose.material.icons.filled.Notifications -import androidx.compose.material.icons.filled.Save import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Checkbox -import androidx.compose.material3.CheckboxColors import androidx.compose.material3.CheckboxDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text 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.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import app.myzel394.alibi.R import app.myzel394.alibi.db.NotificationSettings -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.models.NotificationViewModel 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; @@ -65,25 +45,17 @@ val HORIZONTAL_PADDING = 16.dp; @Composable fun NotificationEditor( modifier: Modifier = Modifier, + notificationModel: NotificationViewModel = viewModel(), 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) - var title: String by rememberSaveable { - mutableStateOf(defaultTitle) - } - var description: String by rememberSaveable { - mutableStateOf(defaultDescription) - } - var showOngoing: Boolean by rememberSaveable { - mutableStateOf(true) - } - var icon: Int by rememberSaveable { - mutableIntStateOf(R.drawable.launcher_monochrome_noopacity) - } - var preset: NotificationSettings.Preset? by remember { - mutableStateOf(null) + LaunchedEffect(defaultTitle, defaultDescription) { + notificationModel.initialize( + defaultTitle, + defaultDescription, + ) } Column( @@ -101,21 +73,17 @@ fun NotificationEditor( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), - showOngoing = showOngoing, - title = title, - description = description, - icon = painterResource(icon), + showOngoing = notificationModel.showOngoing, + title = notificationModel.title, + description = notificationModel.description, + icon = painterResource(notificationModel.icon), onShowOngoingChange = { - showOngoing = it - }, - onTitleChange = { - title = it - }, - onDescriptionChange = { - description = it + notificationModel.showOngoing = it }, + onTitleChange = notificationModel::setTitle, + onDescriptionChange = notificationModel::setDescription, onIconChange = { - icon = it + notificationModel.icon = it }, ) @@ -126,15 +94,15 @@ fun NotificationEditor( .fillMaxWidth() .clip(MaterialTheme.shapes.medium) .clickable { - showOngoing = showOngoing.not() + notificationModel.showOngoing = notificationModel.showOngoing.not() } .background(MaterialTheme.colorScheme.tertiaryContainer) .padding(8.dp), ) { Checkbox( - checked = showOngoing, + checked = notificationModel.showOngoing, onCheckedChange = { - showOngoing = it + notificationModel.showOngoing = it }, colors = CheckboxDefaults.colors( checkedColor = MaterialTheme.colorScheme.tertiary, @@ -154,23 +122,17 @@ fun NotificationEditor( verticalArrangement = Arrangement.spacedBy(32.dp), ) { NotificationPresetsRoulette( - onClick = { presetTitle, presetDescription, presetIcon, presetShowOngoing, newPreset -> - title = presetTitle - description = presetDescription - icon = presetIcon - showOngoing = presetShowOngoing - preset = newPreset - } + onClick = notificationModel::setPreset, ) Button( onClick = { onNotificationChange( - title, - description, - icon, - showOngoing, - preset, + notificationModel.title, + notificationModel.description, + notificationModel.icon, + notificationModel.showOngoing, + notificationModel.notificationPreset, ) }, modifier = Modifier