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)
|
## Current state (one line)
|
||||||
|
|
||||||
✅ **M4 done.** Clockula has a face. Four tabs under an M3 Expressive navigation
|
✅ **M5 done.** The Alarms tab is real: a live list that says when each alarm
|
||||||
bar that becomes a wide rail on a tablet, with the back-stack policy and the
|
will ring and marks the next one, and an editor that writes as you go — the
|
||||||
live pill's whole decision written as pure functions rather than as composable
|
Material time picker, a repeat-day row that starts on your locale's own first
|
||||||
state; the ring screen is real, with a maths or hold challenge that always has a
|
day, a ringtone picker with the device's sounds, a file of your own and a Silent
|
||||||
way out — three wrong answers or sixty seconds, whichever comes first. The tabs
|
option that still vibrates, and five per-alarm overrides each of which can say
|
||||||
themselves are still empty states: **M5** (the alarms screen — list, editor,
|
"follow the app default" rather than silently copying it. The other three tabs
|
||||||
time picker, repeat days, per-alarm overrides) is next.
|
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
|
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.
|
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,
|
List, create, edit, delete, enable/disable. Time picker, repeat-day selector,
|
||||||
label, ringtone picker, vibrate, snooze settings, per-alarm overrides. Next-fire
|
label, ringtone picker, vibrate, snooze settings, per-alarm overrides. Next-fire
|
||||||
line ("in 9h 12m") on each row. Built on `GroupedSurface`/`GroupedRow`.
|
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
|
### ⬜ M6 — Timers
|
||||||
Multiple concurrent timers, presets, labels, add/pause/reset/+1min. Foreground
|
Multiple concurrent timers, presets, labels, add/pause/reset/+1min. Foreground
|
||||||
service with notification controls, expiry ringing reusing M3's audio path.
|
service with notification controls, expiry ringing reusing M3's audio path.
|
||||||
|
|||||||
Reference in New Issue
Block a user