Reader: whole-Bible search in every translation
Build and Push Docker Image / build-and-push (push) Failing after 20s
Build and Push Docker Image / build-and-push (push) Failing after 20s
BSB and NET are indexed in the browser; ESV, NLT, CSB and NASB are searched through a server proxy (keys stay server-side). Results page in 25 at a time and jump to the verse. Also fixes a stray trailing comma in CSB chapter text. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3279dddae5
commit
c11b6a60bf
8 files changed
+262
-55
No files matched your search
@@ -6,6 +6,7 @@ import { bookOptions } from '../utils/bibleUtils.jsx';
|
||||
import { getPlan, getPlanSchedule, findDayIndexForRef, formatDayReadings } from '../utils/readingPlans.js';
|
||||
import DrawCanvas from './DrawCanvas.jsx';
|
||||
import { READER_TRANSLATIONS } from '../hooks/useBibleReader.js';
|
||||
import { useBibleSearch } from '../hooks/useBibleSearch.js';
|
||||
import { themeVars } from '../components/reader/readerThemes.js';
|
||||
import { TopBar, BottomBar } from '../components/reader/ReaderBars.jsx';
|
||||
import ReaderText from '../components/reader/ReaderText.jsx';
|
||||
@@ -45,7 +46,7 @@ export default function ReaderPage() {
|
||||
readerSearchScope, setReaderSearchScope,
|
||||
readerAudioState,
|
||||
audioProgress,
|
||||
bibleIndexStatus,
|
||||
bibleIndexStatusFor,
|
||||
audioNarrator, setAudioNarrator,
|
||||
_bibleIndexCacheRef,
|
||||
readerGoToPreviousChapter,
|
||||
@@ -142,11 +143,15 @@ export default function ReaderPage() {
|
||||
return m.done ? null : { label: 'Finish plan', done: false, onClick: markDone };
|
||||
}, [planMatches]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Whole-Bible search: lowercase the ~31k-verse index once (not per keystroke),
|
||||
// and let typing stay responsive while results catch up via useDeferredValue.
|
||||
const bibleIndex = bibleIndexStatus === 'ready' ? (_bibleIndexCacheRef.current.BSB ?? null) : null;
|
||||
// Whole-Bible search. BSB and NET are indexed in the browser (lowercased once, not per
|
||||
// keystroke, with typing kept responsive via useDeferredValue); ESV, NLT, CSB and NASB
|
||||
// go through the server's search proxy.
|
||||
const localSearch = READER_TRANSLATIONS.find((t) => t.id === readerTranslation)?.licensed !== true;
|
||||
const indexStatus = bibleIndexStatusFor(readerTranslation);
|
||||
const bibleIndex = localSearch && indexStatus === 'ready' ? (_bibleIndexCacheRef.current[readerTranslation] ?? null) : null;
|
||||
const bibleIndexLower = useMemo(() => (bibleIndex ? bibleIndex.map((v) => v.text.toLowerCase()) : null), [bibleIndex]);
|
||||
const deferredBibleQuery = useDeferredValue(sheet === 'search' && readerSearchScope === 'bible' ? readerSearch.trim().toLowerCase() : '');
|
||||
const wholeBibleSearching = sheet === 'search' && readerSearchScope === 'bible';
|
||||
const deferredBibleQuery = useDeferredValue(wholeBibleSearching && localSearch ? readerSearch.trim().toLowerCase() : '');
|
||||
const bibleMatches = useMemo(() => {
|
||||
if (!bibleIndex || !deferredBibleQuery) return [];
|
||||
const out = [];
|
||||
@@ -155,6 +160,7 @@ export default function ReaderPage() {
|
||||
}
|
||||
return out;
|
||||
}, [bibleIndex, bibleIndexLower, deferredBibleQuery]);
|
||||
const remoteSearch = useBibleSearch(readerTranslation, readerSearch, wholeBibleSearching && !localSearch);
|
||||
|
||||
const openSheet = (name) => {
|
||||
setSheet(name);
|
||||
@@ -407,8 +413,9 @@ export default function ReaderPage() {
|
||||
query={readerSearch} onQuery={setReaderSearch}
|
||||
scope={readerSearchScope} onScope={setReaderSearchScope}
|
||||
verses={readerVerses} bookName={readerBook?.name} chapter={readerChapter} currentBook={readerBookAbbrev}
|
||||
indexStatus={bibleIndexStatus} onLoadIndex={loadBibleIndex}
|
||||
bibleMatches={bibleMatches} deferredBibleQuery={deferredBibleQuery}
|
||||
translation={readerTranslation} isLocal={localSearch}
|
||||
indexStatus={indexStatus} onLoadIndex={() => loadBibleIndex(readerTranslation)}
|
||||
bibleMatches={bibleMatches} deferredBibleQuery={deferredBibleQuery} remote={remoteSearch}
|
||||
onJump={jump}
|
||||
/>
|
||||
<BookmarksSheet
|
||||
|
||||
@@ -18,7 +18,7 @@ const ctx = {
|
||||
readerSearch: '', setReaderSearch: noop, setReaderSearchActive: noop,
|
||||
readerSearchScope: 'chapter', setReaderSearchScope: noop,
|
||||
readerAudioState: { status: 'idle' }, audioProgress: { currentTime: 0, duration: 0 },
|
||||
bibleIndexStatus: 'idle', audioNarrator: 'david', setAudioNarrator: noop,
|
||||
bibleIndexStatusFor: () => 'idle', audioNarrator: 'david', setAudioNarrator: noop,
|
||||
_bibleIndexCacheRef: { current: {} },
|
||||
readerGoToPreviousChapter: noop, readerGoToNextChapter: noop, jumpToReaderVerse: noop,
|
||||
toggleReaderBookmark: noop, cycleBookmarkColor: noop, loadReaderCrossRefs: noop, loadBibleIndex: noop,
|
||||
|
||||
Reference in new issue
Block a user