docs: bring home-screen widgets into M10, out of post-v1
Widgets share M10's machinery end to end: the next-alarm and timer state a widget mirrors is exactly what the settings/backup/self-check work already touches, and a widget tap is just another caller of the MainActivity door the AlarmClock contract already opens. Keeping them parked in post-v1 would mean building the same read paths twice. QS tile, screensaver and bedtime stay deferred — none of them shares M10's surface the way widgets do. Also tightens PLAN.md §4's DND wording (interruption-filter read, no ACCESS_NOTIFICATION_POLICY) and §7's backup semantics (whole-state replace, ring state excluded, Room column vocabulary) ahead of M10's implementation.
This commit is contained in:
+31
-8
@@ -54,7 +54,7 @@ Agendula swap its whole storage posture without touching the UI.
|
||||
| # | Decision | Why |
|
||||
|---|---|---|
|
||||
| 1 | **Four surfaces in v1**: alarms, timers, stopwatch, world clock. | The complete stock-clock feature set. Anything less reads as a toy next to the app it wants to replace. |
|
||||
| 2 | **No extras in v1.** No widget, no QS tile, no screensaver, no bedtime. | v1 is already large. All four land in the roadmap as post-v1 milestones. Better a tight, finished v1 than five half-surfaces. |
|
||||
| 2 | **Home-screen widgets (next alarm, running timer, clock) are in v1, in M10.** No QS tile, no screensaver, no bedtime. | Widgets are the cheapest way to make the live pill's promise ("a running timer is never invisible") reach past the app itself, and M10 already touches every piece of state a widget reads. The other three stay out: v1 is already large, and none of them shares M10's machinery the way widgets do. |
|
||||
| 3 | **Full `AlarmClock` intent contract** + next-alarm publishing via `setAlarmClock`. | §6. This is the thesis. |
|
||||
| 4 | **Room + DataStore + JSON export.** | Repeat rules, per-alarm overrides and lap history want a real schema. Prefs stay DataStore. Backup is an open documented format. |
|
||||
| 5 | **Maximum alarm reliability**, including a self-check diagnostics screen. | §4. An alarm that doesn't ring is a dead app. This is the whole value proposition, not a nice-to-have. |
|
||||
@@ -161,10 +161,13 @@ notification whose content intent is the ring activity.
|
||||
|
||||
A "**Why might my alarm not ring?**" screen that reports actual device state, not
|
||||
generic advice: exact-alarm permission, notification permission, full-screen-intent
|
||||
permission, battery-optimisation exemption, DND policy access, whether the OEM has
|
||||
Clockula under an aggressive app-killer, and the next scheduled fire time as the
|
||||
system sees it (`getNextAlarmClock()`). Where possible each row deep-links to the
|
||||
exact settings page. This screen is a v1 feature, not a support afterthought.
|
||||
permission, battery-optimisation exemption, **whether DND currently blocks alarms**
|
||||
(read via `NotificationManager.getCurrentInterruptionFilter()` — Clockula never
|
||||
requests `ACCESS_NOTIFICATION_POLICY` or changes DND itself, it only reports what the
|
||||
user already has), whether the OEM has Clockula under an aggressive app-killer, and
|
||||
the next scheduled fire time as the system sees it (`getNextAlarmClock()`), compared
|
||||
against the next fire Clockula itself computed. Where possible each row deep-links to
|
||||
the exact settings page. This screen is a v1 feature, not a support afterthought.
|
||||
|
||||
---
|
||||
|
||||
@@ -221,9 +224,18 @@ than writing anything. `SKIP_UI` never means "skip validation".
|
||||
(`DocumentFile`), mirroring Agendula's export module shape. Top-level
|
||||
`{ "format": "clockula-backup", "version": 1, "exportedAt": …, "alarms": […],
|
||||
"timers": […], "worldClocks": […], "settings": {…} }`. The schema is **documented
|
||||
in the repo**, versioned, and import is tolerant of unknown fields and strict
|
||||
about known ones. Ringtone URIs are exported as-is with a documented fallback
|
||||
when the target device can't resolve them.
|
||||
in the repo** (`docs/BACKUP.md`), versioned, and import is tolerant of unknown
|
||||
fields (ignored, at any level) and strict about known ones (a malformed known
|
||||
field rejects the whole file — nothing is imported half-way). Ringtone URIs are
|
||||
exported as-is with a documented fallback when the target device can't resolve
|
||||
them.
|
||||
|
||||
Import is **whole-state replacement**, not a merge: the user is shown exactly
|
||||
that before confirming. Alarm and timer records carry only configuration — ring
|
||||
state (`alarm_states`, a timer's running anchors) is never exported and never
|
||||
touched by an import; an imported timer always lands `IDLE`. Record field names
|
||||
mirror the Room column vocabulary (§5), so the schema, the exported Room schema
|
||||
and the backup all read the same words.
|
||||
|
||||
---
|
||||
|
||||
@@ -265,6 +277,17 @@ standing on its tab. The pill is not decoration; it is the fix.
|
||||
|
||||
Adaptive: navigation rail on wide layouts, per M3 adaptive guidance.
|
||||
|
||||
### Home-screen widgets (M10)
|
||||
|
||||
Three Jetpack Glance app widgets, each a read-only mirror of state that already
|
||||
exists — no widget owns data: **next alarm** (day, time, label), **timer**
|
||||
(the live pill's subject timer, same selection logic, with pause/resume/reset),
|
||||
and **clock** (local time, growing to world clocks at larger sizes). Tapping a
|
||||
widget opens the matching tab through the same `MainActivity` intents the
|
||||
`AlarmClock` contract (§6) already uses — a widget is just another caller of
|
||||
that door, not a second entry point. Refresh is event-driven (`updatePeriodMillis
|
||||
= 0`): widgets update when the state they mirror changes, not on a timer.
|
||||
|
||||
---
|
||||
|
||||
## 10. Repository & pipeline
|
||||
|
||||
+6
-4
@@ -586,13 +586,16 @@ next-alarm publishing. Hostile-input validation at the intent boundary.
|
||||
hardware**, as no device was attached — the same caveat M5's seven, M6's four,
|
||||
M7's four and M8's four carry.
|
||||
|
||||
### ⬜ M10 — Settings, backup, and the self-check
|
||||
### ⬜ M10 — Settings, backup, the self-check, and widgets
|
||||
- Settings composed from kit components: theme, dynamic colour, language,
|
||||
alarm/timer/clock defaults, about + crash reporting.
|
||||
- JSON backup export/import via SAF (`PLAN.md` §7), schema documented in the repo.
|
||||
- JSON backup export/import via SAF (`PLAN.md` §7), schema documented in
|
||||
`docs/BACKUP.md`.
|
||||
- The **"why might my alarm not ring?"** self-check screen (`PLAN.md` §4) —
|
||||
real device state, deep links to the exact settings pages.
|
||||
- **Tests:** backup round-trip and unknown-field tolerance.
|
||||
- Three Glance home-screen widgets — next alarm, timer, clock (`PLAN.md` §9).
|
||||
- **Tests:** backup round-trip and unknown-field tolerance; self-check rule
|
||||
logic per permission/state combination; widget model selection/formatting.
|
||||
|
||||
### ⬜ M11 — Release readiness
|
||||
Translations wired to Weblate, fastlane metadata and screenshots, F-Droid
|
||||
@@ -608,7 +611,6 @@ Deferred deliberately, in rough priority order:
|
||||
|
||||
- **Dock / screensaver mode** — a `DreamService` full-screen clock. Cheapest big
|
||||
win, and the surface people look at most.
|
||||
- **Glance home-screen widget** — next alarm and running timer.
|
||||
- **Quick Settings tile** — timer control and next alarm from the shade.
|
||||
- **Bedtime / sleep schedule** — wind-down and wake, with DND handoff. A feature
|
||||
in its own right, realistically v2.
|
||||
|
||||
Reference in New Issue
Block a user