/** * Familiar duration references for time-blindness aids. * * "About as long as a movie", "3 episodes of The Office". * Pure client-side TS — no backend dependency. */ import type { TimeRangeEntry, TimeReference } from './types.js'; const DEFAULT_DATABASE: TimeRangeEntry[] = [ { minHours: 0, maxHours: 0.25, references: [ { text: 'About as long as a coffee break', emoji: '☕', category: 'activity' }, { text: 'Like listening to a few songs', emoji: '🎵', category: 'media' }, ], }, { minHours: 0.25, maxHours: 0.5, references: [ { text: 'About as long as a TV episode', emoji: '📺', category: 'media' }, { text: 'Like a short walk around the block', emoji: '🚶', category: 'activity' }, ], }, { minHours: 0.5, maxHours: 1, references: [ { text: 'About as long as a yoga class', emoji: '🧘', category: 'activity' }, { text: 'Like watching 2 episodes of The Office', emoji: '📺', category: 'media' }, ], }, { minHours: 1, maxHours: 2, references: [ { text: 'About as long as a movie', emoji: '🎬', category: 'media' }, { text: 'Like a nice bike ride', emoji: '🚴', category: 'activity' }, ], }, { minHours: 2, maxHours: 4, references: [ { text: 'About as long as a road trip to the next city', emoji: '🚗', category: 'travel' }, { text: 'Like binge-watching a short series', emoji: '📺', category: 'media' }, ], }, { minHours: 4, maxHours: 8, references: [ { text: 'About as long as a work day', emoji: '💼', category: 'activity' }, { text: 'Like a full night of sleep', emoji: '😴', category: 'nature' }, ], }, { minHours: 8, maxHours: 12, references: [ { text: 'About as long as a cross-country flight', emoji: '✈️', category: 'travel' }, { text: 'Like sunrise to sunset in winter', emoji: '🌅', category: 'nature' }, ], }, { minHours: 12, maxHours: 16, references: [ { text: 'About as long as daylight hours in summer', emoji: '☀️', category: 'nature' }, { text: 'Like watching the entire Lord of the Rings trilogy (extended)', emoji: '🧙', category: 'media', }, ], }, { minHours: 16, maxHours: 24, references: [ { text: 'Almost a full day — impressive!', emoji: '🌍', category: 'nature' }, { text: 'Like a full day of hiking', emoji: '🥾', category: 'activity' }, ], }, { minHours: 24, maxHours: 48, references: [ { text: 'More than a full day!', emoji: '🏆', category: 'nature' }, { text: 'Like a weekend camping trip', emoji: '⛺', category: 'activity' }, ], }, { minHours: 48, maxHours: Infinity, references: [ { text: 'An extraordinary duration — you are incredible!', emoji: '🌟', category: 'nature' }, ], }, ]; const FALLBACK: TimeReference = { text: 'A meaningful amount of time', emoji: '⏳', category: 'nature', }; const customRegistry: TimeRangeEntry[] = []; function findReferences(hours: number, custom: TimeRangeEntry[]): TimeReference[] { for (const entry of custom) { if (hours >= entry.minHours && hours < entry.maxHours) { return entry.references; } } for (const entry of DEFAULT_DATABASE) { if (hours >= entry.minHours && hours < entry.maxHours) { return entry.references; } } return [FALLBACK]; } export function getTimeReference(elapsedHours: number): TimeReference { const refs = findReferences(Math.max(0, elapsedHours), customRegistry); const index = Math.floor(Math.random() * refs.length); return refs[index]; } export function getEpisodeComparison( elapsedHours: number, showName = 'The Office', episodeMins = 22 ): string { const totalMins = elapsedHours * 60; const episodes = Math.round(totalMins / episodeMins); if (episodes <= 0) return `Less than one episode of ${showName}`; if (episodes === 1) return `About 1 episode of ${showName}`; return `About ${episodes} episodes of ${showName}`; } export function getEncouragingMessage(elapsedHours: number): string { if (elapsedHours < 1) return 'Every minute counts — great start!'; if (elapsedHours < 4) return 'You are building momentum — keep going!'; if (elapsedHours < 8) return 'Impressive dedication — halfway through the day!'; if (elapsedHours < 16) return 'Amazing endurance — you are a champion!'; if (elapsedHours < 24) return 'Nearly a full day — extraordinary commitment!'; return 'Beyond a full day — you are truly remarkable!'; } export function registerReferences(entries: TimeRangeEntry[]): void { customRegistry.push(...entries); } export function clearCustomReferences(): void { customRegistry.length = 0; }