fix: robust first-launch auto-preload (mobile bible/download)
- OfflineManager.preload accepts bibleTranslations: 'all' and resolves translation ids internally from versions.json (single source), removing the fragile settings-side fetch that could throw and abort the whole download on mobile first launch - Decouple trigger from '#settings/autopreload' route param via one-shot requestAutoPreload()/consumeAutoPreload() flag - Auto-expand + tick Bible variant checkboxes for UI consistency - Offer modal sets the flag and navigates to plain '#settings'
This commit is contained in:
1 parent
142b95d226
commit
623c56a96f
3 files changed
+41
-13
No files matched your search
@@ -20,7 +20,7 @@ import { diagLog } from './diag-log';
|
||||
export interface PreloadOptions {
|
||||
languages: string[];
|
||||
types: ('calendar' | 'bible')[];
|
||||
bibleTranslations?: string[];
|
||||
bibleTranslations?: string[] | 'all';
|
||||
}
|
||||
|
||||
export interface PreloadProgress {
|
||||
@@ -89,12 +89,36 @@ function getFallbackCalendarFiles(lang: string): string[] {
|
||||
|
||||
export class OfflineManager {
|
||||
private static _progress: PreloadProgress | null = null;
|
||||
private static _autoPreloadRequested = false;
|
||||
|
||||
/** Request an automatic "preload everything" once the Settings view opens. */
|
||||
static requestAutoPreload() {
|
||||
OfflineManager._autoPreloadRequested = true;
|
||||
}
|
||||
|
||||
/** Consume (one-shot) the automatic preload request. */
|
||||
static consumeAutoPreload(): boolean {
|
||||
const v = OfflineManager._autoPreloadRequested;
|
||||
OfflineManager._autoPreloadRequested = false;
|
||||
return v;
|
||||
}
|
||||
|
||||
/** Get size string for a Bible translation. */
|
||||
static getBibleSize(translationPath: string): string {
|
||||
return BIBLE_SIZES[translationPath] || '?';
|
||||
}
|
||||
|
||||
/** Resolve every Bible translation id from versions.json (single source). */
|
||||
static async getAllBibleTranslationIds(): Promise<string[]> {
|
||||
try {
|
||||
const resp = await fetch('/data/bible/versions.json');
|
||||
const versions = await resp.json() as any[];
|
||||
return versions.map((v: any) => v.id);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/** Discover all book files for a Bible translation from versions.json. */
|
||||
static async getBibleFiles(translationPath: string): Promise<string[]> {
|
||||
const files: string[] = [];
|
||||
@@ -140,7 +164,10 @@ export class OfflineManager {
|
||||
const uniqueFiles = [...new Set(filesToFetch)];
|
||||
|
||||
// Add Bible translation files
|
||||
for (const trans of options.bibleTranslations || []) {
|
||||
const bibleTranslations = options.bibleTranslations === 'all'
|
||||
? await OfflineManager.getAllBibleTranslationIds()
|
||||
: (options.bibleTranslations || []);
|
||||
for (const trans of bibleTranslations) {
|
||||
const bibleFiles = await OfflineManager.getBibleFiles(trans);
|
||||
for (const f of bibleFiles) {
|
||||
if (!uniqueFiles.includes(f)) uniqueFiles.push(f);
|
||||
@@ -162,7 +189,7 @@ export class OfflineManager {
|
||||
diagLog('preload-start', {
|
||||
langs: options.languages.join(','),
|
||||
types: options.types.join(','),
|
||||
bibles: (options.bibleTranslations || []).length,
|
||||
bibles: bibleTranslations.length,
|
||||
total: progress.total,
|
||||
manifest: m !== null,
|
||||
});
|
||||
|
||||
+3
-1
@@ -12,6 +12,7 @@ import { loadSettings, type Settings } from './settings-view';
|
||||
import { getTranslations, type LanguageCode } from '../core/i18n';
|
||||
import { DataCache } from '../core/data-cache';
|
||||
import { diagLog } from '../core/diag-log';
|
||||
import { OfflineManager } from '../core/offline-manager';
|
||||
import { markEverInstalled, hasEverInstalledMarker } from '../core/pwa-install';
|
||||
|
||||
type View = 'calendar' | 'bible' | 'prayer' | 'akathists' | 'parimii' | 'horologion' | 'sbornik' | 'paraclete' | 'irmologion' | 'menaion' | 'triodion' | 'lives' | 'settings';
|
||||
@@ -201,7 +202,8 @@ export class App {
|
||||
|
||||
document.getElementById('offline-offer-all')?.addEventListener('click', () => {
|
||||
overlay.remove();
|
||||
window.location.hash = '#settings/autopreload';
|
||||
OfflineManager.requestAutoPreload();
|
||||
window.location.hash = '#settings';
|
||||
});
|
||||
document.getElementById('offline-offer-choose')?.addEventListener('click', () => {
|
||||
overlay.remove();
|
||||
|
||||
@@ -672,7 +672,7 @@ export class SettingsView {
|
||||
}
|
||||
|
||||
// Auto-preload everything if triggered from first-launch offer
|
||||
if (this.action === 'autopreload') {
|
||||
if (OfflineManager.consumeAutoPreload() || this.action === 'autopreload') {
|
||||
document.querySelectorAll('.offline-lang').forEach(el => (el as HTMLInputElement).checked = true);
|
||||
document.querySelectorAll('.offline-type').forEach(el => (el as HTMLInputElement).checked = true);
|
||||
const progressDiv = document.getElementById('offline-progress');
|
||||
@@ -680,20 +680,19 @@ export class SettingsView {
|
||||
const progressText = document.getElementById('offline-progress-text');
|
||||
if (progressDiv) progressDiv.classList.remove('hidden');
|
||||
|
||||
// Reveal + select all Bible variants for UI consistency
|
||||
document.getElementById('bible-row')?.dispatchEvent(new Event('click'));
|
||||
setTimeout(() => {
|
||||
document.querySelectorAll('.bible-trans').forEach(el => (el as HTMLInputElement).checked = true);
|
||||
}, 300);
|
||||
|
||||
const selectedLangs = LANGUAGES.map(l => l.code);
|
||||
const selectedTypes: ('calendar' | 'bible')[] = ['calendar', 'bible'];
|
||||
|
||||
let bibleTrans: string[] = [];
|
||||
try {
|
||||
const resp = await fetch('/data/bible/versions.json');
|
||||
const versions = await resp.json();
|
||||
bibleTrans = versions.map((v: any) => v.id);
|
||||
} catch {}
|
||||
|
||||
OfflineManager.preload({
|
||||
languages: selectedLangs,
|
||||
types: selectedTypes,
|
||||
bibleTranslations: bibleTrans,
|
||||
bibleTranslations: 'all',
|
||||
}).then((prog) => {
|
||||
if (progressBar) progressBar.style.width = '100%';
|
||||
if (progressText) {
|
||||
|
||||
Reference in new issue
Block a user