diff --git a/src/client/App.tsx b/src/client/App.tsx index b569773..8b5d1e2 100644 --- a/src/client/App.tsx +++ b/src/client/App.tsx @@ -24,7 +24,6 @@ import { compareRows, SORT_MODES, type Activity, type SortMode } from "./state/s import { advanceFocus, countByGame, - followingDeadlineMs, nextToExpire, outstanding, resolveFocus, @@ -301,15 +300,6 @@ export function App() { const live = visible.filter((r) => r.clock.live); const upcoming = visible.filter((r) => r.clock.upcoming); - /** - * What falls due after the row at the top of "Running now". - * - * Read off the deadlines rather than off the list, because the list is in - * whichever order the reader chose — see `followingDeadlineMs`. Null when - * there is no second dated end, and the header then says nothing rather than - * counting down to a placeholder. - */ - const following = followingDeadlineMs(live); /** * The unstarted events the checklist actually lists. * @@ -522,11 +512,6 @@ export function App() {
1 ? (

{title}

- {action ?? (hint !== undefined &&

{hint}

)} + {action}
{legend === true && } {children} diff --git a/src/client/state/lens.ts b/src/client/state/lens.ts index 3676df6..50879ef 100644 --- a/src/client/state/lens.ts +++ b/src/client/state/lens.ts @@ -71,31 +71,6 @@ export function firstToExpire(rows: readonly T[]): T | null { return nextToExpire(rows, 1)[0] ?? null; } -/** - * How long the deadline *behind* the closest one has left, or null when there - * is not a second dated deadline to report. - * - * The "Running now" header uses this to say what falls due after the row at the - * top. It asked the list for `rows[1]` before, which was wrong twice over and - * in the two ways this module exists to prevent. - * - * The list arrives sorted by whatever mode the reader chose, so under "doing - * first" `rows[1]` is the second thing they are partway through — the same - * mistake `firstToExpire` was written to stop the headline making, one row - * further down. And an unannounced end has no time remaining at all, so the - * old `?? 0` handed `formatRemaining` a zero and the header read "next after - * this ends in ended": the `endsAt: null` rule turned into a claim that - * something expired, which is exactly backwards. - * - * So it reads the second *dated* deadline and returns null rather than a - * stand-in, and the caller omits the line when there is nothing to say. - */ -export function followingDeadlineMs( - rows: readonly T[], -): number | null { - return nextToExpire(rows, 2)[1]?.clock.msRemaining ?? null; -} - /** * The focused game, if it is still a game the reader can see. * diff --git a/test/lens.test.ts b/test/lens.test.ts index 071284f..5bea56f 100644 --- a/test/lens.test.ts +++ b/test/lens.test.ts @@ -3,7 +3,6 @@ import { advanceFocus, countByGame, firstToExpire, - followingDeadlineMs, nextToExpire, outstanding, resolveFocus, @@ -47,40 +46,6 @@ describe("outstanding", () => { }); }); -describe("followingDeadlineMs", () => { - const HOUR = 3_600_000; - - test("reads the second deadline, not the second row", () => { - // The "Running now" header says what falls due after the top row. The list - // arrives in whichever order the reader chose, so under "doing first" its - // second row is the second thing they are partway through — the mistake - // `firstToExpire` prevents one row up. - const rows = [ - row("mid-run", "genshin", 9 * 24 * HOUR), - row("next-week", "hsr", 5 * 24 * HOUR), - row("tonight", "zzz", 3 * HOUR), - ]; - expect(followingDeadlineMs(rows)).toBe(5 * 24 * HOUR); - }); - - test("an unannounced end is not a deadline of zero", () => { - // The old code took `rows[1].msRemaining ?? 0`, and `formatRemaining(0)` is - // the string "ended" — so a second row with `endsAt: null` had the header - // reading "next after this ends in ended". Null means there is nothing to - // say, and the caller says nothing. - expect(followingDeadlineMs([row("tonight", "genshin", 3 * HOUR), row("undated", "hsr", null)])) - .toBeNull(); - }); - - test("one deadline has nothing behind it", () => { - expect(followingDeadlineMs([row("only", "genshin", 3 * HOUR)])).toBeNull(); - }); - - test("an empty list is null, not a zero", () => { - expect(followingDeadlineMs([])).toBeNull(); - }); -}); - describe("firstToExpire", () => { test("takes the soonest, not the first row", () => { // The list arrives sorted by whatever mode the reader chose. Under "doing