Commit Graph
35 Commits
Author SHA1 Message Date
nmemmertandClaude Sonnet 5.5 512c6b6889 Put every preference in Settings; same header on every page
Build and Push Docker Image / build-and-push (push) Successful in 5m7s
- Settings > Preferences: typeface, line spacing, verse numbers, highlight colour names,
  My Studies grid/list and sort, verse-of-the-day Bible and picture, commentary sources, study templates
- Header uses one fixed width and reserves scrollbar space so the nav sits in the same place on every page

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 14:10:12 -04:00
nmemmertandClaude Sonnet 5.5 a2185ba1dd Easier navigation on iPhone
Build and Push Docker Image / build-and-push (push) Successful in 5m7s
- Phones get a bottom tab bar (Studies, Bible, Plans, Prayer, Account); wider screens keep the header nav
- The Account menu opens upward from the bar; toasts sit above it
- Reader and study pages get a labelled Home button instead of a small arrow

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 13:54:24 -04:00
nmemmertandClaude Sonnet 5.5 207bfcb919 Version history, notes on highlights and bookmarks, "you've studied this", prayer journal
Build and Push Docker Image / build-and-push (push) Successful in 5m13s
- Earlier versions of a study: the server keeps compressed copies (about one per ten minutes of
  editing, the latest 30); Export shows what differs and puts one back (the replaced copy is kept)
- Notes on highlights and bookmarks: synced, merged without loss, in exports and backups
- Reader verse panel lists your studies and chunks that cover the verse, and opens them
- Prayer journal: requests, who for, linked verses, days prayed, answers; synced, in backups
  and the account export; daily prayer reminder through ntfy
- TODO.md lists the ideas not built yet

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 10:45:32 -04:00
nmemmertandClaude Sonnet 5.5 54cb1c217d Invite-only sign-up, present mode, series, handouts, templates, dictation, progress, sharing
Build and Push Docker Image / build-and-push (push) Successful in 6m47s
- Admin: sign-up Open / Invite only / Closed with single-use invite links
- Present mode for scripts (auto-scroll) and outlines (step through, pace vs planned minutes)
- Series: group studies on the dashboard, filter by series, calendar file for a study's sessions
- Lesson handout: printable page per session (passage, outline, questions, writing lines)
- Save a chunk's notes as your own study template (synced)
- Voice dictation for notes and scripts (browser speech recognition)
- Reading progress: map of the 66 books and a calendar of days read, synced and merged across devices
- Export highlights and bookmarks as Markdown or Word, grouped by named colour
- Verse of the day push to the ntfy topic (needs IQBIBLE_API_KEY)
- Sharing: co-teacher editing via single-use invite links; read-only links can expire and take a passcode

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 10:26:43 -04:00
nmemmertandClaude Sonnet 5.5 f274bc9c8a Harden sync and security; add IQ Bible, templates, password reset, backups
Build and Push Docker Image / build-and-push (push) Successful in 7m14s
Sync and data safety
- Autosave flushes on leaving a study or the tab; storage-full errors are reported
- Unsynced studies, deletes and ink are queued and retried when back online
- Deletes propagate across devices (with a "Keep it" undo) and no longer resurrect
- Server assigns study versions (no client-clock conflicts); "Combine both"
  merges a conflicted study chunk by chunk
- Reading-plan progress made offline is merged, not overwritten; plans, ink and
  marks are cleared from the device on sign-out

Security
- Block SSRF through the ntfy reminder URL; failure-only rate limiting per IP and
  account; constant-time login; TOTP replay protection; input validation;
  SESSION_SECRET required in production; admin user delete fixed
- Forgot password: one-time code sent to the account's ntfy topic

Features
- IQ Bible proxy (route allow-list, text-only caching per its terms): more
  commentaries, lexicons, study aids, daily verse and devotional, plan calendar
  export, narrations, podcast background
- Study templates, reading-plan catch-up, account export, daily database snapshots

