From 945c5ef1099eda150ce9c60643cd6454bf8b0599 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Fri, 21 Aug 2026 06:50:42 -0400 Subject: [PATCH] Default the initial hour to local time of day instead of always Prime Visiting the app with no hour in the URL previously always showed Prime for today, since selectedHour was hardcoded in AppState. Now it picks the hour whose band contains the visitor's local clock time. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD --- src/app-state.ts | 15 ++++++++++++++- tests/app-state.test.ts | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/app-state.test.ts diff --git a/src/app-state.ts b/src/app-state.ts index fe09c36..8b0beb3 100644 --- a/src/app-state.ts +++ b/src/app-state.ts @@ -16,9 +16,22 @@ export function todayIso(): string { return `${yyyy}-${mm}-${dd}`; } +/** Which hour to default to when the URL doesn't specify one, based on local wall-clock time. */ +export function defaultHourForTime(date: Date): HourId { + const h = date.getHours(); + if (h < 6) return 'matins'; + if (h < 8) return 'lauds'; + if (h < 9) return 'prime'; + if (h < 12) return 'terce'; + if (h < 15) return 'sext'; + if (h < 17) return 'none'; + if (h < 21) return 'vespers'; + return 'compline'; +} + const state: AppState = { date: todayIso(), - selectedHour: 'prime', + selectedHour: defaultHourForTime(new Date()), languages: ['en'], }; diff --git a/tests/app-state.test.ts b/tests/app-state.test.ts new file mode 100644 index 0000000..ab39cd7 --- /dev/null +++ b/tests/app-state.test.ts @@ -0,0 +1,39 @@ +import { describe, it, expect } from 'vitest'; +import { defaultHourForTime } from '../src/app-state'; + +function at(hour: number, minute = 0): Date { + const d = new Date(); + d.setHours(hour, minute, 0, 0); + return d; +} + +describe('defaultHourForTime', () => { + it.each([ + [0, 30, 'matins'], + [3, 0, 'matins'], + [5, 59, 'matins'], + [6, 0, 'lauds'], + [6, 30, 'lauds'], + [7, 59, 'lauds'], + [8, 0, 'prime'], + [8, 30, 'prime'], + [8, 59, 'prime'], + [9, 0, 'terce'], + [10, 0, 'terce'], + [11, 59, 'terce'], + [12, 0, 'sext'], + [13, 0, 'sext'], + [14, 59, 'sext'], + [15, 0, 'none'], + [16, 0, 'none'], + [16, 59, 'none'], + [17, 0, 'vespers'], + [18, 0, 'vespers'], + [20, 59, 'vespers'], + [21, 0, 'compline'], + [22, 0, 'compline'], + [23, 59, 'compline'], + ] as const)('%i:%i -> %s', (hour, minute, expected) => { + expect(defaultHourForTime(at(hour, minute))).toBe(expected); + }); +});