diff --git a/src/ui/app.ts b/src/ui/app.ts index 2b31d7b..2f2f3dc 100644 --- a/src/ui/app.ts +++ b/src/ui/app.ts @@ -10,6 +10,7 @@ import { SettingsView } from './settings-view'; import { JDate } from '../core/jdate'; import { loadSettings, type Settings } from './settings-view'; import { getTranslations, type LanguageCode } from '../core/i18n'; +import { DataCache } from '../core/data-cache'; type View = 'calendar' | 'bible' | 'prayer' | 'akathists' | 'parimii' | 'horologion' | 'sbornik' | 'paraclete' | 'irmologion' | 'menaion' | 'triodion' | 'settings'; @@ -49,6 +50,30 @@ export class App { e.preventDefault(); (window as any).__deferredPrompt = e; }); + + // Auto-preload essential data for the current language + this.autoPreload(); + } + + private async autoPreload(): Promise { + try { + const key = 'ponomar-preloaded'; + if (localStorage.getItem(key)) return; + const lang = this.settings.language as LanguageCode; + const languages = lang === 'ru' ? ['ru', 'cu'] : [lang]; + for (const l of languages) { + // Preload menaion bundle + await DataCache.fetch(`/data/${l}/menaion-bundle.json`).catch(() => {}); + // Preload current month lives + const mm = String(JDate.today().getMonth()).padStart(2, '0'); + await DataCache.fetch(`/data/${l}/lives/${mm}.json`).catch(() => {}); + } + // Preload calendar data + await DataCache.fetch('/data/shared/fasting.json').catch(() => {}); + localStorage.setItem(key, '1'); + } catch { + // Silently fail — user can manually preload via settings + } } private handleRoute() { diff --git a/src/ui/calendar-view.ts b/src/ui/calendar-view.ts index 5e21e81..93eeebe 100644 --- a/src/ui/calendar-view.ts +++ b/src/ui/calendar-view.ts @@ -411,7 +411,6 @@ export class CalendarView { if (stored) { const settings = JSON.parse(stored); let cuFont = settings.cuFont || ''; - // Migrate old usePonomarFont if (settings.usePonomarFont !== undefined) { cuFont = settings.usePonomarFont ? 'Ponomar' : ''; } @@ -422,6 +421,14 @@ export class CalendarView { return this.language === 'cu' ? 'font-ponomar' : ''; } + /** Prefetch lives data for a given month to warm the cache. */ + private prefetchMonth(month: number): void { + const mm = String(month).padStart(2, '0'); + const lang = this.language; + const url = `/data/${lang}/lives/${mm}.json`; + DataCache.fetch(url).catch(() => {}); + } + /** Lightweight dRank computation for calendar grid highlighting */ private getDayRank(date: JDate, julianYear: number): number { const month = date.getMonth(); @@ -932,5 +939,13 @@ export class CalendarView { svcPanel.innerHTML = `

${this.t.loading}

`; } } + + // Prefetch current and adjacent month's lives data for faster navigation + const currentMonth = this.currentDate.getMonth(); + const prevMonth = currentMonth <= 1 ? 12 : currentMonth - 1; + const nextMonth = currentMonth >= 12 ? 1 : currentMonth + 1; + this.prefetchMonth(currentMonth); + this.prefetchMonth(prevMonth); + this.prefetchMonth(nextMonth); } } \ No newline at end of file