Skip to content

#968 Warn Safari users that annotations may be deleted when app is not installed to home screen#999

Open
cdelgado10 wants to merge 4 commits into
sillsdev:mainfrom
cdelgado10:safari-annotation-warning
Open

#968 Warn Safari users that annotations may be deleted when app is not installed to home screen#999
cdelgado10 wants to merge 4 commits into
sillsdev:mainfrom
cdelgado10:safari-annotation-warning

Conversation

@cdelgado10

@cdelgado10 cdelgado10 commented Jun 16, 2026

Copy link
Copy Markdown

Summary

  • Detects when the user is on Safari without the app added to the home screen
  • shows a dismissible warning banner on the bookmarks, highlights and notes page
  • Dismissal is remembered in localStorage for 30 days to avoid being annoying

Test Plan

  • if on Safari (IPhone/IPad) app is not added to home screen then banner appears on bookmarks/highlights/notes
  • if Safari added to home screen then no banner
  • when on Chrome/Firefox there will be no banner
  • clicking 'X' will dissmiss the banner and will not re-appear if refreshed
  • banner will re-appear after 30 days

closes #968

Summary by CodeRabbit

  • New Features
    • A dismissible warning banner now appears on bookmarks, highlights, and notes pages. The dismissed state persists for 30 days, preventing the banner from reappearing during that period.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

More reviews will be available in 48 minutes and 21 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: a14531e4-3d19-4ef1-954c-2e959bfb7725

📥 Commits

Reviewing files that changed from the base of the PR and between df8689d and 8193404.

📒 Files selected for processing (5)
  • src/lib/components/SafariAnnotationWarning.svelte
  • src/lib/scripts/safariUtils.ts
  • src/routes/bookmarks/+page.svelte
  • src/routes/highlights/+page.svelte
  • src/routes/notes/+page.svelte
📝 Walkthrough

Walkthrough

A new safariUtils.ts module detects non-standalone Safari browsers and controls a 30-day dismissible warning via localStorage. A new SafariAnnotationWarning.svelte component uses those utilities to render an amber banner. The component is then integrated into the bookmarks, highlights, and notes pages.

Changes

Safari Annotation Warning Feature

Layer / File(s) Summary
Safari detection utility and warning banner component
src/lib/scripts/safariUtils.ts, src/lib/components/SafariAnnotationWarning.svelte
safariUtils.ts exports shouldShowSafariWarning() (SSR guard, ?debug_safari=true URL hash override, 30-day localStorage expiry) and dismissSafariWarning() (writes current timestamp). SafariAnnotationWarning.svelte initializes visible from shouldShowSafariWarning(), wires the dismiss button to dismissSafariWarning() + visible = false, and conditionally renders the amber banner.
Page integration
src/routes/bookmarks/+page.svelte, src/routes/highlights/+page.svelte, src/routes/notes/+page.svelte
Imports and renders <SafariAnnotationWarning /> in each annotation page container area without modifying existing list, sorting, or action logic.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AnnotationPage as Annotation Page (bookmarks/highlights/notes)
  participant SafariAnnotationWarning
  participant safariUtils
  participant localStorage

  User->>AnnotationPage: navigate to page
  AnnotationPage->>SafariAnnotationWarning: mount component
  SafariAnnotationWarning->>safariUtils: shouldShowSafariWarning()
  safariUtils->>localStorage: read dismissal timestamp
  localStorage-->>safariUtils: timestamp or null
  safariUtils-->>SafariAnnotationWarning: true (Safari, not standalone, not dismissed)
  SafariAnnotationWarning-->>AnnotationPage: render amber warning banner
  User->>SafariAnnotationWarning: click dismiss
  SafariAnnotationWarning->>safariUtils: dismissSafariWarning()
  safariUtils->>localStorage: write current timestamp
  SafariAnnotationWarning-->>AnnotationPage: set visible = false, hide banner
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • chrisvire

Poem

🐇 Hop hop, a warning appears,
For Safari folk who haven't pinned their gears —
A banner in amber, polite and brief,
One tap to dismiss brings sweet relief.
Thirty days of quiet, then back it comes,
Protecting your notes, bookmarks, and plums! 🍏

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a warning for Safari users about potential annotation deletion.
Linked Issues check ✅ Passed The implementation fully addresses issue #968 by detecting Safari non-installed status, displaying dismissible warnings on annotation pages, and using localStorage to prevent notification fatigue.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the Safari warning feature; no unrelated modifications are present.

✏️ 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.

@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

🧹 Nitpick comments (1)
src/lib/components/SafariAnnotationWarning.svelte (1)

28-32: ⚡ Quick win

Localize banner text instead of hardcoding English copy.

