Files
readest/apps/readest-app/.claude/memory/rsvp-rtl-word-display-4630.md
T
Huang Xin 451f0ccd90 fix(library): count only uploaded, non-deleted books in synced toast (#4654)
* fix(library): count only uploaded, non-deleted books in synced toast

The "N book(s) synced" toast shown on pull-to-refresh and the
last-synced menu counted every non-deleted book record a pull
returned, including books indexed in the cloud as metadata only
whose file blob was never uploaded. Those books are never added to
the library (updateLibrary requires uploadedAt && !deletedAt), so
the toast over-reported.

Extract the count into a pure countSyncedRecords(type, records)
helper that excludes deleted records and, for books only, requires
uploaded_at — matching what actually lands in the library.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(memory): record agent notes for recent fixes

Persisted project-memory docs accumulated alongside recently merged
work (biometric app-lock, download-file scope regression, inline-block
column overflow, iOS instant-dict double popup, RSVP RTL words, web
security advisories) plus MEMORY.md/share-feature index updates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 19:53:01 +02:00

1.9 KiB
Raw Blame History

name, description, metadata
name description metadata
rsvp-rtl-word-display-4630 RSVP ORP focus-letter split breaks Arabic/RTL shaping; render RTL words whole with dir=rtl
node_type type originSessionId
memory project 0561d60a-5d21-4b58-8bc9-1295a9f768ce

#4630: In RSVP the word window showed Arabic with letters separated, LTR, wrong order (e.g. علم → ل م ع), sometimes a tofu box. Root cause = the ORP focus-letter layout in RSVPOverlay.tsx slices each word into wordBefore/orpChar/wordAfter by character index and lays them out in absolutely-positioned LTR spans. Slicing by index breaks Arabic letter shaping (letters stop connecting → isolated/notdef forms) and the before→after LTR layout reverses visual order. The context panel renders each word as ONE unsplit <span>, which is why the reporter saw it render correctly there.

Fix: detect RTL and render the word whole, reusing the existing CJK "Highlight Word" .rsvp-word-whole branch, with dir='rtl' for correct base direction.

  • New isRTLText(text) in src/services/rsvp/utils.tsRTL_PATTERN = /[֐-ࣿיִ-﷿ﹰ-]/ (Hebrew/Arabic/Syriac/Thaana/NKo/Samaritan/Mandaic + presentation forms). Mind the literal-char Edit pitfall: bidi reordering made exact-string Edit fail; wrote the regex with \u escapes via perl on the line number instead.
  • Overlay branch: isRTLWord || (isCJKWord && highlightWholeWord) → whole-word span; dir={isRTLWord ? 'rtl' : undefined}. No new toggle — RTL always renders whole (ORP anchoring is meaningless for unsplittable shaped scripts).

General lesson: any complex-shaping/bidi script can't survive per-character span splitting; the same trap applies to other features that slice words by index for highlighting. Related: rsvp-font-settings-4519. jsdom tests assert DOM structure (whole span + dir) only; glyph shaping is a real-browser concern but is guaranteed correct because the sibling context span already shapes correctly.