Tests and tooling
- ESLint config; App tests split into src/test; tests for sync queues, library
  hook, merge, templates, IQ Bible UI and reset form

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 08:13:36 -04:00
nmemmertandClaude Sonnet 5.5 e5812fd4ee Reader: resizable side panel
Drag the left edge of the verse side panel to resize it (arrow keys too,
Shift for bigger steps; double-click resets). The text reflows to make room,
and the width is remembered on this device. Reuses the Study page's resize
handle; the hook now takes the CSS variable to drive.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 16:37:50 -04:00
nmemmertandClaude Sonnet 5.5 d7a1601f80 Outline: share as a read-only link
- Share on the Outline page opens a sheet: create / copy / turn off a
  read-only link, share the link with the system share sheet, or send the
  outline as text
- The link has its own token (separate from the whole-study share link) and
  the public endpoint returns only the outlines, rebuilt field by field:
  no observations, interpretations, applications, scripts or word notes
- Opening the link shows the outline(s) with no sign-in, a switcher between
  the whole-study and per-chunk outlines, and Print / PDF
- New outline_share_token column (added automatically on start)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 16:02:40 -04:00
nmemmertandClaude Sonnet 5.5 aa27a5bb18 Reader: show how much another translation differs from the one being read
- Word-level comparison (ignores case and punctuation): differing words are
  marked in both columns of the side-by-side view
- Chapter summary ("NET is 18% different from BSB · 37 of 39 verses differ")
  with links to the most different verses, and a percentage on each verse
- Compare tab on a verse shows each translation's difference from the one
  being read, with the differing words marked
- "Highlight differences" setting; your own highlights and search matches
  always win where they overlap a difference mark

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 14:36:46 -04:00
nmemmertandClaude Sonnet 5.5 d13f55faf7 Add Outline stage, parallel reading, offline saves, backup, sync-conflict handling and more
Study
- New Outline stage (hierarchical I./A./1. points, linked to chunks, in all exports);
  the chunk stage is now "Chunks"
- Home cards: passages shown as ranges, tags capped with "+N more"

Reader
- Side-by-side translations and a Compare tab per verse
- Typeface, line spacing, verse-number settings; text and column scale with the screen
- Highlights/bookmarks sheet with named colours (synced); BSB footnote spacing fix
- Cmd-K palette (passages, studies, notes, marks), keyboard shortcuts and "?" help

Flow and safety
- Toasts with Undo replace most confirm()/alert()
- Back/Forward move between pages
- Server refuses saves over a newer copy (409); keep-mine / use-other banner;
  opening a study no longer re-stamps it
- Latest chapter request wins when flipping quickly

Offline and data
- Save books, plan days or a whole BSB/NET for offline
- Service worker fixes: helloao /api/ URLs were skipped and responses cloned too late
- Settings: download/restore a full backup

Accessibility
- Sheets trap focus and close on Escape, skip link, focus ring, reduced motion,
  theme contrast raised to 4.5:1 (with a test)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 14:08:08 -04:00
