From b3c266fa66fecbd2f5a7d02ef234ec7df9b94f48 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 03:38:01 +0000 Subject: [PATCH] Add a read-only Bible reader page (BSB) Adds a "Read Bible" button on the home screen that opens a simple chapter browser using the existing helloao BSB API, with book/chapter pickers and prev/next navigation, separate from study projects. https://claude.ai/code/session_013GXQxSaTF6zeBsSYTeF3fN --- src/App.jsx | 166 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 159 insertions(+), 7 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index cda8fa9..3c2c6fe 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -892,6 +892,12 @@ const App = () => { const [homeTagFilter, setHomeTagFilter] = useState(''); const [renamingId, setRenamingId] = useState(null); const [renameValue, setRenameValue] = useState(''); + const [readerBookAbbrev, setReaderBookAbbrev] = useState(bookOptions[0].abbrev); + const [readerChapter, setReaderChapter] = useState(1); + const [readerVerses, setReaderVerses] = useState([]); + const [readerTotalChapters, setReaderTotalChapters] = useState(1); + const [readerLoading, setReaderLoading] = useState(false); + const [readerError, setReaderError] = useState(''); const [audioBook, setAudioBook] = useState(bookOptions[0].abbrev); const [audioNarrator, setAudioNarrator] = useState('souer'); const [audioState, setAudioState] = useState({ status: 'idle', chapter: 0, total: 0 }); @@ -1008,6 +1014,53 @@ const App = () => { return data; }; + // --------------------------------------------------------------------------- + // Bible reader (read-only browsing, separate from study projects) + // --------------------------------------------------------------------------- + + const loadReaderChapter = async (bookAbbrev, chapterNumber) => { + setReaderLoading(true); + setReaderError(''); + try { + const res = await fetch(`https://bible.helloao.org/api/BSB/${bookAbbrev}/${chapterNumber}.json`); + if (!res.ok) throw new Error('Unable to load chapter.'); + const data = await res.json(); + const verses = parseBibleChapter(data); + if (!Array.isArray(verses) || verses.length === 0) { + throw new Error('Invalid Bible data returned.'); + } + setReaderVerses(verses); + setReaderTotalChapters(data.book?.numberOfChapters ?? chapterNumber); + } catch (err) { + setReaderError(err.message || 'Failed to load chapter.'); + setReaderVerses([]); + } finally { + setReaderLoading(false); + } + }; + + useEffect(() => { + if (currentPage !== 'reader') return; + loadReaderChapter(readerBookAbbrev, readerChapter); + }, [currentPage, readerBookAbbrev, readerChapter]); + + const openBibleReader = () => { + setCurrentPage('reader'); + }; + + const readerGoToPreviousChapter = () => { + if (readerChapter > 1) setReaderChapter((c) => c - 1); + }; + + const readerGoToNextChapter = () => { + if (readerChapter < readerTotalChapters) setReaderChapter((c) => c + 1); + }; + + const handleReaderBookChange = (abbrev) => { + setReaderBookAbbrev(abbrev); + setReaderChapter(1); + }; + // --------------------------------------------------------------------------- // Startup: migrate old keys and load index // --------------------------------------------------------------------------- @@ -2689,13 +2742,22 @@ const restoreRemoteProject = async (id) => {

Bible Study Project

My Studies

- +
+ + +
@@ -2966,6 +3028,96 @@ const restoreRemoteProject = async (id) => { ); } + // --------------------------------------------------------------------------- + // BIBLE READER PAGE (plain read-only browsing) + // --------------------------------------------------------------------------- + if (currentPage === 'reader') { + const readerBook = bookOptions.find((b) => b.abbrev === readerBookAbbrev); + return ( +
+
+
+
+

Bible Study Project

+

Read the Bible (BSB)

+
+ +
+
+
+
+ + +
+ + +
+
+ +
+

+ {readerBook?.name} {readerChapter} (BSB) +

+ {readerLoading &&

Loading…

} + {readerError &&

{readerError}

} + {!readerLoading && !readerError && ( +
+ {readerVerses.map((verse) => ( +

+ {verse.number} + {verse.text} +

+ ))} +
+ )} +
+
+
+ ); + } + // --------------------------------------------------------------------------- // SETUP PAGE (chunk builder) // ---------------------------------------------------------------------------