refactor(settings): read a silence-after of an hour or more as Never

A stored value of 60 minutes or more now reads as Never, which rings that
long anyway. The picker no longer shows both "60 minutes" and "Never" for
the same window. Also drops a redundant null check in TimerRingPolicy.

Refs #17
This commit is contained in:
makiolaj committed 2026-10-21 19:45:44 +02:00
1 parent 1689794da6
commit 6239ca0477
6 files changed
+12 -10

No files matched your search

@@ -44,13 +44,14 @@ object SilenceAfter {
/**
* What a stored value is read and written as, from a picker, a hand-edited
* file or a backup. Too long is the hard stop, which is what it would ring
* for anyway. Negative is nothing anyone chose, so it is the default rather
* file or a backup. The hard stop or longer is "Never", which rings that
* long anyway, so the picker never shows two names for one window. Negative is nothing anyone chose, so it is the default rather
* than the clamp's floor, which would be "Never".
*/
fun sanitise(minutes: Int): Int = when {
minutes < MINUTES.first -> DEFAULT_MINUTES
else -> minutes.coerceAtMost(MINUTES.last)
minutes >= HARD_STOP_MINUTES -> NEVER
else -> minutes
}
/** The ring window [minutes] stands for, sanitised first so the engines never see an unofferable value. */
@@ -68,7 +68,7 @@ object TimerRingPolicy {
// Auto-silence before suppression: a window that has run out stays run
// out, and an alarm ringing over it must not hand it a fresh one.
val window = defaults.timerSilenceAfter
if (soundingSince != null && isLapsed(soundingSince, now, window)) {
if (soundingSince != null && now - soundingSince >= window) {
return TimerRingOutcome(
TimerRingDecision.AutoSilenced(subject.timer.id),
// Raising the setting later cannot start a silenced timer ringing again.
@@ -161,7 +161,7 @@ class ClockPrefsTest {
prefs.setAlarmSilenceAfterMinutes(999)
prefs.setTimerSilenceAfterMinutes(-3)
assertThat(prefs.defaults.first().alarmSilenceAfterMinutes).isEqualTo(60)
assertThat(prefs.defaults.first().alarmSilenceAfterMinutes).isEqualTo(SilenceAfter.NEVER)
assertThat(prefs.defaults.first().timerSilenceAfterMinutes).isEqualTo(SilenceAfter.DEFAULT_MINUTES)
dataStore.updateData { stored ->
@@ -7,6 +7,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import de.jeanlucmakiola.clockula.domain.ClockDefaults
import de.jeanlucmakiola.clockula.domain.ring.SilenceAfter
import de.jeanlucmakiola.clockula.domain.backup.BackupSettings
import de.jeanlucmakiola.floret.prefs.Appearance
import de.jeanlucmakiola.floret.prefs.PrefStore
@@ -91,7 +92,7 @@ class SettingsPrefsTest {
assertThat(prefs.currentDefaults().volumeRampSeconds).isEqualTo(60)
assertThat(prefs.currentDefaults().alarmRingtoneUri).isNull()
assertThat(prefs.currentDefaults().alarmSilenceAfterMinutes).isEqualTo(25)
assertThat(prefs.currentDefaults().timerSilenceAfterMinutes).isEqualTo(60)
assertThat(prefs.currentDefaults().timerSilenceAfterMinutes).isEqualTo(SilenceAfter.NEVER)
assertThat(prefs.timerPresets.first()).containsExactly(1.minutes, 5.minutes).inOrder()
}
+2 -2
View File
@@ -1175,8 +1175,8 @@ from ringing until its battery is flat, what bounds the ring services' wake
locks, and what keeps a reboot hours later from resuming a ring nobody was
there for. So "Never" maps to `SilenceAfter.HARD_STOP` (60 minutes), longer
than any finite choice, and the settings hint says so in words. Stored values
go through `SilenceAfter.sanitise` on read, on write and from a backup: over 60
is 60, so no value can make a ring outlast the hard stop, and a negative one is
go through `SilenceAfter.sanitise` on read, on write and from a backup: 60 or more
is "Never", so no value can make a ring outlast the hard stop, and a negative one is
the default rather than the clamp's floor, which would be "Never".
Changing the setting mid-ring applies at once. The settings screen writes it
+2 -2
View File
@@ -151,8 +151,8 @@ other unknown field.
are how long a ringing alarm or a finished timer keeps going before it stops on
its own: whole minutes, with `0` meaning "Never" (which still stops after an
hour). A file without them, from before the setting existed, imports as `10`,
the value it was made with. A value over 60 reads as 60 (which is what Never
rings for anyway); a negative one reads as the default, 10.
the value it was made with. A value of 60 or more reads as 0, "Never" (which
rings for that long anyway); a negative one reads as the default, 10.
Every numeric/duration value is clamped on *apply* using the same ranges and encoding
as the existing preference setters, never on parse.