nmemmertandClaude Sonnet 5.5 7a010fcda8 Resizable right column in the Study stage; start on the chosen page without a flash
Build and Push Docker Image / build-and-push (push) Failing after 20s
The Study stage's right column has a drag handle (mouse, arrow keys, double-click
or Home to reset); the width is remembered per device. The app now starts on the
user's chosen home page from the first render instead of showing My Studies
first. Tests wait on page headings so a lazily loaded page can't be confused
with hidden text from the previous one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 11:01:56 -04:00
nmemmertandClaude Sonnet 5.5 8c4f54e033 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>
2026-09-29 10:55:07 -04:00
nmemmertandClaude Sonnet 5.5 760c1e568b Sync bookmarks, highlights and display preferences to the account
Build and Push Docker Image / build-and-push (push) Failing after 19s
Bookmarks and text highlights are saved per user and merged across devices
(union on first contact, newer server copy when this device is clean). Theme,
default translation, verse layout, commentary source and reading position sync
too, each with its own timestamp so the newest change to each setting wins.
The Reader never moves under you while it is open. Signing out clears this
device's marks and forgets sync timestamps.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 10:45:23 -04:00
nmemmertandClaude Sonnet 5.5 297f2c7e84 Fix plan days with no chapters, add a way out of ink mode, harden ntfy reminders
Build and Push Docker Image / build-and-push (push) Failing after 19s
Plans can no longer have more days than chapters (existing ones heal), and
opening a plan never strands the Reader on an empty day. The Reader shows
Done drawing while inking (Escape also exits). Reminders use the user's own
timezone, send within a 3 hour grace window, and Settings has a Send test
notification button.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 10:34:46 -04:00
nmemmertandClaude Sonnet 5.5 31abee0695 Redesign the study side: Outline, Study, Script and Export stages
Build and Push Docker Image / build-and-push (push) Successful in 4m15s
Studies now move through a stage bar in the reader's themes. Outline splits
chunks by clicking between verses (join merges notes) and suggests chunks from
section headings. Study is three panes: outline, passage with an Observe /
Interpret / Apply accordion, and commentary / word study / cross-refs / people
& places for the chunk; original words are added by clicking them in the
interlinear. Script drafts an outline from notes; Export holds files and the
share link. Home, Import and the Pronunciation guide are restyled. Study
projects are BSB only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 10:13:46 -04:00
nmemmertandClaude Sonnet 5.5 b1bc1c8ea4 Reading plans: integrated into the Reader, redesigned, with per-plan translation
Build and Push Docker Image / build-and-push (push) Failing after 19s
Reader: plan strip with a dot per chapter, plan sheet (day picker, chapter
ticks, translation, streak, other plans), end-of-day card that steps through
the day and rolls into the next, and chapter-level auto-marking.
Each plan remembers its own translation (BSB, ESV, NLT, CSB, NASB, NET) and the
Reader follows it while a plan is open. Plans home redesigned in the reader's
themes with a Continue card, in-progress plans, a filterable catalog, and
sheets for details and the custom-plan builder.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 09:47:51 -04:00
nmemmertandClaude Sonnet 5.5 c11b6a60bf Reader: whole-Bible search in every translation
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>
2026-09-29 09:25:00 -04:00
nmemmertandClaude Sonnet 5.5 3279dddae5 Reader: ESV chapter audio
Build and Push Docker Image / build-and-push (push) Failing after 19s
The Reader's player follows the translation on screen: ESV plays its own
recording via a server route that resolves the ESV API's audio redirect;
other translations keep the BSB narrators.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 09:20:15 -04:00
nmemmertandClaude Sonnet 5.5 9e722a296d Redesign the Reader; add ESV
Build and Push Docker Image / build-and-push (push) Failing after 20s
New reading surface with paper/sepia/dark themes, slim top and bottom bars,
and sheets for navigation, search, settings, audio and per-verse study tools.
Plan progress is built into the reader. Page-flip mode removed. ESV added via
the server-side proxy (ESV_API_KEY).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 09:11:47 -04:00
nmemmertandClaude Sonnet 5.5 9e8420a1ae Reader: verse study panel (commentaries, people & places) and NET Bible
Build and Push Docker Image / build-and-push (push) Failing after 20s
Adds a per-verse panel with seven HelloAO commentaries and Theographic
people/places/events, and NET as a fifth Reader translation.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 08:57:51 -04:00
nmemmertandClaude Sonnet 5.5 22c80d2bc3 Add NLT, CSB and NASB via api.bible proxy; new app logo and icons
Build and Push Docker Image / build-and-push (push) Failing after 21s
Reader and Reading Plans get a translation picker. Licensed translations are
fetched through a server-side api.bible proxy so the key stays off the client.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 08:37:48 -04:00
nmemmertandClaude Sonnet 5 986d2e9331 Surface reading-plan pull failures too, fix StrictMode false sync
Build and Push Docker Image / build-and-push (push) Failing after 21s
The sign-in pull (GET /api/reading-plans -> merge) had the same silent-
failure gap the push side had before the last fix: a failed fetch just
left local state as-is with zero indication anything was wrong. Moved it
into the hook as pullServerReadingProgress(), which reports failures
through the same error banner/retry the push path already uses.

Also found and fixed a real bug while testing this: the "skip syncing on
the very first render" guard used a boolean ref, which React 18 StrictMode
defeats by double-invoking effects in dev — the second invocation saw the
flag already flipped and fired a spurious sync of stale localStorage data
before the app had even confirmed sign-in, occasionally producing a false
"couldn't sync" banner on fresh loads. Replaced it with a reference-equality
check against the state object captured at mount, which both of
StrictMode's synthetic invocations see identically. Caught this in
useReadingPlans.js's own test run, not manual testing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:47:51 -04:00
nmemmertandClaude Sonnet 5 b14dbb52cc Surface reading plan sync failures instead of failing silently
Build and Push Docker Image / build-and-push (push) Successful in 4m34s
Reading plan sync was truly fire-and-forget: a failed PUT to
/api/reading-plans left the change stuck on that device with no
indication anything was wrong, which is exactly what "doesn't sync
across devices" looks like from the outside.

