fix(alarms): keep a one-shot on when it was given a date mid-snooze
Dismissing a snoozed one-shot switched it off even when the user had just scheduled it for a later date from the editor, so the date never rang. Closing a cycle now leaves a one-shot on while its date is still ahead.
This commit is contained in:
1 parent
247dbcb751
commit
301ce2fec9
3 files changed
+25
-4
No files matched your search
@@ -9,6 +9,7 @@ import de.jeanlucmakiola.clockula.domain.alarm.AlarmResolution
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.AlarmResolver
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.AlarmRing
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.AlarmRingState
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.AlarmSchedule
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.DismissOutcome
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.FireOutcome
|
||||
import de.jeanlucmakiola.clockula.domain.alarm.FireSource
|
||||
@@ -379,7 +380,10 @@ class AlarmEngine @Inject constructor(
|
||||
if (closed != state) states.save(closed)
|
||||
|
||||
val alarm = alarms.find(alarmId)
|
||||
if (alarm != null && !alarm.repeatDays.isRepeating) disableOrDeleteLocked(alarm)
|
||||
// A one-shot given a date while it was snoozed still has that date to
|
||||
// ring on, so this cycle closing does not switch it off (#21).
|
||||
val dateAhead = alarm != null && AlarmSchedule.upcomingDate(alarm, wallClock.now(), zones.current()) != null
|
||||
if (alarm != null && !alarm.repeatDays.isRepeating && !dateAhead) disableOrDeleteLocked(alarm)
|
||||
rescheduleLocked()
|
||||
}
|
||||
}
|
||||
@@ -101,8 +101,9 @@ internal fun ScheduleDatePickerDialog(
|
||||
|
||||
/**
|
||||
* Picks the days a repeating alarm stays quiet on. A start with no end is a
|
||||
* one-day pause. A pause already under way keeps its start, so reopening it
|
||||
* to check or extend it does not rewrite the days already behind it.
|
||||
* one-day pause. A pause already under way opens with its own start, so
|
||||
* reopening it to check it and confirming does not rewrite the days already
|
||||
* behind it. (Tapping a day starts a new range, as in any M3 range picker.)
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -114,7 +115,7 @@ internal fun PauseRangePickerDialog(
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
val start = initial?.start
|
||||
val end = initial?.end?.takeUnless { it.isBefore(today) }
|
||||
val end = initial?.end
|
||||
val earliest = start?.let { minOf(it, today) } ?: today
|
||||
val selectable = remember(earliest) { PickerDates.from(earliest) }
|
||||
val state = rememberDateRangePickerState(
|
||||
|
||||
@@ -121,4 +121,20 @@ class AlarmEngineScheduleTest {
|
||||
|
||||
assertThat(harness.alarmDao.stored.single().pauseStart).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a one-shot given a date while snoozed stays on when the snooze is dismissed`(@TempDir tempDir: Path) =
|
||||
runTest {
|
||||
val harness = alarmEngineHarness(tempDir)
|
||||
harness.givenAlarm(hour = 7)
|
||||
harness.engine.reschedule()
|
||||
harness.givenRinging(alarmId = 1L, at = offsetInstant("2026-06-10T07:00+02:00"))
|
||||
harness.engine.snooze(1L)
|
||||
harness.alarms.edit(1L) { it.copy(scheduledDate = june18) }
|
||||
|
||||
harness.engine.dismiss(1L)
|
||||
|
||||
assertThat(harness.alarms.find(1L)!!.enabled).isTrue()
|
||||
assertThat(harness.scheduler.next).isEqualTo(Registration(offsetInstant("2026-06-18T07:00+02:00"), 1L))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user