Files
readest/apps/readest-app/.claude/memory/MEMORY.md
T
Huang Xin c23c21d37d fix(kosync): reflowable conflict comparison via local CFI; scrolled-mode + library fixes (#4367)
* feat(kosync): compare reflowable conflicts via locally-resolved CFI percentage

KOReader reports progress as a percentage from its own pagination, which isn't directly comparable to Readest's progress. For reflowable books, resolve the remote XPointer to a local CFI and compute the equivalent fraction (getRemoteLocalFraction), comparing that against the local percentage and falling back to the reported percentage only when it can't be resolved locally (non-XPointer progress or a missing section). The resolved fraction also drives the conflict-dialog remote preview so the shown value matches what was compared.

Loosen the conflict threshold to 0.01 when the remote progress was last pushed from this same device (remote.device_id === local deviceId), so sub-page drift between a push and the next pull doesn't prompt. Render sync percentages with 2 decimals via formatProgressPercentage.

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

* fix(reader): correct scrolled-mode reopen drift over background-image sections

Bump the foliate-js submodule to include the scrolled-mode reopen drift fix for sections with background images, and add a browser regression test plus its EPUB fixture.

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

* fix(library): redirect to login on pull-to-refresh when signed out

Guard the pull-to-refresh handlers so an unauthenticated user is sent to the login screen instead of attempting a library pull and OPDS subscription check.

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

* docs(memory): add kosync conflict + toc/scrolled-restore notes

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

* fix(reader): prevent CFI crash on inert-only section bodies

Reopening/​paginating across a background-image or otherwise content-less section could crash with "Cannot destructure property 'nodeType' of 'param' as it is undefined" in foliate's fromRange, aborting the relocate so the reading position was never saved. Bumps the foliate-js submodule to 569cc06 (visible-range walker skips cfi-inert skip-links; isTextNode/isElementNode are null-safe) and adds a regression test reproducing the exact crash.

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

* fix(kosync): keep auto-push working when a pull finds no real conflict

In the 'prompt' strategy, pullProgress set syncState to 'conflict' unconditionally on every pull that returned remote progress, even when promptedSync found no actual difference. Since auto-push only runs while 'synced', and a pull fires on every book-open and window re-activation, progress stopped being pushed. promptedSync now returns whether a real conflict was surfaced, and pullProgress only stays in 'conflict' for genuine conflicts (otherwise 'synced').

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

* fix(settings): show most recent sync time and reorder settings tabs

Library settings menu now reports the latest of the book/config/note sync timestamps as "Synced …" instead of only the books timestamp. Reorder the settings tabs so Integrations precedes TTS.

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-05-30 18:07:29 +02:00

5.7 KiB

Readest Project Memory

Key Reference Documents

Paginator Scroll Knowledge

  • Issue #4112 scroll-anchoring — RESOLVED (PR #4349). Scroll-anchoring suppressed at scrollTop 0 when prepending a section in scrolled mode; fix patterns (prepend compensation, eager backward preload, no-blank nav) + test & dev-server gotchas
  • Reading ruler line/column-aware — ruler snaps to real lines; multi-column band spans one column; Range.getClientRects() returns tall block boxes that must be dropped; iframe frame-offset mapping; synthetic-key throttling
  • TOC expand + auto-scroll — #4059 collapse-by-default policy in tocTree.ts; pinned-sidebar mounts before progress → dynamic expansion breaks scroll-to-current via (1) spurious onScroll clearing pending and (2) Virtuoso scrollToIndex landing short after row growth (re-assert on rAF)

Critical Files (Most Bug-Prone)

  • src/utils/style.ts - Central EPUB CSS transformation hub (14+ bug fixes)
  • packages/foliate-js/paginator.js - Page layout, image sizing, backgrounds
  • src/services/tts/TTSController.ts - TTS state machine, section tracking
  • src/hooks/useSafeAreaInsets.ts - Safe area inset management
  • src/app/reader/components/FoliateViewer.tsx - Reader view orchestration
  • src/app/reader/components/annotator/Annotator.tsx - Annotation lifecycle

Sync Notes

  • KOSync CFI spine resolution — convert via the CFI's own spine (getXPointerFromCFI/getCFIFromXPointer), never new XCFI(primaryDoc, primaryIndex); primaryIndex lags during scroll → spine-mismatch throw

Feature Notes

  • Manage Cache + iOS container layout'Cache' base = Library/Caches/<bundle> only (not all of Caches); iOS Documents/Inbox cleared too; WebKit cache + tmp out of reach; never touch App Support
  • D-pad Navigation — Android TV remote / keyboard arrow navigation design, key files, and pitfalls
  • Cloudflare Workers WebSocket — use fetch() Upgrade pattern (not ws npm); CF delivers binary frames as Blob (must serialize async decodes)
  • Share-a-Book Feature (in progress) — locked decisions for the /s/{token} share-link feature; plan at ~/.claude/plans/ok-we-will-learn-cosmic-acorn.md
  • readest.koplugin i18n — gettext loader at apps/readest.koplugin/i18n.lua, .po catalog at locales/<i18next-code>/translation.po, extract/apply scripts in scripts/

Patterns

  • Virtuoso + OverlayScrollbars — useOverlayScrollbars hook integration for overlay scrollbars on mobile webviews
  • Design system → DESIGN.md — codify recurring UI/UX rules in apps/readest-app/DESIGN.md; never pl/pr/ml/mr/text-left/text-right (RTL); §5 boxed list anatomy has uniform min-h-14 rows and chromeless controls

Architecture Notes

  • foliate-js is a git submodule at packages/foliate-js/
  • Multiview paginator: loads adjacent sections in background, multiple View/Overlayer instances per book
  • Style overrides: getLayoutStyles() (always), getColorStyles() (when overriding color)
  • transformStylesheet() does regex-based EPUB CSS rewriting at load time
  • TTS uses independent section tracking (#ttsSectionIndex) decoupled from view
  • Safe area insets flow: Native plugin -> useSafeAreaInsets hook -> component styles
  • Dropdown menus use DropdownContext (not blur-based) for screen reader compat
  • Foliate touch-listener capture phase — to suppress reader gestures from the app, use {capture:true}; the paginator registers bubble-phase doc listeners first (during view.open())

Workflow