From 02155325ef6e0729eb718d9c8c1be57964f68b97 Mon Sep 17 00:00:00 2001 From: Mo Gorhom Date: Sun, 12 Sep 2021 19:35:37 +0100 Subject: [PATCH] chore: updated patch and add new hook --- @react-navigation+stack+6.0.7.patch | 68 -------------- App.tsx | 4 +- patches/@react-navigation+stack+6.0.7.patch | 98 +++++++++++++++++---- src/Modal.tsx | 59 +++---------- src/useCardModalGestureInteraction.ts | 57 ++++++++++++ 5 files changed, 151 insertions(+), 135 deletions(-) delete mode 100644 @react-navigation+stack+6.0.7.patch create mode 100644 src/useCardModalGestureInteraction.ts diff --git a/@react-navigation+stack+6.0.7.patch b/@react-navigation+stack+6.0.7.patch deleted file mode 100644 index 1dc8857..0000000 --- a/@react-navigation+stack+6.0.7.patch +++ /dev/null @@ -1,68 +0,0 @@ -diff --git a/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx b/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx -index a013ff9..c99c5ab 100755 ---- a/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx -+++ b/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx -@@ -89,6 +89,8 @@ const hasOpacityStyle = (style: any) => { - return false; - }; - -+export const CardContext = React.createContext(null) -+ - export default class Card extends React.Component { - static defaultProps = { - shadowEnabled: false, -@@ -303,8 +305,15 @@ export default class Card extends React.Component { - gestureDirection === 'vertical-inverted' - ) { - distance = layout.height; -- translation = nativeEvent.translationY; -- velocity = nativeEvent.velocityY; -+ // translation = nativeEvent.translationY; -+ if(this.props.gesture._offset < 0) { -+ translation = this.props.gesture._offset - this.props.gesture._value; -+ velocity = nativeEvent.velocityY / 2; -+ }else{ -+ translation = this.props.gesture._value; -+ velocity = nativeEvent.velocityY; -+ } - } else { - distance = layout.width; - translation = nativeEvent.translationX; -@@ -392,7 +401,7 @@ export default class Card extends React.Component { - return { - maxDeltaX: 15, - minOffsetY: 5, -- hitSlop: { bottom: -layout.height + distance }, -+ // hitSlop: { bottom: -layout.height + distance }, - enableTrackpadTwoFingerGesture, - }; - } else if (gestureDirection === 'vertical-inverted') { -@@ -425,6 +434,7 @@ export default class Card extends React.Component { - } - - private contentRef = React.createRef(); -+ private scrollableGestureRef = React.createRef(); - - render() { - const { -@@ -526,10 +536,12 @@ export default class Card extends React.Component { - style={[styles.container, containerStyle, customContainerStyle]} - pointerEvents="box-none" - > -+ - - { - - - -+ - - - diff --git a/App.tsx b/App.tsx index b815ca0..869fb5c 100644 --- a/App.tsx +++ b/App.tsx @@ -9,11 +9,11 @@ const Stack = createStackNavigator(); export default () => ( - + diff --git a/patches/@react-navigation+stack+6.0.7.patch b/patches/@react-navigation+stack+6.0.7.patch index 1dc8857..bb8ec99 100644 --- a/patches/@react-navigation+stack+6.0.7.patch +++ b/patches/@react-navigation+stack+6.0.7.patch @@ -1,34 +1,100 @@ +diff --git a/node_modules/@react-navigation/stack/lib/typescript/src/index.d.ts b/node_modules/@react-navigation/stack/lib/typescript/src/index.d.ts +index 35a863b..66239cd 100644 +--- a/node_modules/@react-navigation/stack/lib/typescript/src/index.d.ts ++++ b/node_modules/@react-navigation/stack/lib/typescript/src/index.d.ts +@@ -22,6 +22,8 @@ export { default as CardAnimationContext } from './utils/CardAnimationContext'; + export { default as GestureHandlerRefContext } from './utils/GestureHandlerRefContext'; + export { default as useCardAnimation } from './utils/useCardAnimation'; + export { default as useGestureHandlerRef } from './utils/useGestureHandlerRef'; ++export { CardModalGestureContext } from './utils/CardModalGestureContext'; ++ + /** + * Types + */ +diff --git a/node_modules/@react-navigation/stack/lib/typescript/src/utils/CardModalGestureContext.d.ts b/node_modules/@react-navigation/stack/lib/typescript/src/utils/CardModalGestureContext.d.ts +new file mode 100644 +index 0000000..590bf05 +--- /dev/null ++++ b/node_modules/@react-navigation/stack/lib/typescript/src/utils/CardModalGestureContext.d.ts +@@ -0,0 +1,9 @@ ++import * as React from 'react'; ++import type { Animated } from 'react-native'; ++ ++export interface CardModalGestureContextType { ++ scrollableGestureRef: React.RefObject; ++ cardModalTranslateY: Animated.Value; ++} ++ ++export declare const CardModalGestureContext: React.Context; +diff --git a/node_modules/@react-navigation/stack/src/index.tsx b/node_modules/@react-navigation/stack/src/index.tsx +index f20d3fb..d914384 100644 +--- a/node_modules/@react-navigation/stack/src/index.tsx ++++ b/node_modules/@react-navigation/stack/src/index.tsx +@@ -31,6 +31,7 @@ export { default as CardAnimationContext } from './utils/CardAnimationContext'; + export { default as GestureHandlerRefContext } from './utils/GestureHandlerRefContext'; + export { default as useCardAnimation } from './utils/useCardAnimation'; + export { default as useGestureHandlerRef } from './utils/useGestureHandlerRef'; ++export { CardModalGestureContext } from './utils/CardModalGestureContext'; + + /** + * Types +diff --git a/node_modules/@react-navigation/stack/src/utils/CardModalGestureContext.ts b/node_modules/@react-navigation/stack/src/utils/CardModalGestureContext.ts +new file mode 100644 +index 0000000..c2e32db +--- /dev/null ++++ b/node_modules/@react-navigation/stack/src/utils/CardModalGestureContext.ts +@@ -0,0 +1,9 @@ ++import React from 'react'; ++import { Animated } from 'react-native'; ++ ++interface CardModalGestureContextType { ++ scrollableGestureRef: React.RefObject; ++ cardModalTranslateY: Animated.Value; ++} ++ ++export const CardModalGestureContext = React.createContext(null) +\ No newline at end of file diff --git a/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx b/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx -index a013ff9..c99c5ab 100755 +index a013ff9..6a6e5f9 100755 --- a/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx +++ b/node_modules/@react-navigation/stack/src/views/Stack/Card.tsx -@@ -89,6 +89,8 @@ const hasOpacityStyle = (style: any) => { - return false; - }; +@@ -21,6 +21,7 @@ import type { + TransitionSpec, + } from '../../types'; + import CardAnimationContext from '../../utils/CardAnimationContext'; ++import { CardModalGestureContext } from '../../utils/CardModalGestureContext'; + import getDistanceForDirection from '../../utils/getDistanceForDirection'; + import getInvertedMultiplier from '../../utils/getInvertedMultiplier'; + import memoize from '../../utils/memoize'; +@@ -294,6 +295,8 @@ export default class Card extends React.Component { + case GestureState.END: { + this.isSwiping.setValue(FALSE); -+export const CardContext = React.createContext(null) ++ this.isSwiping.removeListener + - export default class Card extends React.Component { - static defaultProps = { - shadowEnabled: false, -@@ -303,8 +305,15 @@ export default class Card extends React.Component { + let distance; + let translation; + let velocity; +@@ -303,8 +306,16 @@ export default class Card extends React.Component { gestureDirection === 'vertical-inverted' ) { distance = layout.height; - translation = nativeEvent.translationY; - velocity = nativeEvent.velocityY; -+ // translation = nativeEvent.translationY; ++ // @ts-ignore + if(this.props.gesture._offset < 0) { ++ // @ts-ignore + translation = this.props.gesture._offset - this.props.gesture._value; + velocity = nativeEvent.velocityY / 2; + }else{ ++ // @ts-ignore + translation = this.props.gesture._value; + velocity = nativeEvent.velocityY; + } } else { distance = layout.width; translation = nativeEvent.translationX; -@@ -392,7 +401,7 @@ export default class Card extends React.Component { +@@ -392,7 +403,7 @@ export default class Card extends React.Component { return { maxDeltaX: 15, minOffsetY: 5, @@ -37,7 +103,7 @@ index a013ff9..c99c5ab 100755 enableTrackpadTwoFingerGesture, }; } else if (gestureDirection === 'vertical-inverted') { -@@ -425,6 +434,7 @@ export default class Card extends React.Component { +@@ -425,6 +436,7 @@ export default class Card extends React.Component { } private contentRef = React.createRef(); @@ -45,11 +111,11 @@ index a013ff9..c99c5ab 100755 render() { const { -@@ -526,10 +536,12 @@ export default class Card extends React.Component { +@@ -526,10 +538,12 @@ export default class Card extends React.Component { style={[styles.container, containerStyle, customContainerStyle]} pointerEvents="box-none" > -+ ++ { +@@ -563,6 +577,7 @@ export default class Card extends React.Component { -+ ++ diff --git a/src/Modal.tsx b/src/Modal.tsx index ffa5ca1..07c3009 100644 --- a/src/Modal.tsx +++ b/src/Modal.tsx @@ -1,25 +1,8 @@ -import React, { useCallback, useContext, useRef } from "react"; -import { - Button, - FlatList, - FlatListProps, - StyleSheet, - Text, - View, -} from "react-native"; -import { - NativeViewGestureHandler, - NativeViewGestureHandlerProps, -} from "react-native-gesture-handler"; -import { useNavigation } from "@react-navigation/core"; -import { CardContext } from "@react-navigation/stack/src/views/Stack/Card"; -import Animated, { - runOnJS, - scrollTo, - useAnimatedRef, - useAnimatedScrollHandler, - useSharedValue, -} from "react-native-reanimated"; +import React from "react"; +import { FlatList, FlatListProps, StyleSheet, Text, View } from "react-native"; +import { NativeViewGestureHandler } from "react-native-gesture-handler"; +import Animated, { useAnimatedRef } from "react-native-reanimated"; +import { useCardModalGestureInteraction } from "./useCardModalGestureInteraction"; const AnimatedFlatList = Animated.createAnimatedComponent>(FlatList); @@ -28,8 +11,9 @@ const data = Array(40) .fill(0) .map((_, index) => `${index}`); -const keyExtractor = (item) => `item-${item}`; +const keyExtractor = (item: any) => `item-${item}`; +// @ts-ignore const renderItem = ({ item }) => ( {item} @@ -38,32 +22,9 @@ const renderItem = ({ item }) => ( export const Modal = () => { const scrollableRef = useAnimatedRef(); - const { scrollableGestureRef, cardPanTranslateY } = useContext(CardContext); - const allowScrollable = useSharedValue(true); - const setCardPanTranslateYOffset = useCallback((value: number) => { - // console.log("offset", -value); - cardPanTranslateY.setOffset(-value); - }, []); - - const handleScroll = useAnimatedScrollHandler( - { - onBeginDrag: ({ contentOffset: { y } }) => { - runOnJS(setCardPanTranslateYOffset)(y); - }, - onScroll: ({ contentOffset: { y } }) => { - if (y <= 0 || !allowScrollable.value) { - scrollTo(scrollableRef, 0, 0, false); - } - }, - }, - [allowScrollable, setCardPanTranslateYOffset] - ); - - cardPanTranslateY.addListener(({ value }) => { - // console.log("cardPanTranslateY", value); - allowScrollable.value = value <= 0; - }); + const { scrollableGestureRef, handleScrolling } = + useCardModalGestureInteraction(scrollableRef); return ( @@ -72,7 +33,7 @@ export const Modal = () => { data={data} keyExtractor={keyExtractor} scrollEventThrottle={16} - onScroll={handleScroll} + onScroll={handleScrolling} style={styles.container} contentContainerStyle={styles.contentContainer} renderItem={renderItem} diff --git a/src/useCardModalGestureInteraction.ts b/src/useCardModalGestureInteraction.ts new file mode 100644 index 0000000..4c86e0b --- /dev/null +++ b/src/useCardModalGestureInteraction.ts @@ -0,0 +1,57 @@ +import { useCallback, useContext, useEffect } from "react"; +import { CardModalGestureContext } from "@react-navigation/stack"; +import { + runOnJS, + scrollTo, + useAnimatedScrollHandler, + useSharedValue, +} from "react-native-reanimated"; +import type { FlatList, ScrollView } from "react-native"; + +export const useCardModalGestureInteraction = ( + scrollableRef: React.RefObject +) => { + // context + const { scrollableGestureRef, cardModalTranslateY } = useContext(CardModalGestureContext); + + // variables + const lockScrolling = useSharedValue(true); + + // callback + const setCardPanTranslateYOffset = useCallback((value: number) => { + cardModalTranslateY.setOffset(-value); + }, []); + const setLockScrolling = useCallback( + ({ value }) => { + lockScrolling.value = value > 0; + }, + [lockScrolling] + ); + const handleScrolling = useAnimatedScrollHandler( + { + onBeginDrag: ({ contentOffset: { y } }) => { + runOnJS(setCardPanTranslateYOffset)(y); + }, + onScroll: ({ contentOffset: { y } }) => { + if (y <= 0 || lockScrolling.value) { + // @ts-ignore + scrollTo(scrollableRef, 0, 0, false); + } + }, + }, + [lockScrolling, setCardPanTranslateYOffset] + ); + + // effects + useEffect(() => { + const listener = cardModalTranslateY.addListener(setLockScrolling); + return () => { + cardModalTranslateY.removeListener(listener); + }; + }, []); + + return { + scrollableGestureRef, + handleScrolling, + }; +};