Skip to content

Improve types for annotations and scripture view#998

Open
FyreByrd wants to merge 3 commits into
mainfrom
refactor/improve-types
Open

Improve types for annotations and scripture view#998
FyreByrd wants to merge 3 commits into
mainfrom
refactor/improve-types

Conversation

@FyreByrd

@FyreByrd FyreByrd commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

I recommend rebase and merge, since these commits are not super closely related.

Summary by CodeRabbit

  • Improvements
    • Enhanced scripture view reliability with improved type safety, safer DOM handling, and more consistent in-text navigation
    • More robust verse selection behavior through tighter store-driven syncing and safer click handling
    • Improved image cropping stability with additional guards and safer null handling during interactions
    • Stronger sorting consistency across bookmarks, highlights, and notes via a unified sort type
    • Better plan state management for resets and milestone/state updates

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@FyreByrd, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 50 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 32116292-160b-49e8-89d3-313694454135

📥 Commits

Reviewing files that changed from the base of the PR and between 6341d78 and 09e91f3.

📒 Files selected for processing (8)
  • src/lib/components/ScriptureViewSofria.svelte
  • src/lib/data/stores/plan.ts
  • src/lib/data/stores/scripture.ts
  • src/lib/scripts/stringUtils.ts
  • src/lib/scripts/verseSelectUtil.ts
  • src/lib/video/index.ts
  • src/routes/image/upload/+page.svelte
  • src/routes/text/+page.svelte
📝 Walkthrough

Walkthrough

This PR replaces untyped sort constants with a typed Sort enum and updates all consumers; converts isDefined to a generic type guard; refactors verseSelectUtil functions to read from the selectedVerses store directly; strengthens types in plan.ts, scripture.ts, and video/index.ts; and extensively refactors ScriptureViewSofria.svelte with local TypeScript model types, store-driven prop removal, and typed Sofria action callbacks. The image upload page gains defensive null guards.

Changes

TypeScript Typing Improvements and Component Refactor

