/** * Blocks carousel pan at first/last slide so parent scroll can take over. * e.g. on slide 0, swiping right fails the gesture instead of rubber-banding. */ import { useCallback } from 'react'; import { PanGesture } from 'react-native-gesture-handler'; import { PARALLAX_PAN_ACTIVE_OFFSET } from '../constants'; import { IUseEdgePanGestureParams } from './type'; export const useEdgePanGesture = ({ activeIndex, maxIndex, touchStartX }: IUseEdgePanGestureParams) => { return useCallback( (gestureChain: PanGesture) => { gestureChain.activeOffsetX([-PARALLAX_PAN_ACTIVE_OFFSET, PARALLAX_PAN_ACTIVE_OFFSET]); gestureChain.onTouchesDown((event) => { 'worklet'; const touch = event.allTouches[0]; if (touch) { touchStartX.value = touch.x; } }); gestureChain.onTouchesMove((event, stateManager) => { 'worklet'; const touch = event.allTouches[0]; if (!touch) { return; } const deltaX = touch.x - touchStartX.value; const index = activeIndex.value; if (index <= 0 && deltaX > 0) { stateManager.fail(); return; } if (index >= maxIndex && deltaX < 0) { stateManager.fail(); } }); }, [activeIndex, maxIndex, touchStartX], ); };