Skip to content

Implement songbooks#972

Open
TheNonPirate wants to merge 19 commits into
sillsdev:mainfrom
TheNonPirate:feature/songbooks/859
Open

Implement songbooks#972
TheNonPirate wants to merge 19 commits into
sillsdev:mainfrom
TheNonPirate:feature/songbooks/859

Conversation

@TheNonPirate

@TheNonPirate TheNonPirate commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Closes #859 and building on #881. This implements songbooks. When a songbook is selected, the app goes to a page that allows the user to select which song they want, sorted by number or title. Currently, the song's text is rendered the same as any scripture book, which means that it does not perfectly match the mobile app.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added songs as a supported book type with a dedicated interface
    • Two browsable views for songs: browse by title or by number
    • Search capability enabled for songs collections
  • Changes

    • Verse selection automatically hides when viewing songs content

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds end-to-end support for songs as a native book type: converting songs USFM with chapter-verse preprocessing, routing songs navigation to a dedicated page at /songs/{collection}/{id}, loading tab-separated song lists from generated assets, disabling verse selection for songs, and rendering chapter numbers immediately in the scripture view.

Changes

Songs Book Type Support

Layer / File(s) Summary
Enable songs in USFM conversion
convert/convertBooks.ts
Remove songs from unsupportedBookTypes, add case 'songs' fallthrough to main conversion path, and preprocess songs USFM by inserting \v 1 after each \s ... section heading before the normal filter/import pipeline.
Navigation and UI updates
src/lib/components/BookSelector.svelte, src/lib/components/ChapterSelector.svelte
Add /songs/{collection}/{id} routing for songs books in getBookUrl, update navigateReference to set reference fields and await navigation before URL routing, and disable verse selector for songs book type via computed showVerseSelector logic.
Songs page loader and data pipeline
src/routes/songs/[collection]/[id]/+page.ts
Discover and fetch generated song asset files (title and number lists) using import.meta.glob, parse tab-separated content into songsByTitle and songsByNumber arrays, resolve display label from config, and return structured data for page consumption.
Songs collection page and interaction
src/routes/songs/[collection]/[id]/+page.svelte
Render tabbed UI switching between song-by-title and song-by-number views with navbar controls (BookSelector, ChapterSelector), apply styling from config store, and navigate song selections via completeNavigation which updates references and triggers text navigation.
Scripture view chapter rendering for songs
src/lib/components/ScriptureViewSofria.svelte
Insert chapter number markup immediately for songs books in chapter_label mark handler, supporting drop-cap or top-of-page formats controlled by the chapter-number-format feature setting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • sillsdev/appbuilder-pwa#842: Modifies BookSelector.svelte navigation logic and chapter defaulting; the songs navigation changes in this PR are code-adjacent to that PR's HTML-book navigation fixes.

Suggested reviewers

  • chrisvire
  • FyreByrd

Poem

🎵 A rabbit hops through verses new,
With songs now woven in the brew,
Tab-separated melodies flow,
From assets fetched with gentle glow—
Each chapter marked, each song displayed,
In tabbed delight, the features made! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature being implemented: songbook functionality across multiple components, data fetching, routing, and rendering.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@TheNonPirate TheNonPirate requested a review from FyreByrd June 6, 2026 01:16
Comment thread convert/convertBooks.ts Outdated
@TheNonPirate TheNonPirate marked this pull request as ready for review June 8, 2026 22:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/components/BookSelector.svelte (1)

97-112: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid navigateToText in the URL-navigation branch.

This branch now does two navigations: navigateToText(...) (which goes to /text and records history) and then navigateToUrl(...). That creates an unintended intermediate route jump and extra history entry for songs/quiz selection.

Use a state-only reference update (refs.set(...) or a dedicated helper) before navigateToUrl(...) instead of navigateToText(...).

