Skip to content

v1.30.0

Choose a tag to compare

@Purgator Purgator released this 22 Oct 18:12
· 25 commits to main since this release

Maintenance release implementing the "Suggestions — rest of the app" section of docs/REVIEW-2026-09-30.md. Nothing changes in how the app behaves day to day; a few small things got better on the side.

Refactor (no behaviour change)

  • ui.js split by job (1 255 lines → 6 modules): dom.js ($, $$, esc, shake, pctText, signed), toast.js (toasts, sparkles, celebrate), sheet.js (the bottom sheet, its back-button history handling, and the new confirmDialog), widgets.js (row builders shared by renderers and sheets), sheets.js (the twelve non-quest sheets), ui.js (the renderers, tabbar, diffHtml). ui.js re-exports the rest, so import * as U from './ui.js' is still the one door for app.js.
  • app.js tap handling: the 55-case switch is now six per-area maps (SHELL, LIVE, QUEST, MOMENT, SETUP, OB actions) merged into ACTIONS; each handler gets (btn, now) and returns early.
  • Deduplicated: shake (×5 → dom.js), pctText (×2), fmtDate(new Date(day + 'T12:00')) (×3 → time.fmtDay(key)), new Date(day + 'T12:00').getDay() (×2 → time.weekday(key)).
  • Dead parameters and keys: fmtClock(ts, lang) and fmtDuration(ms, lang) never read lang — gone at the 19 call sites; update.js announce(worker) likewise; 23 unused i18n keys (appName, tagline, obQ_*, obPick*, toastMissed, minutesShort…) and the duplicated now removed from both languages.
  • Rough-patch detection (three misses in a row) moved from app.js into engine.missRun(now), so it is unit-tested.

Changed

  • Confirmations — deleting a moment, a premade or a quest, giving a quest up, replacing a premade of the same name — use the app's own dialog (confirmDialog, promise-based, floats above the open sheet) instead of the browser's confirm() pop-up. Cancel keeps you where you were.
  • Accessibility: every switch and select in Setup is named after its row (aria-label injected by toggleRow); rows and cards that react to a tap are focusable (tabindex=0 role=button) and Enter / Space activates them; the active tab carries aria-current="page"; the importance dot on a moment has a name, not just a colour.
  • Layout guards: tab labels ellipsise instead of pushing the bar around at large font scales; the clock and the four pills fit one row at 375 px in French.
  • Midnight: whichever tab is open re-renders when the day changes (previously only Now and Quests).

Fixed

  • A moment set inside the hour the clocks skip in spring (e.g. 02:30–03:30 on the switch day) collapsed to a zero-length window and was missed instantly. It now keeps its nominal length. Found by the new DST test.

Tests

41 unit + 4 relay. New: a DST switch day (both directions), settlePastDays after a 46-day gap (catches up on the 45-day window only, old records untouched), mergeWithDefaults on a v1 save (migrations, back-filled day start, every field defaulted), engine.missRun. Not added: the relay double-fire test — the double-fire itself is still an open decision in the review.