Repository navigation
fix: stop the desktop calling yesterday today - #552
Merged
Merged
Conversation
A window opened on the 13th still read `Today · November 13, 2026` at 08:29 on the 14th, in the accent colour, over the page the user was about to write into, and the sidebar calendar still ringed the 13th. Nothing was stale in the needs-a-refetch sense. The app was asserting a falsehood about the day, on the one surface where believing it means writing into the wrong journal. Two frozen copies of one fact caused it. The header resolved the day in a createResource keyed on the page slug, so it re-asked on navigation and never otherwise. The sidebar calendar called new Date() in a component body, read once at mount and on the browser clock rather than the configured [calendar] timezone, so that one could be wrong at any hour of any day. createDayClock owns it now, and the header, the calendar ring and the task list's journal headings all read it. The value is still the backend's today_slug. The browser clock only decides when to ask, capped at an hour, because a configured timezone puts midnight where the browser cannot predict it. Midnight relabels and does not navigate, since the user may be looking at the window. Returning to today happens on the way back in, under the shouldWakeToToday rule the phone already used, now shared rather than mobile-only. Signed-off-by: Avelino <31996+avelino@users.noreply.github.com>
Signed-off-by: Avelino <31996+avelino@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A desktop window left open overnight kept calling yesterday "Today". This gives the day a single owner that re-asks on its own, so the header, the sidebar calendar ring and the task list stop disagreeing with the clock.
Context
Reported from a real window: opened on the 13th, still reading
Today · November 13, 2026at 08:29 on the 14th, in the accent colour, directly over the page the user was about to type into. The calendar ring was still on the 13th.Nothing here was stale in the needs-a-refetch sense. The app was asserting a falsehood about the day, on the one surface where believing it means writing into the wrong journal.
Two frozen copies of one fact caused it:
PageTitle.tsxresolved the day in acreateResourcekeyed on the page slug, so it re-asked on navigation and never otherwise. No navigation, no new answer, forever.Sidebar.tsx's calendar callednew Date()in a component body. Read once at mount, and on the browser clock rather than the configured[calendar] timezone, so that one could be wrong at any hour of any day, not only after midnight.The TUI never had this (
view/sidebar.rsrecomputes per frame) and mobile already solved it inJournal.day-nav.ts. The desktop was the client left out.No issue number found on the branch or in the commits, so none is linked.
Changes
createDayClockin@outl/shared/journalis the one owner now.AppShellwires it intoappState.todaySlug, and every surface that names a day reads that field.Three decisions worth a reviewer's attention:
The day comes from the backend, the schedule comes from the browser.
today_slugresolves inoutl_actions::clock's timezone. The browser clock only decides when to ask, and because a configured timezone puts midnight where the browser cannot predict it, that delay is capped at an hour. Anew Date()used as the answer is the bug this replaces, not a shortcut.Midnight relabels, it does not navigate. The user may be looking at the window at 00:00. Returning to today happens on the way back in (
focus/visibilitychange), undershouldWakeToToday, which is promoted out ofoutl-mobile/src/lib/into the shared library rather than copied. Both clients now answer "does this count as opening the app" the same way: never mid-edit, never when today is already on screen.The clock is created in
AppShell's component body, not in itsasync onMount. It registers anonCleanup, and the owner is gone once that body awaits.On size: 659 lines, of which 251 are new tests, 35 are docs and roughly 70 are the new module's own doc comments. The remaining logic is small and does not split cleanly. The shared module without its consumers is dead code, and the consumers without it do not compile. The one separable piece is the
shouldWakeToTodaypromotion, which on its own is a move with no visible reason.Testing
@outl/shared: 685 tests, including 14 new inday-clock.test.ts(midnight tick under an untouched app, failed backend call, disposal, wake on return, never mid-edit, no navigation on the tick itself)outl-desktop: 280 tests, including the regression inPageTitle.test.tsx: the day rolls over with no navigation and the header has to stop claiming the page on screen is todayoutl-mobile: 364 tests, parity after theshouldWakeToTodaymovetsc --noEmiton all three packagescargo fmt --check, clippy onoutl-desktopandoutl-tauri-shared, and 320 Rust tests in the crates that read frontend files (wire_mirrors,outl-themetokens, shortcut parity)/ux-desktoplayout battery: 13 rows,PASS: pointing at a row moves nothing. Its captured frame also shows the real app booting with this change and renderingToday · November 14, 2026from the new store field, which is the wiring vitest cannot seeNot covered: the rollover itself with a window open. The lab uses a fixed fixture and a parked clock, so it never crosses midnight. The unit tests cover the logic. The lived scenario needs a build running overnight.
Screenshots
Touches the page header and the sidebar calendar. Attach a before/after if the label change is worth showing.
Verified
day-clock.test.ts,PageTitle.test.tsx) and an existing one updated (TasksPanel.test.tsx, which mocked the command this field replaces)CHANGELOG.md,outl-desktop/CLAUDE.md(new "Which day it is" section), theoutl-frontend-shared/CLAUDE.mdsurface table, and the mobile pointershouldWakeToTodaymoved between internal modules andAppStateShapegained a field, both repo-internalOpen in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is enabled.