Suggested fix
-            await navigateToText({
+            await refs.set({
                 docSet: $refs.docSet,
-                collection: $refs.collection,
                 book: $nextRef.book,
                 chapter: $nextRef.chapter,
                 verse: $nextRef.verse
             });
             navigateToUrl({
                 collection: $refs.collection,
                 book: text,
                 url: url
             });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/components/BookSelector.svelte` around lines 97 - 112, The branch
currently calls navigateToText(...) then navigateToUrl(...), causing an unwanted
intermediate route and history entry; replace the navigateToText call with a
state-only update using refs.set(...) or the existing refs helper so you only
update $nextRef.book/$nextRef.chapter/$nextRef.verse (or call refs.set({ book:
text, chapter: '1', verse: '' })) and then call navigateToUrl({ collection:
$refs.collection, book: text, url }); remove the await navigateToText(...) call
and ensure only the state is mutated before navigateToUrl to avoid pushing /text
into history.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@convert/convertBooks.ts`:
- Around line 770-772: The current songs branch in convertBooks.ts
unconditionally appends "\v 1" after every section header (the block where
book.type === 'songs' and content is modified), causing duplicate verse markers;
change the replacement so it only inserts "\v 1" when the header line is not
already immediately followed by a verse marker (i.e., ensure the match checks
the following line does not start with "\v"). Locate the snippet that does
content = content.replace(/^\\s.*$/gm, '$&\n\\v 1') and update the regex or
replacement logic to include a negative lookahead (or a small callback that
inspects the next line) so headers already followed by "\v" are left unchanged.

In `@src/lib/components/ChapterSelector.svelte`:
- Around line 21-26: The derived value showVerseSelector currently treats an
unresolved book (where ?.type is undefined) as not 'songs' and thus true; update
the $derived expression to first resolve the current book into a variable and
explicitly check its existence before comparing its type (e.g., ensure the found
book object exists and then evaluate bookObj.type !== 'songs'), using
$userSettingsOrDefault, scriptureConfig, $refs.collection and book to locate the
book; keep the final result cast to boolean so unresolved/missing book yields
false instead of true.

In `@src/lib/components/Sidebar.svelte`:
- Around line 81-82: The divider is shown because showSongbooks is hardcoded
true while the actual songbook <li> is commented out; update the Sidebar.svelte
logic so the separator only appears when a real songbook menu item will render.
Either set showSongbooks to the real feature flag or runtime condition used
elsewhere (remove the hardcoded const showSongbooks = true) or remove
showSongbooks from the divider condition so the separator uses the same
visibility expression as the songbook <li> (match the condition used for
rendering the commented-out menu item); apply the same fix for the duplicate
instance around the block referenced at lines ~217-225.

In `@src/routes/songs/`[collection]/[id]/+page.svelte:
- Around line 19-31: The parsing logic for data.titleData and data.numberData is
fragile because it only splits on '\r\n'; update the split to use a
cross-platform regex like /\r?\n/ and filter out empty lines before splitting
each line on '\t', so that songsByTitle and songsByNumber are built correctly
for LF-only or CRLF files; keep existing checks for separatedValue.length === 2
and push objects with number and title as before.
- Around line 45-50: completeNavigation currently reads $refs.collection and
$refs.book which can be stale on deep links; update the navigateToText call to
use the route loader values (data.collection and data.songId) as the source of
truth. Replace references to $refs.collection and $refs.book inside
completeNavigation/navigateToText invocation with data.collection and
data.songId (keep songNumber and $nextRef.verse as before) so navigation is
deterministic even when the stores are not initialized.

In `@src/routes/songs/`[collection]/[id]/+page.ts:
- Around line 23-47: The current single try/catch around both fetches causes one
failure to skip the other; split the work so title and number are fetched
independently (either wrap the title fetch block that sets
titleKey/titleUrl/titleResponse/titleData in its own try/catch and do the same
for the numberKey/numberUrl/numberResponse/numberData, or replace both with a
Promise.allSettled that fetches both URLs and assigns titleData/numberData only
for fulfilled results), log errors per asset instead of rethrowing so a failure
in one asset does not wipe the other’s data.

---

Outside diff comments:
In `@src/lib/components/BookSelector.svelte`:
- Around line 97-112: The branch currently calls navigateToText(...) then
navigateToUrl(...), causing an unwanted intermediate route and history entry;
replace the navigateToText call with a state-only update using refs.set(...) or
the existing refs helper so you only update
$nextRef.book/$nextRef.chapter/$nextRef.verse (or call refs.set({ book: text,
chapter: '1', verse: '' })) and then call navigateToUrl({ collection:
$refs.collection, book: text, url }); remove the await navigateToText(...) call
and ensure only the state is mutated before navigateToUrl to avoid pushing /text
into history.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d37e2dc9-8329-491c-80c8-6c0bf03383dc

📥 Commits

Reviewing files that changed from the base of the PR and between e0bc617 and 3ab317a.

📒 Files selected for processing (9)
  • convert/convertBooks.ts
  • src/lib/components/BookSelector.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/components/Sidebar.svelte
  • src/lib/icons/SongBookIcon.svelte
  • src/lib/icons/index.ts
  • src/lib/types.ts
  • src/routes/songs/[collection]/[id]/+page.svelte
  • src/routes/songs/[collection]/[id]/+page.ts

Comment thread convert/convertBooks.ts Outdated
Comment thread src/lib/components/ChapterSelector.svelte Outdated
Comment thread src/lib/components/Sidebar.svelte Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.svelte Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.svelte
Comment thread src/routes/songs/[collection]/[id]/+page.ts
This was referenced Jun 9, 2026
const showVerseSelector = $derived($userSettingsOrDefault['verse-selection']) as boolean;
const showVerseSelector = $derived(
$userSettingsOrDefault['verse-selection'] &&
scriptureConfig.bookCollections

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar filter should be in BookSelector?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior in the native app is that the verse selector still shows up for the book selector, but not for the chapter selector. Do we want to keep it how it is to match the native app, or change it because it doesn't make much sense to still have the verse selector for songs?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my mind at least, it doesn't really make any sense to keep it, but on the other hand fidelity to the native app is still important... Thoughts @chrisvire ?

Comment thread src/lib/components/ChapterSelector.svelte Outdated
Comment thread src/lib/components/Sidebar.svelte Outdated
const showNotes = !!config.mainFeatures['annotation-notes'];
const showHighlights = !!config.mainFeatures['annotation-highlights'];
const showPlans = scriptureConfig.plans?.plans.length;
const showSongbooks = true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be incomplete.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (And the SongBookIcon) was part of some code in the previous attempt at songbooks. It added an icon in the menu that apparently could be used to go directly to the songbook. However, I can't find any setting in SAB that would cause such an icon to show up. Do you know of any such setting, or should I just remove this completely?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea. That would be a question for @chrisvire

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to go ahead and remove it. If it really is a setting that we need to support, I can reimpliment it.

Comment thread src/lib/icons/SongBookIcon.svelte Outdated
Comment thread src/lib/types.ts Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.ts
Comment thread src/routes/songs/[collection]/[id]/+page.svelte Outdated
@TheNonPirate TheNonPirate force-pushed the feature/songbooks/859 branch from 3ab317a to cecf77f Compare June 9, 2026 22:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
src/routes/songs/[collection]/[id]/+page.svelte (3)

20-33: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Song parsing is newline-format fragile.

The parser splits only on '\r\n', so LF-only files ('\n') won't parse correctly. Use a cross-platform split like /\r?\n/ and filter empty lines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/songs/`[collection]/[id]/+page.svelte around lines 20 - 33, The
parsing uses data.titleData.split('\r\n') and data.numberData.split('\r\n'),
which fails on LF-only files; update both splits to use a cross-platform regex
(e.g. /\r?\n/) and filter out empty lines before processing so blank lines are
skipped; keep the rest of the logic that maps parts to songsByTitle and
songsByNumber and still guard on separatedValue.length === 2.

46-54: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use route data as the source of truth for song navigation.

completeNavigation reads $refs.collection and $refs.book, which can be stale on deep links or when stores aren't initialized. The loader already provides data.collection and data.songId; use those for deterministic navigation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/songs/`[collection]/[id]/+page.svelte around lines 46 - 54,
completeNavigation currently reads from reactive stores $refs.collection and
$refs.book which can be stale; change it to use the route loader values instead
(data.collection and data.songId) so navigation is deterministic. Update
completeNavigation to call navigateToText with docSet: $refs.docSet (if still
valid) but replace collection: $refs.collection and book: $refs.book with
collection: data.collection and chapter/verse derived from data.songId (or
data.songId parsed into chapter and verse) and ensure you pass the existing
$nextRef.verse; locate the function completeNavigation and the call to
navigateToText to make this swap and handle parsing of data.songId if needed.

18-33: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Data processing should be moved to $derived or the loader.

Parsing raw strings in an IIFE runs once at component initialization and isn't reactive to data changes. Either refactor to $derived for reactivity or move parsing to +page.ts for better separation of concerns.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/songs/`[collection]/[id]/+page.svelte around lines 18 - 33, Move
the parsing logic out of the IIFE and into a reactive or loader context: either
create derived stores that produce songsByTitle and songsByNumber from
data.titleData and data.numberData (use Svelte's $derived or $: reactive
statements to split by '\r\n' and '\t' so updates to data propagate), or perform
the parsing in the page loader (+page.ts) and return parsed songsByTitle and
songsByNumber from load so the component uses them directly; update references
to songsByTitle/songsByNumber in the component and remove the IIFE to keep
concerns separated and ensure reactivity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/routes/songs/`[collection]/[id]/+page.svelte:
- Line 36: Replace the static let tabs = [...] with a reactive derived store so
labels update when the translation store changes: import { derived } from
'svelte/store' and change to const tabs = derived(t, $t =>
[$t['Song_List_By_Number'], $t['Song_List_By_Title']]); update any template
usages from {tabs} to {$tabs} (or adjust code that expected an array
accordingly) so tab labels react to language changes.

---

Duplicate comments:
In `@src/routes/songs/`[collection]/[id]/+page.svelte:
- Around line 20-33: The parsing uses data.titleData.split('\r\n') and
data.numberData.split('\r\n'), which fails on LF-only files; update both splits
to use a cross-platform regex (e.g. /\r?\n/) and filter out empty lines before
processing so blank lines are skipped; keep the rest of the logic that maps
parts to songsByTitle and songsByNumber and still guard on separatedValue.length
=== 2.
- Around line 46-54: completeNavigation currently reads from reactive stores
$refs.collection and $refs.book which can be stale; change it to use the route
loader values instead (data.collection and data.songId) so navigation is
deterministic. Update completeNavigation to call navigateToText with docSet:
$refs.docSet (if still valid) but replace collection: $refs.collection and book:
$refs.book with collection: data.collection and chapter/verse derived from
data.songId (or data.songId parsed into chapter and verse) and ensure you pass
the existing $nextRef.verse; locate the function completeNavigation and the call
to navigateToText to make this swap and handle parsing of data.songId if needed.
- Around line 18-33: Move the parsing logic out of the IIFE and into a reactive
or loader context: either create derived stores that produce songsByTitle and
songsByNumber from data.titleData and data.numberData (use Svelte's $derived or
$: reactive statements to split by '\r\n' and '\t' so updates to data
propagate), or perform the parsing in the page loader (+page.ts) and return
parsed songsByTitle and songsByNumber from load so the component uses them
directly; update references to songsByTitle/songsByNumber in the component and
remove the IIFE to keep concerns separated and ensure reactivity.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f54c3c7-12b3-458d-9d83-bb2f5b033427

📥 Commits

Reviewing files that changed from the base of the PR and between 3ab317a and cecf77f.

📒 Files selected for processing (9)
  • convert/convertBooks.ts
  • src/lib/components/BookSelector.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/components/Sidebar.svelte
  • src/lib/icons/SongBookIcon.svelte
  • src/lib/icons/index.ts
  • src/lib/types.ts
  • src/routes/songs/[collection]/[id]/+page.svelte
  • src/routes/songs/[collection]/[id]/+page.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/icons/index.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/lib/types.ts
  • src/lib/components/Sidebar.svelte
  • src/lib/components/BookSelector.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/icons/SongBookIcon.svelte
  • convert/convertBooks.ts
  • src/routes/songs/[collection]/[id]/+page.ts

Comment thread src/routes/songs/[collection]/[id]/+page.svelte Outdated
@TheNonPirate

Copy link
Copy Markdown
Contributor Author

I realized that SAB has a "Hide verse number 1 if it is directly after the chapter number" feature, which is enabled in the project that I'm testing but can be disabled. This means that my approach of inserting a verse number 1 at the beginning of the song in order to display the chapter number won't work because it can lead to the dummy verse number being displayed.

@TheNonPirate TheNonPirate force-pushed the feature/songbooks/859 branch from 7b43833 to 8d9238d Compare June 10, 2026 17:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/components/ScriptureViewSofria.svelte`:
- Around line 2025-2028: The code mixes reactive $refs (e.g. $refs.book,
$refs.collection) with the non-reactive references object (references.book,
references.collection), causing inconsistent reads; update the two lines that
declare book and bookType to consistently use the same source (use
references.book and references.collection to match surrounding logic) and derive
bookType from scriptureConfig.bookCollections?.find(x => references.collection
=== x.id)?.books.find(b => references.book === b.id)?.type so all lookups
reference the same variables (references.book, references.collection, and
scriptureConfig.bookCollections).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d440dfdc-d712-425b-bc88-dc70bccac387

📥 Commits

Reviewing files that changed from the base of the PR and between cecf77f and 8d9238d.

📒 Files selected for processing (9)
  • convert/convertBooks.ts
  • src/lib/components/BookSelector.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/components/ScriptureViewSofria.svelte
  • src/lib/components/Sidebar.svelte
  • src/lib/icons/SongBookIcon.svelte
  • src/lib/icons/index.ts
  • src/routes/songs/[collection]/[id]/+page.svelte
  • src/routes/songs/[collection]/[id]/+page.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/icons/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • convert/convertBooks.ts
  • src/lib/components/BookSelector.svelte
  • src/lib/icons/SongBookIcon.svelte

Comment thread src/lib/components/ScriptureViewSofria.svelte Outdated

@FyreByrd FyreByrd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation on the first line doesn't look right compared to the rest of the lines.
Image
Native for comparison:
Image

We may also want to horizontally center the container??

Also, Hark the Herald Angels Sing is missing a lot of the first letter of each line, this should probably be fixed.

Finally, there are some merge conflicts, so you'll need to rebase again.

@TheNonPirate

Copy link
Copy Markdown
Contributor Author

I think the indentation issue is there on Scripture books as well, just not as obviously generally. In this example, the same general issue can be seen:
image
image

I'm pretty sure the container is also not horizontally centered in Scripture books either.
Should these be fixed in this PR or a separate one?

@TheNonPirate TheNonPirate force-pushed the feature/songbooks/859 branch from a4994e3 to 7bd1d17 Compare June 10, 2026 21:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
convert/convertBooks.ts (1)

505-529: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Unresolved merge conflict markers break compilation.

Lines 505-509 contain Git merge conflict markers that cause syntax errors. The static analysis confirms the code cannot be parsed.

Based on the PR objectives (enable songs processing, handle story specially), resolve by:

  1. Removing the conflict markers
  2. Removing case 'songs': (songs should now fall through to default for scripture processing)
  3. Keeping case 'story': before default: at line 529 for the special page-to-chapter conversion in lines 888-896
🔧 Proposed fix
             switch (book.type) {
-<<<<<<< HEAD
-                case 'songs':
-=======
-                case 'story':
->>>>>>> f2db8b4 (Feature- Songbooks)
                 case 'audio-only':
                 case 'bloom-player':
                 case 'undefined':
                     break;
                 case 'quiz':
                     bookConverted = true;
                     // ... quiz handling ...
                     break;
                 case 'story':
                 default:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@convert/convertBooks.ts` around lines 505 - 529, Remove the Git conflict
markers and the obsolete case branch so the switch compiles: delete the <<<<<<<,
=======, and >>>>>>> markers and remove the case 'songs': clause so songs fall
through to the existing default/scripture handling; ensure case 'story': remains
present immediately before the default branch in the same switch (so story
continues to trigger the special page-to-chapter conversion logic used by
convertQuizBook/convertBooks), and verify break/return flow for case 'story' and
subsequent cases is correct to avoid fall-through bugs.

Source: Linters/SAST tools

🧹 Nitpick comments (1)
convert/convertBooks.ts (1)

394-395: 💤 Low value

Unused bookType parameter.

The bookType parameter was added to applyFilters but is never used in the function body. Either remove it or implement the intended conditional logic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@convert/convertBooks.ts` around lines 394 - 395, The applyFilters function
signature currently includes an unused bookType parameter; remove bookType from
the applyFilters signature in convert/convertBooks.ts (and drop it from any
callers) to eliminate the dead parameter, or if the intent was to filter by type
implement the check inside applyFilters (e.g., accept bookType and
early-return/filter items when their type doesn't match) and ensure all call
sites pass the correct value; update the function named applyFilters and any
callers to be consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@convert/convertBooks.ts`:
- Around line 505-529: Remove the Git conflict markers and the obsolete case
branch so the switch compiles: delete the <<<<<<<, =======, and >>>>>>> markers
and remove the case 'songs': clause so songs fall through to the existing
default/scripture handling; ensure case 'story': remains present immediately
before the default branch in the same switch (so story continues to trigger the
special page-to-chapter conversion logic used by convertQuizBook/convertBooks),
and verify break/return flow for case 'story' and subsequent cases is correct to
avoid fall-through bugs.

---

Nitpick comments:
In `@convert/convertBooks.ts`:
- Around line 394-395: The applyFilters function signature currently includes an
unused bookType parameter; remove bookType from the applyFilters signature in
convert/convertBooks.ts (and drop it from any callers) to eliminate the dead
parameter, or if the intent was to filter by type implement the check inside
applyFilters (e.g., accept bookType and early-return/filter items when their
type doesn't match) and ensure all call sites pass the correct value; update the
function named applyFilters and any callers to be consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b65ef962-a59c-48af-87e1-b911a629b834

📥 Commits

Reviewing files that changed from the base of the PR and between 8d9238d and 7bd1d17.

📒 Files selected for processing (9)
  • convert/convertBooks.ts
  • src/lib/components/BookSelector.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/components/ScriptureViewSofria.svelte
  • src/lib/components/Sidebar.svelte
  • src/lib/icons/SongBookIcon.svelte
  • src/lib/icons/index.ts
  • src/routes/songs/[collection]/[id]/+page.svelte
  • src/routes/songs/[collection]/[id]/+page.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/icons/index.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/lib/components/BookSelector.svelte
  • src/lib/components/Sidebar.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/components/ScriptureViewSofria.svelte
  • src/lib/icons/SongBookIcon.svelte
  • src/routes/songs/[collection]/[id]/+page.ts
  • src/routes/songs/[collection]/[id]/+page.svelte

@TheNonPirate TheNonPirate force-pushed the feature/songbooks/859 branch from 6a675fb to 9ee59bc Compare June 11, 2026 16:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/components/ScriptureViewSofria.svelte`:
- Around line 2035-2067: The song chapter number is rendered in the
chapter_label path but workspace.chapterNumText is left populated so
handleVerseLabel (used by verses_label) renders it again; after you append the
chapter number DOM node in the song branch of the chapter_label logic (both the
'drop-cap' branch that appends to workspace.paragraphDiv and the else branch
that appends to workspace.root), clear workspace.chapterNumText (or set a
dedicated flag like workspace.chapterNumRendered = true and check it in
handleVerseLabel) so handleVerseLabel will not double-render the chapter number.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ddf7e5bb-d67f-48c1-83e4-5822db0f384f

📥 Commits

Reviewing files that changed from the base of the PR and between 7bd1d17 and 9ee59bc.

📒 Files selected for processing (6)
  • convert/convertBooks.ts
  • src/lib/components/BookSelector.svelte
  • src/lib/components/ChapterSelector.svelte
  • src/lib/components/ScriptureViewSofria.svelte
  • src/routes/songs/[collection]/[id]/+page.svelte
  • src/routes/songs/[collection]/[id]/+page.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/lib/components/ChapterSelector.svelte
  • convert/convertBooks.ts
  • src/routes/songs/[collection]/[id]/+page.svelte
  • src/lib/components/BookSelector.svelte

Comment thread src/lib/components/ScriptureViewSofria.svelte

@FyreByrd FyreByrd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really close. Just a few nitpicks at this point. I think we may want to wait until #986 is merged before this one is.

Comment thread src/lib/components/ChapterSelector.svelte
Comment thread src/routes/songs/[collection]/[id]/+page.ts Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.ts Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.ts Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.svelte Outdated
Comment thread src/routes/songs/[collection]/[id]/+page.svelte Outdated
@TheNonPirate TheNonPirate force-pushed the feature/songbooks/859 branch from 643a8a1 to c7c0e6a Compare June 15, 2026 22:30
@TheNonPirate

Copy link
Copy Markdown
Contributor Author

I've updated it.

@FyreByrd FyreByrd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last nitpick. You don't have to make that change, but you do still have a merge conflict. Once the conflict is resolved I'm good to approve this.

Comment thread src/routes/songs/[collection]/[id]/+page.ts
@TheNonPirate

Copy link
Copy Markdown
Contributor Author

This ended up being more complicated than I expected. I ended up going ahead and hiding the verse selector in the BookSelector component as well as in the ChapterSelector. That isn't exactly what the native app does, but it makes more sense, and the native app displayed the verse as "i" while the PWA was displaying it as a number or as no number at all, so it wasn't matching the native app anyway. I also found some problems relating to how I navigated to the song that caused the chapter number on the top of the screen to sometimes not update when moving between chapters.
It also appears that I didn't even fully resolve the conflicts, so I'll get back to work on those.

* Create new component for Songbook

* add new route for Songbooks

* create svelte page for individual songs and songbook menu

* borrow icon until icon can be selected
Going to a songbook now has the correct top bar, but the song selection feature is not yet implemented.
One is for songs sorted by title, and one is for songs
sorted by number.
Instead of inserting verse tags in conversion,
which can cause problems for certain settings,
insert chapter numbers in songs in
ScriptureViewSofria.
Removed redundant truthy check, simplified
src/routes/songs/[collection]/[id]/+page.ts data export,
and removed some unneccessary derived variables
Cause verse selector to be hidden in the BookSelector component for
songbooks. Fix some problems related to navigation in songbooks not
updating chapter number properly
@TheNonPirate TheNonPirate force-pushed the feature/songbooks/859 branch from 4d102e4 to a727675 Compare June 16, 2026 17:14
@TheNonPirate

Copy link
Copy Markdown
Contributor Author

It should be good now, but enough did change that it's probably worth another review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Song Books

3 participants