Layer / File(s) Summary
Annotation sort enum and consumer route pages
src/lib/data/annotation-sort.ts, src/routes/bookmarks/+page.svelte, src/routes/highlights/+page.svelte, src/routes/notes/+page.svelte
Removes SORT_DATE/SORT_REFERENCE/SORT_COLOR constants and introduces a typed Sort object/union; makes toSorted generic over T extends Annotation and routes dispatch to compareReference, compareDate, or compareColor based on sortType; all three annotation pages switch import and sort state initialization to Sort.Date/Sort.Reference/Sort.Color enum values.
Supporting utility and store type improvements
src/lib/scripts/stringUtils.ts, src/lib/scripts/verseSelectUtil.ts, src/lib/data/stores/plan.ts, src/lib/data/stores/scripture.ts, src/lib/video/index.ts
isDefined becomes a generic type guard narrowing `T
ScriptureViewSofria: Props interface, local model types, and store rewiring
src/lib/components/ScriptureViewSofria.svelte, src/routes/text/+page.svelte
Props removes 10 any-typed fields (bodyFontSize, bodyLineHeight, bookmarks, notes, highlights, references, glossary, selectedVerses, themeColors, verseLayout), replacing them with store subscriptions; maxSelections is narrowed to number; local model types Block/Element/Sequence/Context/Workspace/Action are introduced; query() signature accepts typed videos/illustrations; text page passes as number cast for maxSelections.
ScriptureViewSofria: rendering, text, and footnote helpers
src/lib/components/ScriptureViewSofria.svelte
Phrase termination helpers strengthen typing; startPhrase uses introductionIndex with + prefix; getFootnoteCallerCharacter uses $refs-scoped typed lookups; helpers appendTextToElement, addGraftText, fixText, addText, usfmSpan, addTextNode, processText, appendPhrase, addVerseNumber are introduced/typed with workspace parameters; phrase div cloning transfers first text child into wrapper span before replacement; figure/illustration helpers (addFigureDiv, figureSource, createIllustrationCaptionBlock, showFullscreenPopup) gain typed signatures; milestone list numbering resets counters via delete rather than assigning undefined.
ScriptureViewSofria: click handling, navigation, and DOM augmentation
src/lib/components/ScriptureViewSofria.svelte
Click routing is refactored to dispatch based on element classes with typed handlers; navigate() resets footnotes; annotation divs (addNotesDiv, addBookmarksDiv, addHighlightedVerses) use typed store access; planDivInChapter compares $plan against $refs to determine visibility; bookmark/data element finders use typed helpers and parseInt; video/illustration injection guards container! and parses placement refs; prepareJmpLink/addJmpLink are typed; onClick dispatches via clickableClasses as const and onClickText is gated by $audioPlayer.playing.
ScriptureViewSofria: Sofria action callback typings and end-of-document pipeline
src/lib/components/ScriptureViewSofria.svelte
All Sofria render action callbacks destructure typed Action; paragraph/heading subType uses optional chaining; endDocument conditionally gates verse annotation augmentation behind !displayingIntroduction; observer setup checks $refs; blockGraft constructs typed graftRecord: Block; inlineGraft uses typed Element; chapter/verse label feature checks use $refs.collection/$refs.book; all action wiring uses consistent typed destructuring.
Image upload null safety
src/routes/image/upload/+page.svelte
image state becomes HTMLImageElement | undefined; onMount cleanup and initCropBox guard on image presence; touch/drag/resize handlers return early when image is absent; getCroppedImage returns null when image is missing, passed through to store updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • sillsdev/appbuilder-pwa#835: Prior Svelte 5 modernization work in ScriptureViewSofria.svelte that this PR builds on with further TypeScript improvements and prop refactoring.
  • sillsdev/appbuilder-pwa#873: Addresses the same selectedVerses store/updateSelections synchronization path that this PR refactors to remove the external selections argument.
  • sillsdev/appbuilder-pwa#889: Modifies the same sortOrder handling in the bookmarks, highlights, and notes pages that this PR migrates to the typed Sort enum.

Suggested reviewers

  • chrisvire

Poem

🐇 Hopping through the types so wide,
No more any left to hide!
Sort.Date, Sort.Reference—neat and clean,
The strictest types this warren's seen.
Store-driven props, null guards in place,
A typed and tidy codebase space! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.05% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Improve types for annotations and scripture view' accurately summarizes the main changes, which focus on enhancing TypeScript type safety across annotation sorting, scripture view components, and related utilities.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/improve-types

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


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.

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
src/lib/data/annotation-sort.ts (1)

50-60: ⚠️ Potential issue | 🟠 Major

Type safety gap: toSorted signature permits invalid Sort.Color usage with non-Highlight arrays.

The generic signature toSorted<T extends Annotation> allows callers to pass BookmarkItem[] or NoteItem[] with sortType === Sort.Color, but compareColor (line 38) requires HighlightItem with a penColor property. The ts-expect-error suppresses the compile error at the call site but doesn't prevent runtime failures if a developer mistakenly calls toSorted(bookmarks, Sort.Color).

In practice, only the highlights page uses Sort.Color (bookmarks and notes pages never set this sort order), but the type system doesn't enforce the constraint.

🔧 Proposed fix using function overloads

Replace the current generic signature with overloads that constrain valid combinations:

-export function toSorted<T extends Annotation>(items: T[], sortType: Sort) {
+export function toSorted(items: HighlightItem[], sortType: typeof Sort.Color): HighlightItem[];
+export function toSorted<T extends Annotation>(items: T[], sortType: Exclude<Sort, typeof Sort.Color>): T[];
+export function toSorted<T extends Annotation>(items: T[], sortType: Sort): T[] {
     if (sortType === Sort.Reference) {
         return items.toSorted(compareReference);
     } else if (sortType === Sort.Date) {
         return items.toSorted(compareDate);
     } else if (sortType === Sort.Color) {
-        //@ts-expect-error I don't know how to specify that this only be for Highlights - Aidan
-        return items.toSorted(compareColor);
+        return (items as HighlightItem[]).toSorted(compareColor);
     }
     return items;
 }

This enforces at compile time that Sort.Color can only be used with HighlightItem[], while preserving type refinement for the other branches.

🤖 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/data/annotation-sort.ts` around lines 50 - 60, The toSorted function
has a generic signature that allows any Annotation type with any Sort type, but
compareColor only works with HighlightItem because it requires the penColor
property. The `@ts-expect-error` suppresses the compile error but doesn't prevent
runtime failures if Sort.Color is used with BookmarkItem or NoteItem. Replace
the current single generic signature with function overloads that enforce
compile-time constraints: create specific overload signatures that restrict
Sort.Color to only HighlightItem arrays, while allowing Sort.Reference and
Sort.Date for any Annotation type. Remove the `@ts-expect-error` comment once the
overloads prevent invalid combinations from compiling.
🧹 Nitpick comments (2)
src/lib/data/annotation-sort.ts (2)

