Files
readest/apps/readest-app/.claude/memory/scrolled-header-title-center-4436.md
T
Huang Xin acd4a67dcf fix(reader): require a still-hold before instant-highlight on touch (#4745)
* fix(reader): require a still-hold before instant-highlight on touch

Instant Highlight (the highlighter quick action) engaged on every
pointer-down over text, calling preventDefault, which swallowed the
single tap / swipe that turns the page on Android. Tapping the side
margins still worked only because they are not selectable text; the
synthetic-click fallback was also dead on Android (native touchend
calls handlePointerUp with no event).

Gate engagement behind a 300ms still hold for touch/pen: a tap
releases first and a swipe moves first, so both fall through to
pagination, and only a deliberate still hold starts drag-to-highlight.
Mouse input keeps engaging immediately (click vs. press-drag is
already unambiguous).

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

* chore(agent): update agent memories

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-23 11:32:41 +02:00

2.4 KiB

name, description, metadata
name description metadata
scrolled-header-title-center-4436 Scrolled-mode header chapter title lagged because getVisibleRange picked the topmost sliver view, not the viewport-center section
node_type type originSessionId
memory project 0c504495-68fe-4a26-b314-644bbc496581

#4436 — In scrolled mode the reader header chapter title was wrong vs paginated mode while transitioning between sections. Title comes from foliate tocItem = TOCProgress.getProgress(index, range); index/range come from the paginator's relocate detail, ultimately from #getVisibleRange().

Root cause: the scrolled branch of #getVisibleRange (packages/foliate-js/paginator.js) returned the FIRST overlapping view (lowest index = topmost in scroll order). When the tail of section K is a thin text-bearing sliver at the very top of the viewport but section K+1 occupies the centre/majority, it returned K's range → title showed K while the reader was reading K+1. Paginated mode never shows this because each page belongs to one section. (comparePoint end-boundary logic in progress.js is shared by both modes and was NOT the divergence — the view choice was.)

Fix: prefer the view whose visible band covers the viewport CENTRE (center = #renderedStart + size/2; center >= off && center < off+vSize); keep the first valid non-collapsed range as a fallback for when no loaded view covers the centre (very top/bottom of book). Also fixed #afterScroll scrolled fraction to size against this.#views.get(index) (the relocated view) instead of #primaryView, since the relocated index can now differ from #primaryIndex. #detectPrimaryView/#primaryIndex left UNCHANGED (drives preload/trim/bg; guarded by #4112/#3987 tests) — only the relocate index/range moved to centre.

Accepted side effect: scrolled CFI/anchor now reflect the centre section (reopen lands at centre section top) — minor, arguably better.

Test: paginator-scrolled.browser.test.ts "should report the section occupying the viewport centre…" — real paginator + sample-alice, two adjacent tall linear sections, setAttribute('no-preload','') AFTER fill to freeze view offsets (else backward-preload scroll-compensation shifts the absolute scrollTop target), nudge-scroll (first debounced scroll only clears #justAnchored; need a 2nd to fire afterScroll('scroll')), assert relocate index == centre section. See issue-4112-scroll-anchoring.