From 55de7589eef37210eb4b860791015c7286bc6fe4 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Tue, 16 Sep 2025 00:39:15 +0530 Subject: [PATCH] fix: Fix some major bugs with the URI to string (and vice versa) conversion --- .../org/nsh07/pomodoro/data/PreferenceDao.kt | 7 +++++ .../pomodoro/data/PreferenceRepository.kt | 17 ++++++++++ .../ui/settingsScreen/SettingsScreen.kt | 14 ++++----- .../viewModel/SettingsViewModel.kt | 31 +++++++------------ 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt index a45c53e..72b01bb 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt @@ -11,6 +11,7 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy.Companion.REPLACE import androidx.room.Query +import kotlinx.coroutines.flow.Flow @Dao interface PreferenceDao { @@ -38,6 +39,12 @@ interface PreferenceDao { @Query("SELECT value FROM boolean_preference WHERE `key` = :key") suspend fun getBooleanPreference(key: String): Boolean? + @Query("SELECT value FROM boolean_preference WHERE `key` = :key") + fun getBooleanPreferenceFlow(key: String): Flow + @Query("SELECT value FROM string_preference WHERE `key` = :key") suspend fun getStringPreference(key: String): String? + + @Query("SELECT value FROM string_preference WHERE `key` = :key") + fun getStringPreferenceFlow(key: String): Flow } \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt index c78d29d..4d53239 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt @@ -9,6 +9,7 @@ package org.nsh07.pomodoro.data import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.withContext /** @@ -42,11 +43,21 @@ interface PreferenceRepository { */ suspend fun getBooleanPreference(key: String): Boolean? + /** + * Retrieves a boolean preference key-value pair as a flow from the database. + */ + fun getBooleanPreferenceFlow(key: String): Flow + /** * Retrieves a string preference key-value pair from the database. */ suspend fun getStringPreference(key: String): String? + /** + * Retrieves a string preference key-value pair as a flow from the database. + */ + fun getStringPreferenceFlow(key: String): Flow + /** * Erases all integer preference key-value pairs in the database. Do note that the default values * will need to be rewritten manually @@ -87,10 +98,16 @@ class AppPreferenceRepository( preferenceDao.getBooleanPreference(key) } + override fun getBooleanPreferenceFlow(key: String): Flow = + preferenceDao.getBooleanPreferenceFlow(key) + override suspend fun getStringPreference(key: String): String? = withContext(ioDispatcher) { preferenceDao.getStringPreference(key) } + override fun getStringPreferenceFlow(key: String): Flow = + preferenceDao.getStringPreferenceFlow(key) + override suspend fun resetSettings() = withContext(ioDispatcher) { preferenceDao.resetIntPreferences() preferenceDao.resetBooleanPreferences() 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 c8b6ace..0a2c9af 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 @@ -71,6 +71,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.core.net.toUri import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import org.nsh07.pomodoro.R @@ -101,9 +102,9 @@ fun SettingsScreenRoot( viewModel.longBreakTimeTextFieldState } - val alarmEnabled by viewModel.alarmEnabled.collectAsStateWithLifecycle() - val vibrateEnabled by viewModel.vibrateEnabled.collectAsStateWithLifecycle() - val alarmSound by viewModel.alarmSound.collectAsStateWithLifecycle() + val alarmEnabled by viewModel.alarmEnabled.collectAsStateWithLifecycle(true) + val vibrateEnabled by viewModel.vibrateEnabled.collectAsStateWithLifecycle(true) + val alarmSound by viewModel.alarmSound.collectAsStateWithLifecycle("") val sessionsSliderState = rememberSaveable( saver = SliderState.Saver( @@ -144,7 +145,7 @@ private fun SettingsScreen( sessionsSliderState: SliderState, alarmEnabled: Boolean, vibrateEnabled: Boolean, - alarmSound: Uri?, + alarmSound: String, onAlarmEnabledChange: (Boolean) -> Unit, onVibrateEnabledChange: (Boolean) -> Unit, onAlarmSoundChanged: (Uri?) -> Unit, @@ -155,7 +156,7 @@ private fun SettingsScreen( checkedIconColor = colorScheme.primary, ) - var selectedSoundUri by remember { mutableStateOf(alarmSound) } + var selectedSoundUri by remember(alarmSound) { mutableStateOf(alarmSound.toUri()) } var selectedSoundName by remember { mutableStateOf("...") } val context = LocalContext.current @@ -173,7 +174,6 @@ private fun SettingsScreen( @Suppress("DEPRECATION") result.data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI) } - selectedSoundUri = uri onAlarmSoundChanged(uri) } } @@ -436,7 +436,7 @@ fun SettingsScreenPreview() { sessionsSliderState = rememberSliderState(value = 3f, steps = 3, valueRange = 1f..5f), alarmEnabled = true, vibrateEnabled = true, - alarmSound = Settings.System.DEFAULT_ALARM_ALERT_URI, + alarmSound = Settings.System.DEFAULT_ALARM_ALERT_URI.toString(), onAlarmEnabledChange = {}, onVibrateEnabledChange = {}, onAlarmSoundChanged = {}, 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 0f9d363..6c779c2 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 @@ -20,10 +20,8 @@ import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch import org.nsh07.pomodoro.TomatoApplication import org.nsh07.pomodoro.data.AppPreferenceRepository @@ -48,16 +46,12 @@ class SettingsViewModel( onValueChangeFinished = ::updateSessionLength ) - private val _alarmSound = MutableStateFlow(timerRepository.alarmSoundUri) - val alarmSound: StateFlow = _alarmSound.asStateFlow() - - private val _alarmEnabled: MutableStateFlow = - MutableStateFlow(timerRepository.alarmEnabled) - val alarmEnabled: StateFlow = _alarmEnabled.asStateFlow() - - private val _vibrateEnabled: MutableStateFlow = - MutableStateFlow(timerRepository.alarmEnabled) - val vibrateEnabled: StateFlow = _vibrateEnabled.asStateFlow() + val alarmSound = + preferenceRepository.getStringPreferenceFlow("alarm_sound").distinctUntilChanged() + val alarmEnabled = + preferenceRepository.getBooleanPreferenceFlow("alarm_enabled").distinctUntilChanged() + val vibrateEnabled = + preferenceRepository.getBooleanPreferenceFlow("vibrate_enabled").distinctUntilChanged() init { viewModelScope.launch(Dispatchers.IO) { @@ -109,17 +103,15 @@ class SettingsViewModel( fun saveAlarmEnabled(enabled: Boolean) { viewModelScope.launch { - timerRepository.alarmEnabled = preferenceRepository - .saveBooleanPreference("alarm_enabled", enabled) - _alarmEnabled.value = enabled + preferenceRepository.saveBooleanPreference("alarm_enabled", enabled) + timerRepository.alarmEnabled = enabled } } fun saveVibrateEnabled(enabled: Boolean) { viewModelScope.launch { - timerRepository.vibrateEnabled = preferenceRepository - .saveBooleanPreference("vibrate_enabled", enabled) - _vibrateEnabled.value = enabled + preferenceRepository.saveBooleanPreference("vibrate_enabled", enabled) + timerRepository.vibrateEnabled = enabled } } @@ -127,7 +119,6 @@ class SettingsViewModel( viewModelScope.launch { preferenceRepository.saveStringPreference("alarm_sound", uri.toString()) timerRepository.alarmSoundUri = uri - _alarmSound.value = uri } }