docs: mark M5 done
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wmy1BpCKi8KeSjaWhYuCPV
This commit is contained in:
+49
-8
@@ -10,13 +10,14 @@ Status legend: ✅ done · 🚧 in progress · ⬜ not started
|
||||
|
||||
## Current state (one line)
|
||||
|
||||
✅ **M4 done.** Clockula has a face. Four tabs under an M3 Expressive navigation
|
||||
bar that becomes a wide rail on a tablet, with the back-stack policy and the
|
||||
live pill's whole decision written as pure functions rather than as composable
|
||||
state; the ring screen is real, with a maths or hold challenge that always has a
|
||||
way out — three wrong answers or sixty seconds, whichever comes first. The tabs
|
||||
themselves are still empty states: **M5** (the alarms screen — list, editor,
|
||||
time picker, repeat days, per-alarm overrides) is next.
|
||||
✅ **M5 done.** The Alarms tab is real: a live list that says when each alarm
|
||||
will ring and marks the next one, and an editor that writes as you go — the
|
||||
Material time picker, a repeat-day row that starts on your locale's own first
|
||||
day, a ringtone picker with the device's sounds, a file of your own and a Silent
|
||||
option that still vibrates, and five per-alarm overrides each of which can say
|
||||
"follow the app default" rather than silently copying it. The other three tabs
|
||||
are still empty states: **M6** (timers — multiple concurrent, presets, the
|
||||
foreground service and expiry ringing) is next.
|
||||
|
||||
---
|
||||
|
||||
@@ -202,11 +203,51 @@ plumbing.
|
||||
denial, and the exact-alarm and full-screen-intent grant deep links, moved
|
||||
wholly to M10's self-check, which is the screen with room to say why.
|
||||
|
||||
### ⬜ M5 — Alarms screen
|
||||
### ✅ M5 — Alarms screen
|
||||
List, create, edit, delete, enable/disable. Time picker, repeat-day selector,
|
||||
label, ringtone picker, vibrate, snooze settings, per-alarm overrides. Next-fire
|
||||
line ("in 9h 12m") on each row. Built on `GroupedSurface`/`GroupedRow`.
|
||||
|
||||
✅ 624 JVM tests, 144 of them new, and **still no Robolectric** — kept for a
|
||||
whole *form*, which is where a screen usually reaches for one. Everything a
|
||||
tap decides is a pure object (`AlarmListRows`, `NextFireFormat`,
|
||||
`RepeatDaysSummary`, `AlarmDefaults`, `AlarmOverrides`, `RingtonePicker`,
|
||||
`AudioSourcePolicy`, `AlarmRoutes`) or a ViewModel method tested over the
|
||||
**real** `AlarmEngine`; three new `ArchitectureRulesTest` rules make that a
|
||||
build fact rather than a habit.
|
||||
|
||||
The decisions worth knowing: the next-fire line comes from
|
||||
`AlarmEngine.upcoming`, which grew a `refresh: Flow<Unit>` cadence parameter
|
||||
so the countdown advances without a database write and the screen re-derives
|
||||
none of the engine's time arithmetic; the list is ordered by **time of day**,
|
||||
not by next fire, so rows never swap under a thumb at 07:00; every per-alarm
|
||||
override is an `OptionPicker` whose first row is "App default (On)", because
|
||||
the stored value is ternary and a `Switch` cannot say "I have not chosen";
|
||||
silence is an explicit sentinel (`clockula://silent`) that resolves to an
|
||||
empty audio-source list and therefore forces vibration, so a "silent" alarm
|
||||
is still an alarm; an unreadable sound is reported, never rewritten, because
|
||||
an unmounted card comes back; and every editor write is a transactional
|
||||
read-modify-write, so a one-shot alarm that disabled itself underneath an open
|
||||
editor is not re-enabled by the next unrelated tap.
|
||||
|
||||
The correctness find: disabling or deleting a **ringing** alarm used to clear
|
||||
`ringingSince` without stopping the ring service — whose auto-silence backstop
|
||||
then disarms itself on its own null guard — so the alarm would have sounded
|
||||
until the 15-minute wake-lock timeout. Both new ViewModels now dismiss through
|
||||
the engine first, conditionally, so a merely snoozed alarm keeps its snooze.
|
||||
|
||||
floret-kit went to **0.6.0** for one change: `CollapsingScaffold` takes a
|
||||
`floatingActionButton` slot, forwarded to the underlying `Scaffold`, rather
|
||||
than each app re-deriving the inset maths in a `Box`.
|
||||
|
||||
Knowingly open: no hand reordering of alarms (the time order answers it, and
|
||||
`alarms` has no `sort_order` column), no multi-select or bulk delete, no undo
|
||||
chip after a delete (traded for a confirmation that names the alarm), no
|
||||
repeat presets, and no per-alarm auto-silence — still M10 at the earliest.
|
||||
Editing the app-wide defaults every override row offers to follow is M10's
|
||||
settings screen. The seven new instrumentation tests compile in the gate but
|
||||
have **never run on hardware**, as no device was attached.
|
||||
|
||||
### ⬜ M6 — Timers
|
||||
Multiple concurrent timers, presets, labels, add/pause/reset/+1min. Foreground
|
||||
service with notification controls, expiry ringing reusing M3's audio path.
|
||||
|
||||
Reference in New Issue
Block a user