Compare commits

..

2 Commits

Author SHA1 Message Date
will 945c5ef109 Default the initial hour to local time of day instead of always Prime
Deploy / deploy (push) Successful in 1m18s
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 06:50:42 -04:00
will 9e6b36bed9 Lower St. Jane Frances de Chantal to semiduplex
Deviates from the reference engine's plain Duplex per the user's own
calendar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 06:50:36 -04:00
3 changed files with 56 additions and 2 deletions
+14 -1
View File
@@ -16,9 +16,22 @@ export function todayIso(): string {
return `${yyyy}-${mm}-${dd}`; 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 = { const state: AppState = {
date: todayIso(), date: todayIso(),
selectedHour: 'prime', selectedHour: defaultHourForTime(new Date()),
languages: ['en'], languages: ['en'],
}; };
@@ -7,9 +7,11 @@
# portugal.yml (no benedictus-antiphon-common-of-a-widow.yml exists). # portugal.yml (no benedictus-antiphon-common-of-a-widow.yml exists).
# No Lectio7-9 in her own file -- defers to the Common's own Nocturn 3, # No Lectio7-9 in her own file -- defers to the Common's own Nocturn 3,
# not transcribed here. # not transcribed here.
# Rank manually lowered from the reference engine's Duplex to semiduplex
# per the user's own calendar (see "Not a reconstruction" in CLAUDE.md).
id: st-jane-frances-de-chantal id: st-jane-frances-de-chantal
name: "St. Jane Frances de Chantal, Widow" name: "St. Jane Frances de Chantal, Widow"
rank: duplex rank: semiduplex
common: common-of-a-widow common: common-of-a-widow
propers: "st-jane-frances-de-chantal" propers: "st-jane-frances-de-chantal"
benedictusCommon: common-of-a-virgin benedictusCommon: common-of-a-virgin
+39
View File
@@ -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);
});
});