Moved the sync call out of the setState updater and into a proper effect
keyed on state, so success/failure can be tracked. Both Home and Reading
Plans now show a red banner with the actual error (HTTP status or network
error) and a Retry button when a sync fails, mirroring how study project
sync already reports errors. Verified the full cycle locally: normal sync,
a killed-server failure showing the banner, and Retry recovering once the
server's back.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:18:09 -04:00
nmemmertandClaude Sonnet 5 787edcbe73 Connect reading plans to study/audio, cache offline audio, add journal export
Build and Push Docker Image / build-and-push (push) Successful in 4m33s
Reading plan days now offer "Study this" (seeds a new chunk-builder project
with the day's full passage and jumps straight into the Study editor) and
"Listen" (starts book-mode audio at the right chapter via a new
handlePlayBookAudioFrom, avoiding a stale-closure bug the reader-state
approach would hit). Fixed the "Listen to BSB Audio" player only rendering
when a study project existed, leaving Listen with nowhere to show up.

The service worker now caches audio.bible.helloao.org (the actual host
serving narrator audio, not just the text/cross-ref API) and no longer
tries to cache 206 Partial Content responses, which the Cache API rejects
and was throwing unhandled rejections for every range-requested audio file.

Added a reading journal export (Settings > My reading journal): gathers
bookmarks, text highlights, and completed plans, fetches their verse text,
and offers a .docx download or a print-to-PDF page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 13:41:40 -04:00
nmemmertandClaude Sonnet 5 1dd6aef6a5 Add streaks, today view, custom plan editing/chapter ranges, and ntfy reminders
Build and Push Docker Image / build-and-push (push) Failing after 21s
Reading plans now track a cross-plan activity log for streaks, surface a
combined "today's reading" view on both Home and the Reading Plans page,
and let custom plans be edited after creation (including narrowing a book
to a specific chapter range). The reader auto-marks a plan's day read after
a dwell period, active plans that fall behind their pace get a "catch me
up" banner, and a new Settings section wires up daily reading reminders
via ntfy.sh, checked once a minute by a small server-side scheduler.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 13:16:27 -04:00
nmemmertandClaude Sonnet 5 600b3d3ab9 Add reading plans: catalog, progress tracking, and custom plans
Replaces the old single-book reading goal with a full Reading Plans page:
9 built-in plans (Whole Bible, OT/NT, topical) with cover photos and
color-themed cards, day-by-day checklists synced to the server per user,
inline "mark today read" in the Bible reader, and user-created plans with
their own book picker and an optional uploaded cover photo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 12:51:28 -04:00
nmemmertandClaude Sonnet 5 f1026dc194 Redesign audio controls into a real media player
Build and Push Docker Image / build-and-push (push) Successful in 5m5s
Adds a shared AudioPlayer component with a seekable progress bar,
big play/pause button, and icon transport controls, replacing the
row of text buttons on both the book and chapter audio players.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:59:42 -04:00
nmemmertandClaude Sonnet 5 b9f9b97cba Add chapter skip and 10s seek controls to audio players
Build and Push Docker Image / build-and-push (push) Successful in 5m42s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 11:49:32 -04:00
nmemmertandClaude Opus 5.5 0f1a9c3d5b Move chunk builder into SetupPage via useChunkBuilder
- The setup form, active chapter tab, verse range selection, typed/bulk/
  cross-chapter chunk creation, reorder, and delete move out of App.
- Setup now opens on the chapter holding the chunk last studied (e.g.
  after Back to Chunks), and the Add Chapter form suggests the chapter
  after the project's last one instead of repeating the current one.
- openNewProject/goHome/resume/import no longer reset setup state by hand;
  SetupPage starts fresh each time it opens.
- Tests: add-chapter default, Back to Chunks chapter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 15:01:53 -04:00
nmemmertandClaude Opus 5.5 bf02e071fa Move study editor state into StudyPage and hooks
- StudyPage owns layout/tabs/collapsed sections, tags, DOCX script
  import, chunk navigation, keyboard shortcuts, and the selected-chunk
  values derived from the project.
- useStudyResources: commentary + interlinear for the selected chunk's
  chapter. These now load only on the study page (they previously also
  fetched while on Setup).
- useCrossRefs: typed refs, dataset suggestions, verse text.
- useWordStudy: word entries, Strong's lookups, suggestion picker.
- Fix: study-page messages (word suggestions, DOCX import, lookups) set a
  status that only SetupPage displayed, so they were never seen. They
  now show as a toast on the study page.
- copyVerse moves into ReaderPage.
- Tests: toast, arrow-key navigation, cross-refs, tags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:59:22 -04:00
nmemmertandClaude Opus 5.5 4b14b3fbe6 Extract project header, share link, exports, and auth status
- ProjectHeader component replaces the headerButtons JSX in context; it
  owns the export menu and share panel state.
- useShareLink (share status/enable/revoke/copy) and useSharedView
  (?share= read-only view, now used directly by the router).
- utils/projectExport: HTML/Markdown/DOCX download and print-to-PDF.
- AuthStatus component replaces the authStatus JSX in context.
- Pages import wordStudy helpers directly instead of via context.
- Remove dead copyPronunciationGuide (PronunciationPage has its own).
- Tests: Markdown export, enabling a share link, the ?share= view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:56:31 -04:00
nmemmertandClaude Opus 5.5 a7e00a76b5 Split Home: local UI state, useProjectLibrary, useReadingPlan
- Search, tag filter, full-text note search, and rename state live in
  HomePage. The sort choice is remembered in localStorage.
- useProjectLibrary owns opening/renaming/deleting projects and the
  server reconcile (auto-restore + newer-on-server list).
- useReadingPlan owns the reading plan shared by Home and Reader.
- Tests: note search, rename, delete, sort memory, reading plan. Test
  setup now resets the storage namespace between tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:52:46 -04:00
nmemmertandClaude Opus 5.5 8bb3b104c8 Move import state into ImportPage; share translation list via hook
The session-list import form, preview, and runEpisodeImport now live in
ImportPage. useAvailableTranslations fetches the translation list once per
visit for both Import and Setup. Drops the never-read importFile state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:50:21 -04:00
nmemmertandClaude Opus 5.5 49ffefed54 Extract auth into hooks/useAuth; move form state into its pages
Build and Push Docker Image / build-and-push (push) Successful in 6m28s
- useAuth owns authUser/authServerDown, the startup session check, and
  signIn/logout, so every sign-in path runs the same follow-up (switch
  local storage to the account, load reader ink). Previously reader ink
  only loaded on a page refresh, not right after logging in.
- Login/2FA form state now lives in AuthPage, and 2FA setup, password
  change, and podcast name state in SettingsPage (23 fewer context
  values; typing in these forms no longer re-renders all of App).
- Add tests for form sign-in, 2FA, session restore + logout, and the
  Settings podcast-name prefill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:44:52 -04:00
nmemmertandClaude Opus 5.5 009fa1e78f Extract shared audio player into hooks/useAudio
Build and Push Docker Image / build-and-push (push) Failing after 2m25s
The Home page's whole-book player and the Reader's chapter player share one
<audio> element, so they move together. App now just calls
useAudio(readerBook, readerChapter) and spreads the result into context.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:36:59 -04:00
nmemmertandClaude Opus 5.5 ade7f1af6f Speed up the app, run production build, remove chunk ink, start App.jsx split
Performance:
- Lazy-load pages, docx, and mammoth (initial JS 1,298 KB -> ~290 KB)
- Gzip responses and cache hashed assets for a year
- Memoize DrawCanvas strokes so ink isn't redrawn on every render
- Precompute whole-Bible search index and defer the query while typing
- Reload once if a lazy chunk is missing after a deploy

Deployment:
- setup.sh builds and runs one production server on APP_PORT (default
  5173); --dev keeps the old Vite dev setup
- Session cookie uses secure: 'auto' so login works behind any proxy

Chunk editor:
- Remove the Draw layout, Ink Notes panel, and ink in HTML export
  (existing inkStrokes data is left in saved projects)

Refactor:
- Move module-level helpers out of App.jsx into src/utils/*
- Extract Bible reader state and logic into hooks/useBibleReader

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:34:13 -04:00