From 5080397999f1fecc9e8ef39238c79cb2107c336f Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Fri, 16 Oct 2026 05:46:50 +0200 Subject: [PATCH] fix(dailies): a built-in on another server's clock leaves the header countdown alone Beyond the Rails rolls on Asia's reset, and the header took the soonest reset of every chip, so a Europe NTE reader read "next reset in 1h" at 20:00 UTC when their day rolls in seven. The countdown now counts the reader's own clocks. Found in the whole-branch review. Co-Authored-By: Claude Opus 5.5 --- src/client/components/Dailies.tsx | 8 ++++++-- test/views.test.tsx | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/client/components/Dailies.tsx b/src/client/components/Dailies.tsx index bd7d10a..8f984f0 100644 --- a/src/client/components/Dailies.tsx +++ b/src/client/components/Dailies.tsx @@ -502,8 +502,12 @@ export function Dailies({ // With mixed reset clocks there is no single "resets in", so the header // reports the next one to land and says that it is the next one. - const soonest = Math.min(...items.map((i) => i.resetsIn)); - const mixed = new Set(items.map((i) => i.resetsIn)).size > 1; + // A built-in on another server's clock (`clock`) rolls a cycle, not the + // reader's day: counting it would announce a reset nothing daily follows. + const own = items.filter((i) => i.clock === undefined); + const clocks = own.length > 0 ? own : items; + const soonest = Math.min(...clocks.map((i) => i.resetsIn)); + const mixed = new Set(clocks.map((i) => i.resetsIn)).size > 1; const open = items.find((i) => i.key === editing && i.goal?.measure === "amount"); const { today, longer } = splitByCadence(items); diff --git a/test/views.test.tsx b/test/views.test.tsx index 44955ee..4a2a3fd 100644 --- a/test/views.test.tsx +++ b/test/views.test.tsx @@ -1471,6 +1471,22 @@ describe("weekly and monthly tasks in the dailies strip", () => { expect(item!.resetsIn).toBeGreaterThan(chore!.resetsIn); }); + test("a clocked built-in does not move the header's reset countdown", () => { + const rails = { + id: "routine:nte:test-rails", game: "nte", title: "Beyond the Rails", + period: { unit: "cycle" as const, days: 14, from: "2026-10-22" }, + measure: { kind: "days" as const, required: 1 }, clock: "asia" as const, + }; + // 20:00 UTC: Europe's NTE day rolls at 03:00 UTC, seven hours off; Asia's in one. + const html = render( + []} onToggleDay={() => {}} tasks={[rails]} + taskStatusFor={() => undefined} />, + ); + expect(html).not.toContain("next reset in"); + expect(html).toMatch(/resets in ()?7h/); + }); + test("a cycle chip shows its days left, under a heading that names it", () => { const html = render(