Skip to content

fix(mobile): tame selection handle page advance#455

Open
codedogQBY wants to merge 11 commits into
mainfrom
codex/fix-android-selection-handle-drift
Open

fix(mobile): tame selection handle page advance#455
codedogQBY wants to merge 11 commits into
mainfrom
codex/fix-android-selection-handle-drift

Conversation

@codedogQBY

@codedogQBY codedogQBY commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Let Foliate's built-in paginated selection handler drive cross-page selection on mobile instead of running a second ReadAny page-advance monitor.
  • Stop locking Foliate navigation merely because RN has an active text selection; that lock also disables Foliate's official selection auto-page path.
  • Make Foliate's pointer-selection auto-page work better on Android handles by:
    • using the selection document to detect selection direction across iframe content;
    • throttling active drag checks instead of waiting for a trailing debounce;
    • triggering a page turn when the active selection edge reaches the visible page edge, even if Android clamps the Range at the current page boundary;
    • requiring a stable 1s dwell at the page edge before that edge fallback turns the page;
    • resetting that dwell whenever the selection Range changes or any available touch/pointer point keeps moving;
    • allowing selectionchange itself to drive paging on touch devices, because Android native selection handles do not always expose reliable pointer button/edge coordinates to the iframe;
    • using touch/pointer coordinates only as movement reset signals, not as hard requirements for paging;
    • canceling the pending edge turn on pointer/touch release;
    • narrowing the edge activation zone and removing the vertical top/bottom fallback to reduce accidental turns;
    • guarding against overlapping page turns.
  • Keep ReadAny selection reporting/tap suppression, and rebuild the Expo reader bundle.

Root Cause

Foliate already supports cross-page selection in foliate-paginator: while pointer-selecting, selectionchange compares the current selection with the last visible range and calls next()/prev() when the selection crosses the page boundary.

ReadAny was blocking or weakening that path in several ways:

  • RN called window.setNavigationLocked(true) whenever selection was active, but Foliate's selection paging exits early when navigationLocked is true.
  • The reader injected its own cross-page selection monitor, locking paginator container scrolling and competing with Foliate's native selection relocation behavior.
  • Android selection handles can clamp the Range at the visible page edge instead of extending it past lastVisibleRange, so Foliate's original strict range-boundary comparison never fired.
  • The original direction check used the outer document to create a Range for iframe content, which can fail in WebView.
  • Requiring the touch/pointer point itself to be at the page edge was too strict on Android WebView; the native selection handle can update the selection without exposing matching pointer coordinates.

Validation

  • pnpm --filter @readany/app-expo run build:reader
  • pnpm --filter @readany/app-expo exec tsc --noEmit
  • git diff --check

Fixes #287

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.

[Bug] 选中文字 bug

1 participant