14-28: 💤 Low value

Optional: compareReference returns -1 for equal items instead of 0.

When two annotations share the same bookIndex, chapter, and verse, the comparator returns -1 (line 26) instead of 0. This violates the comparator contract and can cause unstable sorting behavior. A proper tie-breaker (e.g., secondary sort by date) or returning 0 would make the sort stable and predictable.

♻️ Proposed fix
     } else if (parseInt(a.verse) > parseInt(b.verse)) {
         return 1;
+    } else if (parseInt(a.verse) < parseInt(b.verse)) {
+        return -1;
     } else {
-        return -1;
+        return 0;  // Equal references
     }

Or add a tie-breaker:

     } else if (parseInt(a.verse) > parseInt(b.verse)) {
         return 1;
+    } else if (parseInt(a.verse) < parseInt(b.verse)) {
+        return -1;
     } else {
-        return -1;
+        // Tie-breaker: sort by date descending
+        return a.date < b.date ? 1 : a.date > b.date ? -1 : 0;
     }
🤖 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/data/annotation-sort.ts` around lines 14 - 28, The `compareReference`
function violates the comparator contract by returning `-1` when two annotations
have equal `bookIndex`, `chapter`, and `verse` values. The final else clause
should return `0` for equal items instead of always returning `-1`. Either
replace the final else block to return `0` when all primary sorting criteria are
equal, or add a tie-breaker comparison (such as comparing by a date property) to
ensure stable and predictable sort behavior when annotations share the same
reference point.

30-36: 💤 Low value

Optional: compareDate returns -1 for equal dates instead of 0.

When a.date === b.date, the comparator returns -1 (line 34) instead of 0, violating the comparator contract and causing unstable sort order for annotations created at the same timestamp.

♻️ Proposed fix
 export function compareDate(a: Annotation, b: Annotation) {
     if (a.date < b.date) {
         return 1;
+    } else if (a.date > b.date) {
+        return -1;
     } else {
-        return -1;
+        return 0;  // Equal dates
     }
 }
🤖 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/data/annotation-sort.ts` around lines 30 - 36, The compareDate
function in annotation-sort.ts does not properly handle the case when a.date ===
b.date, as it returns -1 instead of 0. Restructure the function to explicitly
check all three comparison cases: if a.date < b.date return 1, else if a.date >
b.date return -1, and else (when they are equal) return 0. This ensures the
comparator follows the standard contract required for stable sorting.
🤖 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 2552-2557: The loop in the ScriptureViewSofria.svelte file is
meant to clear lower-level list counters by iterating through increasing index
values with i++, but the delete statement inside the loop uses matchNum instead
of the loop variable i. This causes the same level counter to be deleted
repeatedly instead of clearing each subsequent level. Replace the matchNum
reference in the delete workspace statement with i so that each iteration
properly removes the next deeper level's list counter
(workspace[`level${i}ListNum`]).

In `@src/lib/data/stores/plan.ts`:
- Around line 60-62: The currentPlanState store is only updated when result is
truthy, which means if result is falsy (indicating no persisted state), the
previous plan state remains cached in the store. This stale state (such as
"completed" status) can affect downstream plan navigation decisions. Fix this by
adding an else clause to reset currentPlanState to an appropriate default or
empty value when result is falsy, ensuring that switching to a plan with no
saved state properly clears any previously cached state.

---

Outside diff comments:
In `@src/lib/data/annotation-sort.ts`:
- Around line 50-60: The toSorted function has a generic signature that allows
any Annotation type with any Sort type, but compareColor only works with
HighlightItem because it requires the penColor property. The `@ts-expect-error`
suppresses the compile error but doesn't prevent runtime failures if Sort.Color
is used with BookmarkItem or NoteItem. Replace the current single generic
signature with function overloads that enforce compile-time constraints: create
specific overload signatures that restrict Sort.Color to only HighlightItem
arrays, while allowing Sort.Reference and Sort.Date for any Annotation type.
Remove the `@ts-expect-error` comment once the overloads prevent invalid
combinations from compiling.

