Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[Android] Try to disambiguate taps from swipes (#7448)

authored by

dan and committed by
GitHub
96054f4a 479a4a92

+40 -2
+40 -2
src/view/com/pager/Pager.tsx
··· 1 - import React, {forwardRef, useCallback, useContext} from 'react' 1 + import React, {Children, forwardRef, useCallback, useContext} from 'react' 2 2 import {View} from 'react-native' 3 3 import {DrawerGestureContext} from 'react-native-drawer-layout' 4 4 import {Gesture, GestureDetector} from 'react-native-gesture-handler' ··· 17 17 } from 'react-native-reanimated' 18 18 import {useFocusEffect} from '@react-navigation/native' 19 19 20 + import {isAndroid} from '#/platform/detection' 20 21 import {useSetDrawerSwipeDisabled} from '#/state/shell' 21 22 import {atoms as a, native} from '#/alf' 22 23 ··· 148 149 style={[a.flex_1]} 149 150 initialPage={initialPage} 150 151 onPageScroll={handlePageScroll}> 151 - {children} 152 + {isAndroid 153 + ? Children.map(children, child => ( 154 + <CaptureSwipesAndroid>{child}</CaptureSwipesAndroid> 155 + )) 156 + : children} 152 157 </AnimatedPagerView> 153 158 </GestureDetector> 154 159 </View> 155 160 ) 156 161 }, 157 162 ) 163 + 164 + // HACK. 165 + // This works around https://github.com/callstack/react-native-pager-view/issues/960. 166 + // It appears that the Pressables inside the pager get confused if there's enough work 167 + // happening on the JS thread, and mistakingly interpret a pager swipe as a tap. 168 + // We can prevent this by stealing all horizontal movements from the tree inside. 169 + function CaptureSwipesAndroid({children}: {children: React.ReactNode}) { 170 + const lastTouchStart = React.useRef<{x: number; y: number} | null>(null) 171 + return ( 172 + <View 173 + onTouchStart={e => { 174 + lastTouchStart.current = { 175 + x: e.nativeEvent.pageX, 176 + y: e.nativeEvent.pageY, 177 + } 178 + }} 179 + onMoveShouldSetResponderCapture={e => { 180 + const coords = lastTouchStart.current 181 + if (!coords) { 182 + return false 183 + } 184 + const dx = Math.abs(e.nativeEvent.pageX - coords.x) 185 + if (dx > 0) { 186 + // This is a horizontal movement and will result in a swipe. 187 + // Prevent pager children from receiving this touch. 188 + return true 189 + } 190 + return false 191 + }}> 192 + {children} 193 + </View> 194 + ) 195 + } 158 196 159 197 function usePagerHandlers( 160 198 handlers: {