From a709582234a4f648e4be5177d2d80dcd1cc9b129 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 10:05:45 +0000 Subject: [PATCH] Switch an alarm on when its time is changed Setting a time is how you set an alarm, so picking a new one on a switched-off alarm and leaving it off just means it silently doesn't ring. The stock Clock app enables on edit for the same reason. The quick time popup always enables, since changing the time is the only thing it does. The full editor sheet enables only when the time actually changed: that sheet has no on/off switch of its own - it lives on the list row - so saving after merely renaming a switched-off alarm must not quietly turn it on. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01C7x8v5c5Lu29PBWy1LdfCe --- README.md | 6 ++++++ .../haalarmclock/data/AlarmRepository.kt | 7 +++++-- .../haalarmclock/ui/editor/AlarmEditorViewModel.kt | 13 ++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ca5805..87d7cb5 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,12 @@ aren't obvious from using it. about, unlike a timer, so there's nothing worth a permanent notification for; it keeps running across tab swipes and a trip to Settings and back (both stay under the same `TabsScreen` back-stack entry) but not past the app process being killed. +- **Changing an alarm's time switches it on**, the way the stock Clock app does. Setting a + time is how you set an alarm, so picking one on a switched-off alarm and leaving it off + would just mean it silently doesn't ring. The quick time popup always enables; the full + editor sheet only does so when the time actually changed, since that sheet has no on/off + switch of its own (that lives on the list row) and merely renaming a switched-off alarm + shouldn't quietly turn it on. - **Editing is in-place, not a separate screen.** Tap an alarm's time for a quick time-only popup — which now also has a Delete action, so removing an alarm doesn't require opening the full editor either — or tap its label/repeat area for the full diff --git a/app/src/main/java/com/targetcrafter/haalarmclock/data/AlarmRepository.kt b/app/src/main/java/com/targetcrafter/haalarmclock/data/AlarmRepository.kt index 3d471db..8d45128 100644 --- a/app/src/main/java/com/targetcrafter/haalarmclock/data/AlarmRepository.kt +++ b/app/src/main/java/com/targetcrafter/haalarmclock/data/AlarmRepository.kt @@ -48,10 +48,13 @@ class AlarmRepository( save(alarm.copy(enabled = enabled)) } - /** Updates just the time, leaving every other setting untouched — used by the quick time-edit popup. */ + /** Updates just the time, leaving every other setting untouched — used by the quick time-edit + * popup — and switches the alarm on. Setting a time is how you set an alarm: picking one on a + * switched-off alarm and having it stay off means it silently won't ring, which is never what + * was meant. Matches the stock Clock app. */ suspend fun updateTime(id: Long, hour: Int, minute: Int) { val alarm = dao.getById(id) ?: return - save(alarm.copy(hour = hour, minute = minute)) + save(alarm.copy(hour = hour, minute = minute, enabled = true)) } /** Re-arms every enabled alarm's AlarmManager entry; alarms don't survive a reboot on their own. diff --git a/app/src/main/java/com/targetcrafter/haalarmclock/ui/editor/AlarmEditorViewModel.kt b/app/src/main/java/com/targetcrafter/haalarmclock/ui/editor/AlarmEditorViewModel.kt index d5d06c2..fac07e6 100644 --- a/app/src/main/java/com/targetcrafter/haalarmclock/ui/editor/AlarmEditorViewModel.kt +++ b/app/src/main/java/com/targetcrafter/haalarmclock/ui/editor/AlarmEditorViewModel.kt @@ -43,12 +43,17 @@ class AlarmEditorViewModel( private val _state = MutableStateFlow(AlarmEditorUiState(isNew = alarmId == null)) val state: StateFlow = _state.asStateFlow() + /** The time an existing alarm had when the sheet opened, so [save] can tell whether the user + * actually changed it. Null for a new alarm, which starts switched on anyway. */ + private var loadedTime: Pair? = null + init { val defaults = appDefaultsStore.defaults.value val id = alarmId if (id != null) { viewModelScope.launch { val alarm = repository.getById(id) + loadedTime = alarm?.let { it.hour to it.minute } _state.value = if (alarm != null) { AlarmEditorUiState( id = alarm.id, @@ -107,6 +112,12 @@ class AlarmEditorViewModel( fun save(onDone: () -> Unit) { val s = _state.value + // Changing the time switches the alarm on, the same as the quick time popup does: picking + // a new time for a switched-off alarm and leaving it off means it silently won't ring. + // Only when the time actually changed, though — this sheet has no on/off switch of its own + // (that lives on the list row), so saving it after only renaming a switched-off alarm must + // not quietly turn it on. + val timeChanged = loadedTime?.let { (hour, minute) -> hour != s.hour || minute != s.minute } ?: false viewModelScope.launch { repository.save( Alarm( @@ -114,7 +125,7 @@ class AlarmEditorViewModel( hour = s.hour, minute = s.minute, label = s.label, - enabled = s.enabled, + enabled = s.enabled || timeChanged, repeatDaysMask = s.repeatDaysMask, vibrate = s.vibrate, fadeInEnabled = s.fadeInEnabled,