---

Nitpick comments:
In `@src/lib/data/annotation-sort.ts`:
- Around line 14-28: The `compareReference` function violates the comparator
contract by returning `-1` when two annotations have equal `bookIndex`,
`chapter`, and `verse` values. The final else clause should return `0` for equal
items instead of always returning `-1`. Either replace the final else block to
return `0` when all primary sorting criteria are equal, or add a tie-breaker
comparison (such as comparing by a date property) to ensure stable and
predictable sort behavior when annotations share the same reference point.
- Around line 30-36: The compareDate function in annotation-sort.ts does not
properly handle the case when a.date === b.date, as it returns -1 instead of 0.
Restructure the function to explicitly check all three comparison cases: if
a.date < b.date return 1, else if a.date > b.date return -1, and else (when they
are equal) return 0. This ensures the comparator follows the standard contract
required for stable sorting.
🪄 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: 571f7433-ff8b-4107-a8d0-7109ecc2254b

📥 Commits

Reviewing files that changed from the base of the PR and between 8ed25eb and 907425d.

📒 Files selected for processing (12)
  • src/lib/components/ScriptureViewSofria.svelte
  • src/lib/data/annotation-sort.ts
  • src/lib/data/stores/plan.ts
  • src/lib/data/stores/scripture.ts
  • src/lib/scripts/stringUtils.ts
  • src/lib/scripts/verseSelectUtil.ts
  • src/lib/video/index.ts
  • src/routes/bookmarks/+page.svelte
  • src/routes/highlights/+page.svelte
  • src/routes/image/upload/+page.svelte
  • src/routes/notes/+page.svelte
  • src/routes/text/+page.svelte

Comment thread src/lib/components/ScriptureViewSofria.svelte Outdated
Comment thread src/lib/data/stores/plan.ts
@FyreByrd FyreByrd force-pushed the refactor/improve-types branch from 907425d to 6341d78 Compare June 16, 2026 14:58
@FyreByrd FyreByrd requested a review from chrisvire June 16, 2026 14:58
@FyreByrd FyreByrd force-pushed the refactor/improve-types branch from 6341d78 to 09e91f3 Compare June 16, 2026 15:09

@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)
src/lib/components/ScriptureViewSofria.svelte (1)

1792-1876: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Duplicate code in endParagraph causes main paragraph handling to run twice.

The switch statement at line 1793 handles case 'main' (lines 1794-1821), then immediately after the switch, there's an identical if (sequenceType == 'main') block (lines 1824-1850) with the exact same code. When sequenceType === 'main', both blocks execute sequentially.

This causes:

  • appendPhrase potentially called twice
  • workspace.paragraphDiv appended to root, then the now-empty div appended again
  • Duplicate/empty DOM elements in the rendered output

The if-else chain after the switch (lines 1824-1876) appears to be legacy code that should have been removed when the switch was introduced.

