From fc2128dabeaa1b9a90d5c494a6db3a7e2f45fbe9 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 4 Sep 2026 11:35:03 -0400 Subject: [PATCH] Fix swipe eating scroll gestures on the detail page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit onSwipe judged horizontal-vs-vertical from a single touchmove sample compared against the start point. A fast scroll flick's first sample is often slightly diagonal (thumb motion), so it could get claimed as a page-swipe and every subsequent touchmove got preventDefault()'d — the rest of the scroll silently died, so trying to reach off-screen content in About/Stats/Evolution/etc. would instead flip to the next Pokémon. Now vertical intent wins by default (bails, permanently, as soon as the drag is even mildly more vertical than horizontal) and a horizontal page-swipe only gets claimed once the drag is unambiguous (dx > 20 && dx > 2*dy). Deliberate left/right swipes still work. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu --- src/lib/swipe.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib/swipe.js b/src/lib/swipe.js index dd5fa86..3037c5f 100644 --- a/src/lib/swipe.js +++ b/src/lib/swipe.js @@ -32,11 +32,19 @@ export function onSwipe(target, { onLeft, onRight, threshold = 60 } = {}) { const dx = e.touches[0].clientX - x0; const dy = e.touches[0].clientY - y0; if (!claimed) { - if (Math.abs(dy) > 12 && Math.abs(dy) > Math.abs(dx)) { - active = false; // it's a vertical scroll — let it be + const adx = Math.abs(dx); + const ady = Math.abs(dy); + // Scroll is the default: bail out — permanently — at the first sign of + // vertical intent, even a mildly diagonal one. A page full of scrolling + // content (tab panels, lists) means a fast flick's first sample is + // often diagonal; without this bias it gets misread as a page-swipe + // and the rest of the scroll gets eaten by preventDefault(). + if (ady > 10 && ady > adx * 0.7) { + active = false; return; } - if (Math.abs(dx) > 10 && Math.abs(dx) > Math.abs(dy)) claimed = true; + // Only claim a horizontal page-swipe once the drag is unambiguous. + if (adx > 20 && adx > ady * 2) claimed = true; } if (claimed) e.preventDefault(); };