Preferences in Settings and a home page the user chooses
Build and Push Docker Image / build-and-push (push) Failing after 20s

Settings gets a Preferences section: theme, default Bible, the Bible new reading
plans start in, verse layout, commentary, text size, reading width, audio
narrator (the last three stay per device; text size and narrator are now
remembered). A Home page setting (My Studies, Bible Reader or Reading Plans)
decides where the app opens and where every Home button goes; already being
there means My Studies. Back arrows are labelled Home. Tests cover every page
leading back.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-09-29 10:55:07 -04:00
1 parent 760c1e568b
commit 8c4f54e033
15 files changed
+401 -23

No files matched your search

+46 -1
View File
@@ -73,7 +73,46 @@ export function useBibleReader(currentPage, translationOverride = null) {
const [readerInterlinearLoading, setReaderInterlinearLoading] = useState(false);
const [readerSelectedVerse, setReaderSelectedVerse] = useState(null); // verse number with open interlinear panel
const _readerInterlinearCacheRef = useRef({});
const [readerFontSize, setReaderFontSize] = useState(1); // em multiplier: 0.875 | 1 | 1.125 | 1.25
// Text size and reading width are per-device (a phone and a tablet want different ones)
const [readerFontSize, setReaderFontSizeState] = useState(() => {
try {
const n = Number(localStorage.getItem('reader-font-size'));
return [0.875, 1, 1.125, 1.25, 1.5].includes(n) ? n : 1;
} catch { return 1; }
}); // em multiplier: 0.875 | 1 | 1.125 | 1.25 | 1.5
const setReaderFontSize = (n) => {
setReaderFontSizeState(n);
try { localStorage.setItem('reader-font-size', String(n)); } catch {}
};
const [readerWide, setReaderWideState] = useState(() => {
try { return localStorage.getItem('reader-wide') === '1'; } catch { return false; }
});
const setReaderWide = (on) => {
setReaderWideState(!!on);
try { localStorage.setItem('reader-wide', on ? '1' : '0'); } catch {}
};
// The page the app opens to, and where every Home button goes: 'studies' | 'reader' | 'plans'
const [startPagePref, setStartPagePrefState] = useState(() => {
try {
const saved = localStorage.getItem('start-page');
return ['studies', 'reader', 'plans'].includes(saved) ? saved : 'studies';
} catch { return 'studies'; }
});
const setStartPagePref = (id) => {
setStartPagePrefState(id);
try { localStorage.setItem('start-page', id); } catch {}
};
// Which Bible a newly started reading plan begins in: 'same' = whatever the default Bible is
const [planTranslationPref, setPlanTranslationPrefState] = useState(() => {
try {
const saved = localStorage.getItem('plan-translation');
return saved === 'same' || READER_TRANSLATIONS.some((t) => t.id === saved) ? saved : 'same';
} catch { return 'same'; }
});
const setPlanTranslationPref = (id) => {
setPlanTranslationPrefState(id);
try { localStorage.setItem('plan-translation', id); } catch {}
};
const [readerBookmarks, setReaderBookmarks] = useState(() => {
try { return JSON.parse(localStorage.getItem('reader-bookmarks') || '{}'); } catch { return {}; }
});
@@ -397,12 +436,15 @@ export function useBibleReader(currentPage, translationOverride = null) {
const prefsSync = usePrefsSync({
values: {
theme: readerTheme, translation: baseTranslation, layout: readerLayout, commentarySource: readerCommentary,
planTranslation: planTranslationPref, startPage: startPagePref,
position: { book: readerBookAbbrev, chapter: readerChapter },
},
apply: (key, v) => {
if (key === 'theme') { setReaderThemeState(v); try { localStorage.setItem('reader-theme', v); } catch {} }
else if (key === 'translation') { setReaderTranslationState(v); try { localStorage.setItem('reader-translation', v); } catch {} }
else if (key === 'layout') { setReaderLayoutState(v); try { localStorage.setItem('reader-layout', v); } catch {} }
else if (key === 'startPage') { setStartPagePrefState(v); try { localStorage.setItem('start-page', v); } catch {} }
else if (key === 'planTranslation') { setPlanTranslationPrefState(v); try { localStorage.setItem('plan-translation', v); } catch {} }
else if (key === 'commentarySource') { setReaderCommentaryState(v); try { localStorage.setItem('reader-commentary', v); } catch {} }
else if (key === 'position') { setReaderBookAbbrev(v.book); setReaderChapter(v.chapter); setReaderSelectedVerse(null); }
},
@@ -424,6 +466,9 @@ export function useBibleReader(currentPage, translationOverride = null) {
readerInterlinear,
readerSelectedVerse, setReaderSelectedVerse,
readerFontSize, setReaderFontSize,
readerWide, setReaderWide,
planTranslationPref, setPlanTranslationPref,
startPagePref, setStartPagePref,
readerBookmarks, setReaderBookmarks,
readerBookmarksPanelOpen, setReaderBookmarksPanelOpen,
readerCrossRefs, setReaderCrossRefs,