🐛 Proposed fix: Remove duplicate switch case
                             switch (sequenceType) {
                                 case 'main': {
-                                    if (scriptureLogs?.paragraph) {
-                                        console.log('End main paragraph');
-                                    }
-                                    if (
-                                        workspace.phraseDiv != null &&
-                                        workspace.phraseDiv.innerText !== ''
-                                    ) {
-                                        appendPhrase(workspace);
-                                        workspace.phraseDiv = null;
-                                    }
-                                    if (versePerLine) {
-                                        if (workspace.verseDiv !== null) {
-                                            workspace.paragraphDiv.appendChild(
-                                                workspace.verseDiv.cloneNode(true)
-                                            );
-                                            workspace.verseDiv = document.createElement('div');
-                                        }
-                                    }
-                                    // Build div
-                                    if (workspace.paragraphDiv.innerHTML !== '') {
-                                        workspace.root.appendChild(workspace.paragraphDiv);
-                                    }
-                                    if (workspace.videoDiv) {
-                                        workspace.root.appendChild(workspace.videoDiv);
-                                        workspace.videoDiv = null;
-                                    }
                                     break;
                                 }
                             }
                             if (sequenceType == 'main') {

Alternatively, keep the switch case and remove the if-else block for 'main'.

🤖 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/ScriptureViewSofria.svelte` around lines 1792 - 1876, The
endParagraph block contains duplicate handling for sequenceType 'main': the
switch statement's case 'main' block (lines 1794-1821) contains identical code
to the subsequent if (sequenceType == 'main') block (lines 1824-1850), causing
appendPhrase and workspace operations to execute twice. Remove the redundant if
(sequenceType == 'main') condition and its code block, but preserve the else-if
conditions for 'title', 'heading', and 'introduction' that follow it. This
leaves the switch statement as the sole handler for the 'main' case while
maintaining the if-else chain for the other sequence types.
🧹 Nitpick comments (2)
src/lib/components/ScriptureViewSofria.svelte (2)

1505-1510: 💤 Low value

Type definition for Element.atts may not match actual structure.

The atts property is typed as Record<string, string>, but usage patterns suggest values are arrays:

  • Line 2534: element.atts['start'][0] — array indexing
  • Line 584: element.atts['number'] — passed where string expected

Consider Record<string, string | string[]> or investigating the actual Proskomma schema.

🤖 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/ScriptureViewSofria.svelte` around lines 1505 - 1510, The
`atts` property in the `Element` type definition is typed as `Record<string,
string>`, but the actual code usage shows values can be arrays (accessed with
index notation like `element.atts['start'][0]`). Update the type definition of
the `atts` property to `Record<string, string | string[]>` to accurately reflect
that the values can be either strings or arrays of strings, accommodating both
usage patterns throughout the codebase.

1161-1198: 💤 Low value

Style element appended without cleanup causes duplication on remount.

The fullscreen popup styles are appended to document.head every time this component mounts, but never removed in onDestroy. Repeated navigation could accumulate duplicate style blocks.

Consider either:

  1. Moving styles to a global CSS file, or
  2. Tracking and removing the style element in onDestroy
🤖 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/ScriptureViewSofria.svelte` around lines 1161 - 1198, The
style element containing the fullscreen popup styles is appended to
document.head during component initialization but is never removed when the
component unmounts, causing duplicate style blocks to accumulate on remount.
Store a reference to the created style element so it can be properly cleaned up
in the onDestroy lifecycle hook by removing it from document.head.
Alternatively, extract these styles to a global CSS file to avoid appending
styles dynamically in the component at all.
🤖 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 `@src/lib/components/ScriptureViewSofria.svelte`:
- Around line 1792-1876: The endParagraph block contains duplicate handling for
sequenceType 'main': the switch statement's case 'main' block (lines 1794-1821)
contains identical code to the subsequent if (sequenceType == 'main') block
(lines 1824-1850), causing appendPhrase and workspace operations to execute
twice. Remove the redundant if (sequenceType == 'main') condition and its code
block, but preserve the else-if conditions for 'title', 'heading', and
'introduction' that follow it. This leaves the switch statement as the sole
handler for the 'main' case while maintaining the if-else chain for the other
sequence types.

---

Nitpick comments:
In `@src/lib/components/ScriptureViewSofria.svelte`:
- Around line 1505-1510: The `atts` property in the `Element` type definition is
typed as `Record<string, string>`, but the actual code usage shows values can be
arrays (accessed with index notation like `element.atts['start'][0]`). Update
the type definition of the `atts` property to `Record<string, string |
string[]>` to accurately reflect that the values can be either strings or arrays
of strings, accommodating both usage patterns throughout the codebase.
- Around line 1161-1198: The style element containing the fullscreen popup
styles is appended to document.head during component initialization but is never
removed when the component unmounts, causing duplicate style blocks to
accumulate on remount. Store a reference to the created style element so it can
be properly cleaned up in the onDestroy lifecycle hook by removing it from
document.head. Alternatively, extract these styles to a global CSS file to avoid
appending styles dynamically in the component at all.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 813b0620-4179-403d-897c-8b2d073252c6

📥 Commits

Reviewing files that changed from the base of the PR and between 907425d and 6341d78.

📒 Files selected for processing (2)
  • src/lib/components/ScriptureViewSofria.svelte
  • src/routes/image/upload/+page.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/image/upload/+page.svelte

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.

1 participant