about summary refs log tree commit diff
path: root/src/view/com/pager/Pager.tsx
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2025-01-20 01:03:42 +0000
committerGitHub <noreply@github.com>2025-01-20 01:03:42 +0000
commitcb020655504dd0d39f8e91fd517f14dc4a82c307 (patch)
treeb6d4be88f59a318ae7a49c3d1ffcfd29884347f0 /src/view/com/pager/Pager.tsx
parent3e0ac0a0668b5906d7b81dbc075cfd04ba89911c (diff)
downloadvoidsky-cb020655504dd0d39f8e91fd517f14dc4a82c307.tar.zst
Revert "[Android] Fix taps triggering while swiping (#7459)" (#7498)
This reverts commit 5130d19ebdb3267f58e2b6407eb5c4f95107887c.
Diffstat (limited to 'src/view/com/pager/Pager.tsx')
-rw-r--r--src/view/com/pager/Pager.tsx42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index f62bffc53..772cb1715 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -1,4 +1,4 @@
-import React, {forwardRef, useCallback, useContext} from 'react'
+import React, {Children, forwardRef, useCallback, useContext} from 'react'
 import {View} from 'react-native'
 import {DrawerGestureContext} from 'react-native-drawer-layout'
 import {Gesture, GestureDetector} from 'react-native-gesture-handler'
@@ -17,6 +17,7 @@ import Animated, {
 } from 'react-native-reanimated'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {isAndroid} from '#/platform/detection'
 import {useSetDrawerSwipeDisabled} from '#/state/shell'
 import {atoms as a, native} from '#/alf'
 
@@ -148,7 +149,11 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
             style={[a.flex_1]}
             initialPage={initialPage}
             onPageScroll={handlePageScroll}>
-            {children}
+            {isAndroid
+              ? Children.map(children, child => (
+                  <CaptureSwipesAndroid>{child}</CaptureSwipesAndroid>
+                ))
+              : children}
           </AnimatedPagerView>
         </GestureDetector>
       </View>
@@ -156,6 +161,39 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
   },
 )
 
+// HACK.
+// This works around https://github.com/callstack/react-native-pager-view/issues/960.
+// It appears that the Pressables inside the pager get confused if there's enough work
+// happening on the JS thread, and mistakingly interpret a pager swipe as a tap.
+// We can prevent this by stealing all horizontal movements from the tree inside.
+function CaptureSwipesAndroid({children}: {children: React.ReactNode}) {
+  const lastTouchStart = React.useRef<{x: number; y: number} | null>(null)
+  return (
+    <View
+      onTouchStart={e => {
+        lastTouchStart.current = {
+          x: e.nativeEvent.pageX,
+          y: e.nativeEvent.pageY,
+        }
+      }}
+      onMoveShouldSetResponderCapture={e => {
+        const coords = lastTouchStart.current
+        if (!coords) {
+          return false
+        }
+        const dx = Math.abs(e.nativeEvent.pageX - coords.x)
+        if (dx > 0) {
+          // This is a horizontal movement and will result in a swipe.
+          // Prevent pager children from receiving this touch.
+          return true
+        }
+        return false
+      }}>
+      {children}
+    </View>
+  )
+}
+
 function usePagerHandlers(
   handlers: {
     onPageScroll: (e: PagerViewOnPageScrollEventData) => void