mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
The widget renders a pre-computed snapshot Angular pushes into `widget_data`; the blob carried no expiry, so a process that stayed dead across midnight kept rendering yesterday's tasks under a hardcoded "Today" header, indefinitely. Native cannot recompute the list. TODAY_TAG membership is virtual, today's repeat instances do not exist as entities until TaskDueEffects materializes them on a day change, and overdue carry-over runs there too — so there is no persisted field a native filter could read that would give the right answer even in principle. Only running the app can produce today's list. So make the widget honest instead of wrong: Angular stamps the snapshot with `validUntil`, the instant it stops being today (start-of-next-day offset included), and `dayStr` for the label. Native's whole verdict is `WidgetData.headerFor` → `now >= validUntil`; when stale it renders the snapshot's own date instead of "Today". The list stays visible and useful, it just stops claiming to be today's. A stale snapshot whose day cannot be read says "Outdated" rather than falling back to the very lie this fixes. Shipping the boundary rather than its inputs keeps the app's calendar rules in one language. The iOS port (#8950) can consume `validUntil` unchanged instead of mirroring getDbDateStr semantics into Swift, where a non-Gregorian default locale would silently misread the day. The verdict is a pure function so it is unit-testable: this project has no Robolectric, and a decision left inside the provider could ship inverted and green. Both refresh paths rebuild the header. A push can change the day the blob describes; a tap cannot, but it re-renders at a later `now` than the last verdict was computed at — and it is the one interaction that reaches our code while the app is dead, so a tap on a new day must not redraw rows under a "Today" header. Also fixed: onUpdate re-registered the adapter with an unchanged intent, which does not re-invoke the factory's onDataSetChanged(), so the periodic update rendered whatever rows the adapter last built. `v` stays 1: the fields are additive, and parse() returns empty for any other version, so a bump would blank the widget of every install until next opened. A pre-#9098 blob has no `validUntil` and is never reported stale — unknown must not read as expired. Known bounds, documented in the plan rather than papered over: the label flips only on a push, a tap, or the inexact Doze-deferred 30-min periodic update, and the launcher paints cached views on unlock — so the lie is bounded, not eliminated. Force-stop is not a gap: the system masks a stopped package's widget entirely, so the reported symptom can only occur in the Doze band. An exact alarm at `validUntil` would close the rest; deferred on cost/scope, not because it would not work. Verified: 25/25 Kotlin across 6 timezones incl. midnight-gap zones (Santiago, Apia); 203/203 Angular in both timezones CI runs. Boundary math asserted against the real getDbDateStr rollover. Sabotage-measured, not assumed: inverting the verdict fails 5 tests, >=→> fails 4, dropping the validUntil guard fails 3, Locale.US→getDefault fails 1, dropping the day round-trip fails 1. |
||
|---|---|---|
| .. | ||
| 2026-03-22-advanced-onboarding-design.md | ||
| 2026-05-21-clean-slate-data-loss-prevention.md | ||
| 2026-05-28-android-keyboard-resize-jank.md | ||
| 2026-06-05-project-completion.md | ||
| 2026-06-22-android-keyboard-and-systembars-handover.md | ||
| 2026-06-22-android-systembars-migration-corrected.md | ||
| 2026-06-30-plainspace-super-productivity-connect-flow.md | ||
| 2026-07-03-android-home-screen-widget.md | ||
| 2026-07-03-sync-engine-extraction-plan.md | ||
| 2026-07-07-complete-architecture-review.md | ||
| 2026-07-07-ios-home-screen-widget-port.md | ||
| 2026-07-09-todoist-import.md | ||
| 2026-07-13-sync-simplification-plan.md | ||
| 2026-07-14-ios-testflight-master-builds.md | ||
| 2026-07-14-microsoft-365-calendar-provider.md | ||
| 2026-07-16-conflict-review-cohort-audit.md | ||
| 2026-07-16-sync-simplification-audit.md | ||
| 2026-07-16-systematic-simplification-audit-results.md | ||