These lines bypass the existing translation pattern ($t) used across annotation pages, so localized users will still see English here. Please move this copy to translation keys.

🤖 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/SafariAnnotationWarning.svelte` around lines 28 - 32, The
SafariAnnotationWarning.svelte component contains hardcoded English text in the
two paragraph elements instead of using the translation function pattern (`$t`)
that is used throughout the rest of the annotation pages. Replace the hardcoded
strings "Annotations may be deleted by Safari" and the inactivity warning
message with corresponding translation keys using the `$t` function. Move these
text strings to the appropriate translation files and reference them via
`$t('key_name')` in both `<p>` tags to ensure localized users see translated
content instead of English.
🤖 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/scripts/safariUtils.ts`:
- Around line 15-16: The debug safari check is currently parsing
window.location.hash instead of the actual query string, which prevents the
debug_safari=true parameter from being recognized in normal URL query
parameters. Replace window.location.hash with window.location.search on line 15
to properly check the URL query parameters, allowing the debug override to work
correctly with query strings like ?debug_safari=true instead of requiring it in
the hash portion of the URL.
- Around line 18-24: The code needs to handle storage access exceptions and
invalid timestamp values gracefully. In the function that checks if the warning
should be shown (containing the localStorage.getItem call on line 18 and
parseInt on line 20), wrap the localStorage.getItem call in a try-catch block
and return true (show warning) if an exception occurs. Additionally, validate
the result of parseInt by checking if the value is NaN, and return true (show
warning) in that case to fail open instead of treating malformed timestamps as
dismissed. In the dismissSafariWarning function (line 23-24), wrap the
localStorage.setItem call in a try-catch block to prevent crashes when storage
is unavailable, and handle the exception gracefully without breaking the warning
system.

---

Nitpick comments:
In `@src/lib/components/SafariAnnotationWarning.svelte`:
- Around line 28-32: The SafariAnnotationWarning.svelte component contains
hardcoded English text in the two paragraph elements instead of using the
translation function pattern (`$t`) that is used throughout the rest of the
annotation pages. Replace the hardcoded strings "Annotations may be deleted by
Safari" and the inactivity warning message with corresponding translation keys
using the `$t` function. Move these text strings to the appropriate translation
files and reference them via `$t('key_name')` in both `<p>` tags to ensure
localized users see translated content instead of English.
🪄 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: 48762cb6-793a-4d86-9952-01b1568cf546

📥 Commits

Reviewing files that changed from the base of the PR and between b012cae and df8689d.

📒 Files selected for processing (5)
  • src/lib/components/SafariAnnotationWarning.svelte
  • src/lib/scripts/safariUtils.ts
  • src/routes/bookmarks/+page.svelte
  • src/routes/highlights/+page.svelte
  • src/routes/notes/+page.svelte

Comment thread src/lib/scripts/safariUtils.ts Outdated
Comment on lines +15 to +16
const hashQuery = window.location.hash.split('?')[1] ?? '';
if (new URLSearchParams(hashQuery).get('debug_safari') === 'true') return true;

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Debug override parsing checks the hash instead of URL query.

Line 15 parses window.location.hash even though the comment says ?debug_safari=true on the URL. That makes the override fail for normal query params and can mislead QA.

💡 Proposed fix
-    const hashQuery = window.location.hash.split('?')[1] ?? '';
-    if (new URLSearchParams(hashQuery).get('debug_safari') === 'true') return true;
+    const searchQuery = window.location.search;
+    const hashQuery = window.location.hash.split('?')[1] ?? '';
+    const params = new URLSearchParams(searchQuery || hashQuery);
+    if (params.get('debug_safari') === 'true') return true;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const hashQuery = window.location.hash.split('?')[1] ?? '';
if (new URLSearchParams(hashQuery).get('debug_safari') === 'true') return true;
const searchQuery = window.location.search;
const hashQuery = window.location.hash.split('?')[1] ?? '';
const params = new URLSearchParams(searchQuery || hashQuery);
if (params.get('debug_safari') === 'true') return true;
🤖 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/scripts/safariUtils.ts` around lines 15 - 16, The debug safari check
is currently parsing window.location.hash instead of the actual query string,
which prevents the debug_safari=true parameter from being recognized in normal
URL query parameters. Replace window.location.hash with window.location.search
on line 15 to properly check the URL query parameters, allowing the debug
override to work correctly with query strings like ?debug_safari=true instead of
requiring it in the hash portion of the URL.

Comment thread src/lib/scripts/safariUtils.ts Outdated
@chrisvire

Copy link
Copy Markdown
Member

This should not be limited to Safari. Other browsers use the Safari browser component on iOS.

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.

Safari: Warn on Annotation use

3 participants