Commit Graph
154 Commits
Author SHA1 Message Date
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 5287b471d0 Redesign project header and study navigation
Build and Push Docker Image / build-and-push (push) Failing after 20s
- Header: navigation buttons grouped; Study Guide, Podcast, and
  Pronunciation Guide move into a Tools menu (disabled until a chunk
  exists), set apart from Export and Share by a divider.
- Only one header dropdown is open at a time, and it closes on an
  outside click or Escape.
- Study page: drop the duplicate Prev/Next and counter at the top; the
  fixed bottom bar is the single chunk navigation and now shows a
  readable "Chunk N of M".
- Mobile empty-state hint points to Back to Chunks.
- Tests: Tools menu, one-dropdown-at-a-time, Escape/outside click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 15:37:29 -04:00
nmemmertandClaude Opus 5.5 33e3f2bdc6 Fix Greek lookup test expecting a single 'faith, belief' field
Build and Push Docker Image / build-and-push (push) Successful in 4m7s
With no gloss-map entry, the English gloss falls back to the KJV
definition, so both English Gloss and Short Definition show it. Assert
both instead of failing on the duplicate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 15:35:32 -04:00
nmemmertandClaude Opus 5.5 d08c701698 Fix Pronunciation page Speak buttons; tidy App.jsx
Build and Push Docker Image / build-and-push (push) Successful in 7m53s
PronunciationPage still read speakOriginalWord from context after it
moved to utils/wordStudy, so Speak would have thrown. Import it directly.
App.jsx: consolidate imports, update comments, list all pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 15:04:55 -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 365fb1b567 Keep draw pen settings inside DrawCanvas
Only the Reader's canvas uses them now. A module-level lastPen keeps the
chosen tool/color/size when Draw mode is toggled off and on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:53:17 -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 d7bbbe60de Move word-study helpers into utils/wordStudy
Strong's dictionary loaders, lexicon lookup, gloss helpers, cross-ref
formatting, and speech move out of App. Dictionaries are now cached at
module level (still one download per visit), and a failed download is no
longer cached forever, so the next lookup retries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:49:21 -04:00
nmemmertandClaude Opus 5.5 8c55765ae6 Move admin state into AdminPage
Build and Push Docker Image / build-and-push (push) Failing after 21s
All admin state (tab, users, projects, loading/error, preview, reset
result) and the data loader were only used by AdminPage, so they now live
there as local state instead of in App's context. The page loads its data
when it opens (still gated on authUser.isAdmin; the server enforces it too).

Add tests: admin sees users and projects, deleting a user reloads the
list, and non-admins get no Admin button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:46:35 -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
nmemmertandClaude Sonnet 4.6 00932dee4a Update restart.sh to reference Gitea instead of GitHub
Build and Push Docker Image / build-and-push (push) Successful in 2m36s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 09:39:49 -04:00
nmemmertandClaude Sonnet 4.6 85fc566ade Add Pronunciation Guide page with word cards and TTS
Build and Push Docker Image / build-and-push (push) Successful in 3m37s
Replace the copy-to-clipboard button with a dedicated page that shows
all collected Greek/Hebrew words as cards grouped by language. Each
card displays the original script large, transliteration, Strong's
number, English gloss, definition, part of speech, and a Speak button.
Includes a search/filter and a "Copy all" fallback for the old behavior.

