From e6f01096c2e42c6550d673d012e03d381ad1fe6a Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 4 Dec 2025 11:54:40 +0530 Subject: [PATCH] feat(notification): add option to show only current session progress Closes: #162 --- .../nsh07/pomodoro/service/TimerService.kt | 11 +- .../settingsScreen/screens/TimerSettings.kt | 103 +++++++++++++----- .../viewModel/SettingsAction.kt | 1 + .../settingsScreen/viewModel/SettingsState.kt | 1 + .../viewModel/SettingsViewModel.kt | 21 +++- app/src/main/res/drawable/view_day.xml | 26 +++++ app/src/main/res/values/strings.xml | 2 + 7 files changed, 133 insertions(+), 32 deletions(-) create mode 100644 app/src/main/res/drawable/view_day.xml diff --git a/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt b/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt index 3948133..828e220 100644 --- a/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt +++ b/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt @@ -265,7 +265,7 @@ class TimerService : Service() { .setStyle( notificationStyle .setProgress( // Set the current progress by filling the previous intervals and part of the current interval - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA && !settingsState.singleProgressBar) { (totalTime - remainingTime) + ((cycles + 1) / 2) * settingsState.focusTime.toInt() + (cycles / 2) * settingsState.shortBreakTime.toInt() } else (totalTime - remainingTime) ) @@ -288,7 +288,7 @@ class TimerService : Service() { notificationStyle = NotificationCompat.ProgressStyle() .also { // Add all the Focus, Short break and long break intervals in order - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA && !settingsState.singleProgressBar) { // Android 16 and later supports live updates // Set progress bar sections if on Baklava or later for (i in 0..= Build.VERSION_CODES.BAKLAVA) { + item { Spacer(Modifier.height(12.dp)) } + item { + ListItem( + leadingContent = { + Icon(painterResource(R.drawable.view_day), null) + }, + headlineContent = { Text(stringResource(R.string.session_only_progress)) }, + supportingContent = { Text(stringResource(R.string.session_only_progress_desc)) }, + trailingContent = { + Switch( + checked = settingsState.singleProgressBar, + enabled = !serviceRunning, + onCheckedChange = { onAction(SettingsAction.SaveSingleProgressBar(it)) }, + thumbContent = { + if (settingsState.singleProgressBar) { + Icon( + painter = painterResource(R.drawable.check), + contentDescription = null, + modifier = Modifier.size(SwitchDefaults.IconSize), + ) + } else { + Icon( + painter = painterResource(R.drawable.clear), + contentDescription = null, + modifier = Modifier.size(SwitchDefaults.IconSize), + ) + } + }, + colors = switchColors + ) + }, + colors = listItemColors, + modifier = Modifier.clip(cardShape) + ) + } + } + if (!isPlus) { item { PlusDivider(setShowPaywall) @@ -362,7 +413,7 @@ fun TimerSettings( Switch( checked = item.checked, onCheckedChange = { item.onClick(it) }, - enabled = isPlus, + enabled = item.enabled, thumbContent = { if (item.checked) { Icon( 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 index 56e9549..9603809 100644 --- 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 @@ -27,6 +27,7 @@ sealed interface SettingsAction { data class SaveAodEnabled(val enabled: Boolean) : SettingsAction data class SaveDndEnabled(val enabled: Boolean) : SettingsAction data class SaveMediaVolumeForAlarm(val enabled: Boolean) : SettingsAction + data class SaveSingleProgressBar(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/SettingsState.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsState.kt index 8b74711..1ca0165 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsState.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsState.kt @@ -32,6 +32,7 @@ data class SettingsState( val vibrateEnabled: Boolean = true, val dndEnabled: Boolean = false, val mediaVolumeForAlarm: Boolean = false, + val singleProgressBar: Boolean = false, val focusTime: Long = 25 * 60 * 1000L, val shortBreakTime: Long = 5 * 60 * 1000L, 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 d9a3fbe..5a524c2 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 @@ -110,6 +110,7 @@ class SettingsViewModel( is SettingsAction.SaveVibrateEnabled -> saveVibrateEnabled(action.enabled) is SettingsAction.SaveDndEnabled -> saveDndEnabled(action.enabled) is SettingsAction.SaveMediaVolumeForAlarm -> saveMediaVolumeForAlarm(action.enabled) + is SettingsAction.SaveSingleProgressBar -> saveSingleProgressBar(action.enabled) is SettingsAction.SaveColorScheme -> saveColorScheme(action.color) is SettingsAction.SaveTheme -> saveTheme(action.theme) is SettingsAction.SaveBlackTheme -> saveBlackTheme(action.enabled) @@ -273,6 +274,18 @@ class SettingsViewModel( } } + private fun saveSingleProgressBar(singleProgressBar: Boolean) { + viewModelScope.launch { + _settingsState.update { currentState -> + currentState.copy(singleProgressBar = singleProgressBar) + } + preferenceRepository.saveBooleanPreference( + "single_progress_bar", + singleProgressBar + ) + } + } + suspend fun reloadSettings() { var settingsState = _settingsState.value val focusTime = @@ -335,6 +348,11 @@ class SettingsViewModel( "media_volume_for_alarm", settingsState.mediaVolumeForAlarm ) + val singleProgressBar = preferenceRepository.getBooleanPreference("single_progress_bar") + ?: preferenceRepository.saveBooleanPreference( + "single_progress_bar", + settingsState.singleProgressBar + ) _settingsState.update { currentState -> currentState.copy( @@ -350,7 +368,8 @@ class SettingsViewModel( alarmEnabled = alarmEnabled, vibrateEnabled = vibrateEnabled, dndEnabled = dndEnabled, - mediaVolumeForAlarm = mediaVolumeForAlarm + mediaVolumeForAlarm = mediaVolumeForAlarm, + singleProgressBar = singleProgressBar ) } diff --git a/app/src/main/res/drawable/view_day.xml b/app/src/main/res/drawable/view_day.xml new file mode 100644 index 0000000..d9419ca --- /dev/null +++ b/app/src/main/res/drawable/view_day.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 441470e..0cd5947 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -105,4 +105,6 @@ License Headphone mode Plays on headphones only. If headphones are disconnected, alarm plays through speaker at media volume. + Session-only progress + Show progress for the current session only in notifications, rather than the full sequence. \ No newline at end of file