about summary refs log tree commit diff
path: root/src/view/com
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-12-07 16:56:14 -0600
committerPaul Frazee <pfrazee@gmail.com>2022-12-07 16:56:14 -0600
commitf5d1a5c38d0f72bc54eedc7dd917ffa2a7baf02a (patch)
tree95616aa7f825700e381ee5ed4affe8bbbd508a26 /src/view/com
parent9ce02dff5b995d384bdc5ea43323a0d03ca754cc (diff)
downloadvoidsky-f5d1a5c38d0f72bc54eedc7dd917ffa2a7baf02a.tar.zst
Replace navigational 'back swipe' gesture with new HorzSwipe util
Diffstat (limited to 'src/view/com')
-rw-r--r--src/view/com/util/ViewSelector.tsx1
-rw-r--r--src/view/com/util/gestures/HorzSwipe.tsx46
2 files changed, 34 insertions, 13 deletions
diff --git a/src/view/com/util/ViewSelector.tsx b/src/view/com/util/ViewSelector.tsx
index f7652334f..f39254977 100644
--- a/src/view/com/util/ViewSelector.tsx
+++ b/src/view/com/util/ViewSelector.tsx
@@ -76,6 +76,7 @@ export function ViewSelector({
   const data = [HEADER_ITEM, SELECTOR_ITEM, ...items]
   return (
     <HorzSwipe
+      hasPriority
       panX={panX}
       swipeEnabled={swipeEnabled || false}
       canSwipeLeft={selectedIndex > 0}
diff --git a/src/view/com/util/gestures/HorzSwipe.tsx b/src/view/com/util/gestures/HorzSwipe.tsx
index 7ae1ee759..0176bd4c8 100644
--- a/src/view/com/util/gestures/HorzSwipe.tsx
+++ b/src/view/com/util/gestures/HorzSwipe.tsx
@@ -12,9 +12,12 @@ import {clamp} from 'lodash'
 
 interface Props {
   panX: Animated.Value
-  canSwipeLeft: boolean
-  canSwipeRight: boolean
-  swipeEnabled: boolean
+  canSwipeLeft?: boolean
+  canSwipeRight?: boolean
+  swipeEnabled?: boolean
+  hasPriority?: boolean // if has priority, will not release control of the gesture to another gesture
+  distThresholdDivisor?: number
+  useNativeDriver?: boolean
   onSwipeStart?: () => void
   onSwipeEnd?: (dx: number) => void
   children: React.ReactNode
@@ -22,9 +25,12 @@ interface Props {
 
 export function HorzSwipe({
   panX,
-  canSwipeLeft,
-  canSwipeRight,
+  canSwipeLeft = false,
+  canSwipeRight = false,
   swipeEnabled = true,
+  hasPriority = false,
+  distThresholdDivisor = 1.75,
+  useNativeDriver = false,
   onSwipeStart,
   onSwipeEnd,
   children,
@@ -32,7 +38,7 @@ export function HorzSwipe({
   const winDim = useWindowDimensions()
 
   const swipeVelocityThreshold = 35
-  const swipeDistanceThreshold = winDim.width / 1.75
+  const swipeDistanceThreshold = winDim.width / distThresholdDivisor
 
   const isMovingHorizontally = (
     _: GestureResponderEvent,
@@ -53,10 +59,10 @@ export function HorzSwipe({
     }
 
     const diffX = I18nManager.isRTL ? -gestureState.dx : gestureState.dx
-    return (
+    const willHandle =
       isMovingHorizontally(event, gestureState) &&
       ((diffX > 0 && canSwipeLeft) || (diffX < 0 && canSwipeRight))
-    )
+    return willHandle
   }
 
   const startGesture = () => {
@@ -94,28 +100,42 @@ export function HorzSwipe({
     _: GestureResponderEvent,
     gestureState: PanResponderGestureState,
   ) => {
-    panX.flattenOffset()
-    panX.setValue(0)
     if (
       Math.abs(gestureState.dx) > Math.abs(gestureState.dy) &&
       Math.abs(gestureState.vx) > Math.abs(gestureState.vy) &&
       (Math.abs(gestureState.dx) > swipeDistanceThreshold / 3 ||
         Math.abs(gestureState.vx) > swipeVelocityThreshold)
     ) {
-      onSwipeEnd?.(((gestureState.dx / Math.abs(gestureState.dx)) * -1) | 0)
+      const final = ((gestureState.dx / Math.abs(gestureState.dx)) * -1) | 0
+      Animated.timing(panX, {
+        toValue: final,
+        duration: 100,
+        useNativeDriver,
+      }).start(() => {
+        onSwipeEnd?.(final)
+        panX.flattenOffset()
+        panX.setValue(0)
+      })
     } else {
       onSwipeEnd?.(0)
+      Animated.timing(panX, {
+        toValue: 0,
+        duration: 100,
+        useNativeDriver,
+      }).start(() => {
+        panX.flattenOffset()
+        panX.setValue(0)
+      })
     }
   }
 
   const panResponder = PanResponder.create({
     onMoveShouldSetPanResponder: canMoveScreen,
-    onMoveShouldSetPanResponderCapture: canMoveScreen,
     onPanResponderGrant: startGesture,
     onPanResponderMove: respondToGesture,
     onPanResponderTerminate: finishGesture,
     onPanResponderRelease: finishGesture,
-    onPanResponderTerminationRequest: () => true,
+    onPanResponderTerminationRequest: () => !hasPriority,
   })
 
   return (