diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt index c8ae71f..0f48913 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt @@ -19,8 +19,6 @@ package org.nsh07.pomodoro.ui.settingsScreen import android.annotation.SuppressLint import android.app.LocaleManager -import android.content.Intent -import android.net.Uri import android.os.Build import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut @@ -55,7 +53,6 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource @@ -68,7 +65,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation3.runtime.entryProvider import androidx.navigation3.ui.NavDisplay import org.nsh07.pomodoro.R -import org.nsh07.pomodoro.service.TimerService import org.nsh07.pomodoro.ui.Screen import org.nsh07.pomodoro.ui.settingsScreen.components.AboutCard import org.nsh07.pomodoro.ui.settingsScreen.components.ClickableListItem @@ -78,6 +74,7 @@ import org.nsh07.pomodoro.ui.settingsScreen.screens.AlarmSettings import org.nsh07.pomodoro.ui.settingsScreen.screens.AppearanceSettings import org.nsh07.pomodoro.ui.settingsScreen.screens.TimerSettings import org.nsh07.pomodoro.ui.settingsScreen.viewModel.PreferencesState +import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsViewModel import org.nsh07.pomodoro.ui.settingsScreens import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar @@ -92,8 +89,6 @@ fun SettingsScreenRoot( modifier: Modifier = Modifier, viewModel: SettingsViewModel = viewModel(factory = SettingsViewModel.Factory) ) { - val context = LocalContext.current - val backStack = viewModel.backStack DisposableEffect(Unit) { @@ -134,20 +129,7 @@ fun SettingsScreenRoot( vibrateEnabled = vibrateEnabled, dndEnabled = dndEnabled, alarmSound = alarmSound, - onAlarmEnabledChange = viewModel::saveAlarmEnabled, - onVibrateEnabledChange = viewModel::saveVibrateEnabled, - onBlackThemeChange = viewModel::saveBlackTheme, - onAodEnabledChange = viewModel::saveAodEnabled, - onDndEnabledChange = viewModel::saveDndEnabled, - onAlarmSoundChanged = { - viewModel.saveAlarmSound(it) - Intent(context, TimerService::class.java).apply { - action = TimerService.Actions.RESET.toString() - context.startService(this) - } - }, - onThemeChange = viewModel::saveTheme, - onColorSchemeChange = viewModel::saveColorScheme, + onAction = viewModel::onAction, setShowPaywall = setShowPaywall, modifier = modifier ) @@ -168,14 +150,7 @@ private fun SettingsScreen( vibrateEnabled: Boolean, dndEnabled: Boolean, alarmSound: String, - onAlarmEnabledChange: (Boolean) -> Unit, - onVibrateEnabledChange: (Boolean) -> Unit, - onBlackThemeChange: (Boolean) -> Unit, - onAodEnabledChange: (Boolean) -> Unit, - onDndEnabledChange: (Boolean) -> Unit, - onAlarmSoundChanged: (Uri?) -> Unit, - onThemeChange: (String) -> Unit, - onColorSchemeChange: (Color) -> Unit, + onAction: (SettingsAction) -> Unit, setShowPaywall: (Boolean) -> Unit, modifier: Modifier = Modifier ) { @@ -316,9 +291,7 @@ private fun SettingsScreen( alarmEnabled = alarmEnabled, vibrateEnabled = vibrateEnabled, alarmSound = alarmSound, - onAlarmEnabledChange = onAlarmEnabledChange, - onVibrateEnabledChange = onVibrateEnabledChange, - onAlarmSoundChanged = onAlarmSoundChanged, + onAction = onAction, onBack = backStack::removeLastOrNull ) } @@ -326,9 +299,7 @@ private fun SettingsScreen( AppearanceSettings( preferencesState = preferencesState, isPlus = isPlus, - onBlackThemeChange = onBlackThemeChange, - onThemeChange = onThemeChange, - onColorSchemeChange = onColorSchemeChange, + onAction = onAction, setShowPaywall = setShowPaywall, onBack = backStack::removeLastOrNull ) @@ -342,8 +313,7 @@ private fun SettingsScreen( shortBreakTimeInputFieldState = shortBreakTimeInputFieldState, longBreakTimeInputFieldState = longBreakTimeInputFieldState, sessionsSliderState = sessionsSliderState, - onAodEnabledChange = onAodEnabledChange, - onDndEnabledChange = onDndEnabledChange, + onAction = onAction, setShowPaywall = setShowPaywall, onBack = backStack::removeLastOrNull, ) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AlarmSettings.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AlarmSettings.kt index bc46e07..b8ebdb4 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AlarmSettings.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AlarmSettings.kt @@ -17,6 +17,7 @@ package org.nsh07.pomodoro.ui.settingsScreen.screens +import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.media.RingtoneManager @@ -65,6 +66,7 @@ import kotlinx.coroutines.withContext import org.nsh07.pomodoro.R import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem import org.nsh07.pomodoro.ui.settingsScreen.viewModel.PreferencesState +import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors import org.nsh07.pomodoro.ui.theme.CustomColors.switchColors @@ -80,9 +82,7 @@ fun AlarmSettings( alarmEnabled: Boolean, vibrateEnabled: Boolean, alarmSound: String, - onAlarmEnabledChange: (Boolean) -> Unit, - onVibrateEnabledChange: (Boolean) -> Unit, - onAlarmSoundChanged: (Uri?) -> Unit, + onAction: (SettingsAction) -> Unit, onBack: () -> Unit, modifier: Modifier = Modifier ) { @@ -112,10 +112,11 @@ fun AlarmSettings( @Suppress("DEPRECATION") result.data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI) } - onAlarmSoundChanged(uri) + onAction(SettingsAction.SaveAlarmSound(uri)) } } + @SuppressLint("LocalContextGetResourceValueCall") val ringtonePickerIntent = remember(alarmSound) { Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply { putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM) @@ -136,14 +137,14 @@ fun AlarmSettings( icon = R.drawable.alarm_on, label = R.string.sound, description = R.string.alarm_desc, - onClick = onAlarmEnabledChange + onClick = { onAction(SettingsAction.SaveAlarmEnabled(it)) } ), SettingsSwitchItem( checked = vibrateEnabled, icon = R.drawable.mobile_vibrate, label = R.string.vibrate, description = R.string.vibrate_desc, - onClick = onVibrateEnabledChange + onClick = { onAction(SettingsAction.SaveVibrateEnabled(it)) } ) ) } @@ -247,8 +248,6 @@ fun AlarmSettingsPreview() { alarmEnabled = true, vibrateEnabled = false, alarmSound = "", - onAlarmEnabledChange = {}, - onVibrateEnabledChange = {}, - onAlarmSoundChanged = {}, + onAction = {}, onBack = {}) } diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AppearanceSettings.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AppearanceSettings.kt index d5a12ff..755e02d 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AppearanceSettings.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/AppearanceSettings.kt @@ -39,7 +39,6 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -51,6 +50,7 @@ import org.nsh07.pomodoro.ui.settingsScreen.components.ColorSchemePickerListItem import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider import org.nsh07.pomodoro.ui.settingsScreen.components.ThemePickerListItem import org.nsh07.pomodoro.ui.settingsScreen.viewModel.PreferencesState +import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors import org.nsh07.pomodoro.ui.theme.CustomColors.switchColors @@ -64,9 +64,7 @@ import org.nsh07.pomodoro.utils.toColor fun AppearanceSettings( preferencesState: PreferencesState, isPlus: Boolean, - onBlackThemeChange: (Boolean) -> Unit, - onThemeChange: (String) -> Unit, - onColorSchemeChange: (Color) -> Unit, + onAction: (SettingsAction) -> Unit, setShowPaywall: (Boolean) -> Unit, onBack: () -> Unit, modifier: Modifier = Modifier @@ -106,7 +104,7 @@ fun AppearanceSettings( item { ThemePickerListItem( theme = preferencesState.theme, - onThemeChange = onThemeChange, + onThemeChange = { onAction(SettingsAction.SaveTheme(it)) }, items = if (isPlus) 3 else 1, index = 0 ) @@ -122,7 +120,7 @@ fun AppearanceSettings( items = 3, index = if (isPlus) 1 else 0, isPlus = isPlus, - onColorChange = onColorSchemeChange, + onColorChange = { onAction(SettingsAction.SaveColorScheme(it)) }, ) } item { @@ -131,7 +129,7 @@ fun AppearanceSettings( icon = R.drawable.contrast, label = R.string.black_theme, description = R.string.black_theme_desc, - onClick = onBlackThemeChange + onClick = { onAction(SettingsAction.SaveBlackTheme(it)) } ) ListItem( leadingContent = { @@ -180,9 +178,7 @@ fun AppearanceSettingsPreview() { AppearanceSettings( preferencesState = preferencesState, isPlus = false, - onBlackThemeChange = {}, - onThemeChange = {}, - onColorSchemeChange = {}, + onAction = {}, setShowPaywall = {}, onBack = {} ) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt index b0c7ea3..74504f0 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt @@ -36,6 +36,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -76,6 +77,7 @@ import org.nsh07.pomodoro.R import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem import org.nsh07.pomodoro.ui.settingsScreen.components.MinuteInputField import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider +import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors import org.nsh07.pomodoro.ui.theme.CustomColors.switchColors @@ -96,11 +98,10 @@ fun TimerSettings( shortBreakTimeInputFieldState: TextFieldState, longBreakTimeInputFieldState: TextFieldState, sessionsSliderState: SliderState, - onAodEnabledChange: (Boolean) -> Unit, - onDndEnabledChange: (Boolean) -> Unit, + setShowPaywall: (Boolean) -> Unit, + onAction: (SettingsAction) -> Unit, onBack: () -> Unit, - modifier: Modifier = Modifier, - setShowPaywall: (Boolean) -> Unit + modifier: Modifier = Modifier ) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val context = LocalContext.current @@ -110,7 +111,7 @@ fun TimerSettings( LaunchedEffect(Unit) { if (!notificationManagerService.isNotificationPolicyAccessGranted()) - onDndEnabledChange(false) + onAction(SettingsAction.SaveDndEnabled(false)) } val switchItems = listOf( @@ -128,7 +129,7 @@ fun TimerSettings( } else if (!it && notificationManagerService.isNotificationPolicyAccessGranted()) { notificationManagerService.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL) } - onDndEnabledChange(it) + onAction(SettingsAction.SaveDndEnabled(it)) } ), SettingsSwitchItem( @@ -136,7 +137,7 @@ fun TimerSettings( icon = R.drawable.aod, label = R.string.always_on_display, description = R.string.always_on_display_desc, - onClick = onAodEnabledChange + onClick = { onAction(SettingsAction.SaveAodEnabled(it)) } ) ) @@ -313,7 +314,7 @@ fun TimerSettings( item { PlusDivider(setShowPaywall) } - itemsIndexed(switchItems.drop(1)) { index, item -> + items(switchItems.drop(1)) { item -> ListItem( leadingContent = { Icon( @@ -408,8 +409,7 @@ private fun TimerSettingsPreview() { shortBreakTimeInputFieldState = shortBreakTimeInputFieldState, longBreakTimeInputFieldState = longBreakTimeInputFieldState, sessionsSliderState = sessionsSliderState, - onAodEnabledChange = {}, - onDndEnabledChange = {}, + onAction = {}, setShowPaywall = {}, onBack = {} ) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsAction.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsAction.kt new file mode 100644 index 0000000..ae5541a --- /dev/null +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsAction.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Nishant Mishra + * + * This file is part of Tomato - a minimalist pomodoro timer for Android. + * + * Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Tomato. + * If not, see . + */ + +package org.nsh07.pomodoro.ui.settingsScreen.viewModel + +import android.net.Uri +import androidx.compose.ui.graphics.Color + +sealed interface SettingsAction { + data class SaveAlarmEnabled(val enabled: Boolean) : SettingsAction + data class SaveVibrateEnabled(val enabled: Boolean) : SettingsAction + data class SaveBlackTheme(val enabled: Boolean) : SettingsAction + data class SaveAodEnabled(val enabled: Boolean) : SettingsAction + data class SaveDndEnabled(val enabled: Boolean) : SettingsAction + data class SaveAlarmSound(val uri: Uri?) : SettingsAction + data class SaveTheme(val theme: String) : SettingsAction + data class SaveColorScheme(val color: Color) : SettingsAction +} diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt index 94ba2c6..07aa448 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt @@ -103,6 +103,19 @@ class SettingsViewModel( } } + fun onAction(action: SettingsAction) { + when (action) { + is SettingsAction.SaveAlarmSound -> saveAlarmSound(action.uri) + is SettingsAction.SaveAlarmEnabled -> saveAlarmEnabled(action.enabled) + is SettingsAction.SaveVibrateEnabled -> saveVibrateEnabled(action.enabled) + is SettingsAction.SaveDndEnabled -> saveDndEnabled(action.enabled) + is SettingsAction.SaveColorScheme -> saveColorScheme(action.color) + is SettingsAction.SaveTheme -> saveTheme(action.theme) + is SettingsAction.SaveBlackTheme -> saveBlackTheme(action.enabled) + is SettingsAction.SaveAodEnabled -> saveAodEnabled(action.enabled) + } + } + private fun updateSessionLength() { viewModelScope.launch { timerRepository.sessionLength = preferenceRepository.saveIntPreference( @@ -160,35 +173,35 @@ class SettingsViewModel( longBreakFlowCollectionJob?.cancel() } - fun saveAlarmEnabled(enabled: Boolean) { + private fun saveAlarmEnabled(enabled: Boolean) { viewModelScope.launch { timerRepository.alarmEnabled = enabled preferenceRepository.saveBooleanPreference("alarm_enabled", enabled) } } - fun saveVibrateEnabled(enabled: Boolean) { + private fun saveVibrateEnabled(enabled: Boolean) { viewModelScope.launch { timerRepository.vibrateEnabled = enabled preferenceRepository.saveBooleanPreference("vibrate_enabled", enabled) } } - fun saveDndEnabled(enabled: Boolean) { + private fun saveDndEnabled(enabled: Boolean) { viewModelScope.launch { timerRepository.dndEnabled = enabled preferenceRepository.saveBooleanPreference("dnd_enabled", enabled) } } - fun saveAlarmSound(uri: Uri?) { + private fun saveAlarmSound(uri: Uri?) { viewModelScope.launch { timerRepository.alarmSoundUri = uri preferenceRepository.saveStringPreference("alarm_sound", uri.toString()) } } - fun saveColorScheme(colorScheme: Color) { + private fun saveColorScheme(colorScheme: Color) { viewModelScope.launch { _preferencesState.update { currentState -> currentState.copy(colorScheme = colorScheme.toString()) @@ -197,7 +210,7 @@ class SettingsViewModel( } } - fun saveTheme(theme: String) { + private fun saveTheme(theme: String) { viewModelScope.launch { _preferencesState.update { currentState -> currentState.copy(theme = theme) @@ -206,7 +219,7 @@ class SettingsViewModel( } } - fun saveBlackTheme(blackTheme: Boolean) { + private fun saveBlackTheme(blackTheme: Boolean) { viewModelScope.launch { _preferencesState.update { currentState -> currentState.copy(blackTheme = blackTheme) @@ -215,7 +228,7 @@ class SettingsViewModel( } } - fun saveAodEnabled(aodEnabled: Boolean) { + private fun saveAodEnabled(aodEnabled: Boolean) { viewModelScope.launch { _preferencesState.update { currentState -> currentState.copy(aodEnabled = aodEnabled)