Move buildPronunciationGuide to bibleUtils.jsx to avoid circular imports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 09:27:52 -04:00
nmemmertandClaude Sonnet 4.6 7b2920b9e6 Default study layout to split view
Build and Push Docker Image / build-and-push (push) Successful in 3m16s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 09:22:02 -04:00
nmemmertandClaude Sonnet 4.6 9b9de74084 Fix Vite parsing git objects as JS modules on dev server
Build and Push Docker Image / build-and-push (push) Successful in 3m2s
- Add server.watch.ignored for .git/** so chokidar doesn't pick up
  changes to git object files during git pull/fetch on the server
- Add .dockerignore to exclude .git, node_modules, and dist from
  the Docker build context

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 09:20:26 -04:00
nmemmertandClaude Sonnet 4.6 b98aae741f Fix circular imports causing React dispatcher null error
Build and Push Docker Image / build-and-push (push) Successful in 4m0s
Extract shared utilities (constants, helpers, components) from App.jsx
into src/utils/bibleUtils.jsx so page components can import from there
instead of from App.jsx. This breaks the App.jsx <-> pages circular
dependency that was triggering vite:import-analysis warnings and causing
the React hook dispatcher to be null at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 18:36:21 -04:00
nmemmertandClaude Sonnet 4.6 c804aa2ccc Fix Docker build: upgrade npm to 11 to match lockfile format
Build and Push Docker Image / build-and-push (push) Successful in 11m51s
package-lock.json was generated with npm 11; node:20-alpine ships with
npm 10 which can't resolve optional esbuild platform packages from the
newer lockfile format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:49:37 -04:00
nmemmertandClaude Sonnet 4.6 cc234e8192 Fix Docker build: add native build tools for better-sqlite3
Build and Push Docker Image / build-and-push (push) Failing after 2m14s
better-sqlite3 is a native C++ addon that requires python3, make, and g++
to compile on Alpine Linux. Added to both builder and production stages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:30:05 -04:00
nmemmertandClaude Sonnet 4.6 2d659c4fe9 Add Gitea Actions workflow to build and push Docker image
Build and Push Docker Image / build-and-push (push) Failing after 4m9s
Builds on push to main and version tags, pushes to git.necloud.us container registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:23:44 -04:00
nmemmertandClaude Sonnet 4.6 2106595976 Show passage text in inline Ink Notes canvas
Passes selectedChunkVerses as headerContent to the inline DrawCanvas so
highlights overlay the actual scripture text, matching annotate mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-20 10:40:47 -04:00
nmemmertandClaude Sonnet 4.6 902fb5da02 Add Apple Pencil support, reading plan, full-text search, and inline ink
- Apple Pencil hover cursor: previews brush size/shape before contact
- Tilt shading: tilted pen strokes widen and reduce thinning via tiltX/Y
- Two-finger undo in draw mode (non-stylus two-finger tap)
- Copy & open Claude buttons: copies study/podcast prompt then opens claude.ai/new
- Inline ink canvas in study notes (DrawCanvas embedded in Notes tab)
- Full-text search across all project notes with 300ms debounce
- Reading plan: set a book + week goal, mark chapters read from the reader

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-20 10:15:45 -04:00
nmemmertandClaude Sonnet 4.6 837b81b038 Add page-flip reader mode — fixed-height CSS-columns panel
Adds a "Page" toggle in the reader tool strip. When enabled, the verse
panel becomes a fixed-height container using CSS column-width to create
one column per page-width. Content flows naturally into successive pages;
long chapters simply have more pages. Bottom nav shows ← Back/Prev ch.
and Next/Next ch. → with a page counter (e.g. Genesis 1 · 2/3). Swipe
left/right and arrow keys also navigate pages before crossing chapter
boundaries. Preference persisted to localStorage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-13 16:38:25 -04:00
nmemmertandClaude Sonnet 4.6 708f293939 Auto-hide toolbar in wide reader mode with focus bar restore
Wide mode now enters focus state automatically: the full toolbar collapses
and a slim frosted bar appears at the top showing the current chapter name,
Prev/Next buttons, and a ⚙ Tools button to restore the toolbar. A ✕ Hide
button inside the toolbar lets you re-enter focus mode without toggling wide.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-13 16:21:08 -04:00
nmemmertandClaude Sonnet 4.6 f2de985190 Add reader navigation: swipe, keyboard, side arrows, and wide layout
- Swipe left/right on mobile to go between chapters (60px threshold,
  ignores vertical-dominant gestures so scrolling still works)
- Left/right arrow keys on desktop navigate chapters (skips inputs)
- Fixed side ‹ › buttons at viewport midpoint for one-tap chapter nav;
  disappear when at the first/last chapter, hidden in draw mode
- Wide toggle (⊞) switches between narrow reading column (max-w-3xl)
  and full-width two-column layout (max-w-7xl, md:columns-2); persisted
  to localStorage so the preference survives page reloads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-13 16:17:41 -04:00
nmemmertandClaude Sonnet 4.6 90fd5c4e9e Add fixed bottom chunk nav and IndexedDB Bible search cache
- Replace non-functional sticky nav with a fixed bottom bar (position: fixed)
  that stays visible while scrolling long study notes; hides in draw mode
- Add pb-20 to main so the bar never covers the last study section
- Cache whole-Bible search index (BSB complete.json, ~7MB) in IndexedDB
  with a 7-day TTL so repeated searches skip the network fetch entirely

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-13 16:08:25 -04:00
nmemmertandClaude Sonnet 4.6 22ad12e677 Add text highlighting in reader — select text to color, visible in read and draw mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-13 15:03:08 -04:00
nmemmertandClaude Sonnet 4.6 b4ccc15f98 Add XS pen size and make it the default
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 13:43:19 -04:00
nmemmertandClaude Sonnet 4.6 1a586db785 Sync reader draw ink to server for cross-device persistence
Previously reader ink was localStorage-only so it never followed the
user to a different browser or device.

- New reader_ink table (user_id, book_abbrev, chapter, strokes JSON)
- GET /api/reader/ink  — loads all pages for the signed-in user
- PUT /api/reader/ink/:book/:chapter — upserts one page
- On startup, client fetches server ink and merges it over localStorage
  (server wins so the most-recently saved version always wins)
- updateReaderPageInk debounces a PUT call 1 s after the last stroke,
  so rapid Apple Pencil strokes don't flood the server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 12:16:21 -04:00
nmemmertandClaude Sonnet 4.6 5668686f59 Fix PWA header buttons unreachable on iPad
black-translucent status bar overlays page content, pushing the top
nav buttons behind the status bar where they can't be tapped. Switch
to black (status bar takes its own space, content starts below).

Also add env(safe-area-inset-top) padding on <header> elements when
running in standalone/PWA mode so notched iPhones are handled too.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 11:46:35 -04:00
nmemmertandClaude Sonnet 4.6 692595c629 Add PWA support and expandable draw canvas
PWA:
- manifest.json with name, icons, theme/background color, standalone display
- PNG icons (192, 512, 180 apple-touch) generated via pure Node.js (no deps)
- index.html: manifest link, theme-color, apple-mobile-web-app-* meta tags,
  viewport-fit=cover for iPhone notch/Dynamic Island
- service worker extended to cache app shell (static assets + index.html)
  with network-first for navigation, cache-first for hashed assets,
  network-first-with-cache-fallback for external Bible APIs

Expandable canvas:
- "Add More Space" button below each draw canvas adds a full notebook page
- Existing ink rescales to preserve visual pixel positions (no stretching)
- Page count embedded as metadata in the strokes array so it survives
  navigation without a separate state key

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 11:28:23 -04:00
nmemmertandClaude Sonnet 4.6 a947b128b9 Keep draw mode active when navigating chapters in reader
Previously draw mode was closed whenever the book or chapter changed.
Now it stays open so the user can flip between chapters while drawing;
each chapter has its own canvas (ink is keyed per bookAbbrev_chapter).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 11:17:10 -04:00
nmemmertandClaude Sonnet 4.6 9a99247f8d Fix Apple Pencil double-tap bug: switch to Touch Events API on iOS
iPadOS Pointer Events fire pointercancel immediately after pointerdown
for Apple Pencil strokes (triggered by palm detection or canvas-width
resets from React re-renders), forcing the user to tap twice to start
every stroke. The Touch Events API with touchType === 'stylus' bypasses
this issue entirely — Touch Events have no equivalent cancellation
problem and reliably identify Pencil vs finger input. Pointer Events
remain as the fallback for non-iOS platforms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 10:08:32 -04:00
nmemmertandClaude Sonnet 4.6 717a9b3da0 Switch canvas pointer events to native addEventListener
React's synthetic event system delegates to the document root, which
on iOS Safari causes pointermove passive:true to block preventDefault
and introduces timing issues that drop every other stroke.

Attaching directly to the canvas element with {passive: false} on
pointermove gives iOS the explicit signal it needs to suppress scroll
and deliver all pen events reliably.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 09:23:16 -04:00
nmemmertandClaude Sonnet 4.6 cf040ff8dd Fix alternating stroke drop on iPadOS with Apple Pencil
setPointerCapture/hasPointerCapture is unreliable on iPadOS — Safari
sometimes fires pointercancel which releases capture, causing every other
stroke's pointermove events to be discarded. Replace with a simple
isDrawingRef boolean that is set on pointerdown and cleared on pointerup,
avoiding the capture API entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 09:14:33 -04:00
nmemmertandClaude Sonnet 4.6 0a2def9b60 Prevent text selection during Apple Pencil drawing
Add user-select: none (with WebKit prefix) to the DrawCanvas wrapper so
the browser does not start a text-selection gesture when the pencil drags
across the component.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 09:09:02 -04:00
nmemmertandClaude Sonnet 4.6 250d59290d Fix Apple Pencil scrolling during draw by setting touchAction none
touchAction: 'pan-y pinch-zoom' let the browser intercept vertical
pencil movement as a scroll gesture before JavaScript could prevent it.
Setting 'none' hands all pointer input to our handlers exclusively.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 09:07:02 -04:00
nmemmertandClaude Sonnet 4.6 edc5f3dae1 Auto git pull on restart
Discards any local package-lock.json drift (cross-platform regeneration)
then pulls latest from GitHub before setup.sh runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 09:04:28 -04:00
nmemmertandClaude Sonnet 4.6 9013dc4fc4 Expand reader draw mode to full screen width
Use max-w-full on main when draw mode is active so the layout fills the
viewport. Scripture panel is a fixed 288px column; notebook canvas takes
all remaining space.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 09:00:03 -04:00
nmemmertandClaude Sonnet 4.6 42203c038e Reader draw mode: Bible text left, notebook right
Replace stacked scripture-overlay layout with a side-by-side flex row:
the chapter text panel sits on the left (sticky, scrollable) and the
ruled notebook canvas sits on the right. Stacks vertically on mobile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 08:57:52 -04:00