feat(world-clock): an optional compact home clock

A "Compact home clock" switch under Settings > Clock swaps the World clock
tab's analog face for a row: a home glyph, the city, "Home · <zone name>"
and the time, in the seconds-aware style the city rows use and spoken to
the minute like them. It is drawn the way the automatic local clock's row
is, through one shared pinned-row composable, and the local row still sits
directly under home. Off by default.

Like show-seconds it is display-only, so it is its own preference and flow
(world_clock_compact_home) rather than a clock default, and it is applied
outside the tick so flipping it does not restart the ticker. Backups carry
it; older files restore it as off.

Closes #29.
This commit is contained in:
makiolaj committed 2026-11-02 19:29:16 +01:00
1 parent 005df7db19
commit 7d65b2b206
22 files changed
+212 -26

No files matched your search

+1 -1
View File
@@ -618,7 +618,7 @@ Six slices:
|---|---|---|
| Appearance (M1) | `theme_mode`, `dynamic_color` | `AppearancePrefs` in `core-prefs`, the family's shared key names |
| Clock defaults (M2) | `default_snooze_minutes`, `default_snooze_limit`, `default_vibrate`, `default_volume_ramp_seconds`, `default_alarm_ringtone_uri`, `default_timer_ringtone_uri`, `default_timer_vibrate`, `default_timer_volume_ramp_seconds` (#22), `default_dismiss_challenge`, `home_zone_id`, `volume_buttons_while_ringing` (#18; app-wide, no per-alarm override), `automatic_local_clock` (#24) | `ClockPrefs`, surfaced as `SettingsPrefs.defaults: Flow<ClockDefaults>` |
| World clock display (#23) | `world_clock_show_seconds` | `ClockPrefs`, surfaced as its own `SettingsPrefs.worldClockSeconds`, not a clock default, so flipping it re-emits nothing alarms and timers watch |
| World clock display (#23, #29) | `world_clock_show_seconds`, `world_clock_compact_home` | `ClockPrefs`, surfaced as their own `SettingsPrefs.worldClockSeconds` and `SettingsPrefs.compactHomeClock`, not clock defaults, so flipping them re-emits nothing alarms and timers watch |
| Stopwatch run record (M2) | `stopwatch_state`, `stopwatch_started_elapsed_millis`, `stopwatch_accumulated_millis`, `stopwatch_last_lap_cumulative_millis` (M7 is the first caller of the last, for the in-progress lap's split) | `StopwatchPrefs`, behind `StopwatchStateStore` |
| System facts (M3) | `last_boot_id` | `SystemPrefs`, behind `BootStateStore`, the persisted half of the reboot gate |
| Timers (M6) | `timer_presets`, `timer_ring_sounding_since_millis` | `TimerPrefs`: the presets surfaced as `SettingsPrefs.timerPresets`, the ring session's anchor behind `TimerRingStateStore` |
+3 -1
View File
@@ -164,6 +164,7 @@ device or after a reboot (`docs/PLAN.md` §5). Every imported timer lands
"default_timer_silence_after_minutes": 10,
"volume_buttons_while_ringing": "CONTROL_VOLUME",
"world_clock_show_seconds": false,
"world_clock_compact_home": false,
"automatic_local_clock": true,
"timer_presets": [60000, 120000, 180000, 300000, 600000, 900000, 1800000, 3600000],
"bedtime": {
@@ -213,7 +214,8 @@ rings for that long anyway); a negative one reads as the default, 10.
Files from before `world_clock_show_seconds` existed import with it off, its
default. It travels with the settings but is not a clock default: nothing an
alarm or timer inherits depends on it. A file without `automatic_local_clock`
alarm or timer inherits depends on it. The same goes for
`world_clock_compact_home` (#29), which a file without it restores as off. A file without `automatic_local_clock`
(one written before it existed) restores it as `true`, its default.
Every numeric/duration value is clamped on *apply* using the same ranges and encoding