wonday / react-native-pdf

A <Pdf /> component for react-native
MIT License
1.57k stars 532 forks source link

Cannot scroll inside GestureDetector on Android #845

Open shav95 opened 3 weeks ago

shav95 commented 3 weeks ago

Here is my custom modal, I cannot scroll inside this modal

import { Dispatch, FC, ReactNode, SetStateAction, useCallback, useContext, } from 'react'; import { Platform, Pressable, Modal as ReactNativeModal, ModalProps as ReactNativeModalProps, StyleProp, View, ViewStyle, } from 'react-native'; import Animated, { FadeIn, FadeOut, runOnJS, useAnimatedStyle, useSharedValue, } from 'react-native-reanimated';

import {CardWrapper, Icon, Loader} from 'molecules'; import { GestureHandlerRootView, GestureDetector, Gesture, } from 'react-native-gesture-handler'; import {useSelector} from 'react-redux'; import {getMainLoadingState, getPinState} from 'rtk'; import {IColor, ThemeContext} from 'theme'; import {modalStyles} from './modal-styles';

export interface ModalProps extends ReactNativeModalProps { children: ReactNode | ReactNode[]; showLoader?: boolean; isVisible: boolean; setIsVisible: Dispatch<SetStateAction>; swipeToClose?: boolean; showCloseButton?: boolean; showGrabber?: boolean; backgroundColor?: IColor; type?: 'modal' | 'bottom-sheet'; contentContainerStyles?: StyleProp; activateAfterLongPress?: number; }

const Modal: FC = ({ isVisible, setIsVisible, children, showLoader = false, swipeToClose = true, showCloseButton = false, showGrabber = true, backgroundColor = 'surface_overlay', type = 'modal', contentContainerStyles = {}, activateAfterLongPress = 180, ...props }) => { const {color} = useContext(ThemeContext); const isLoading = useSelector(getMainLoadingState);

// In Ios We Cannot Open Multiple Modals // Our Pin Menu Is Inside A Modal And When We Open Pin Modal Over Another Opened Modal, It Will Not Work On IOS const isPinVisible = useSelector(getPinState);

const translateY = useSharedValue(0);

const onClose = useCallback(() => { translateY.value = 0; setIsVisible(false); }, [translateY.value]);

const panGesture = Gesture.Pan() .onBegin(() => { translateY.value = 0; }) .onUpdate(event => { if (event.translationY > 0 && swipeToClose) translateY.value = event.translationY; }) .onEnd(event => { if (event.translationY > 100) { if (onClose && swipeToClose) { runOnJS(onClose)(); } } else { translateY.value = 0; } });

const simultaneousGesture = Gesture.Simultaneous( panGesture, Gesture.Native().disallowInterruption(false).shouldActivateOnStart(false), );

const animatedStyle = useAnimatedStyle(() => { return { transform: [ { translateY: translateY.value, }, ], }; });

return ( <ReactNativeModal {...props} animationType="fade" presentationStyle="overFullScreen" visible={Platform.OS === 'ios' ? !isPinVisible && isVisible : isVisible} transparent> <Animated.View entering={FadeIn} exiting={FadeOut} style={modalStyles({color, ...props}).animatedBackground}>

{showCloseButton && ( )} {type === 'bottom-sheet' && showGrabber ? ( ) : null} {children}
  </Animated.View>

  <Loader isLoading={showLoader && isLoading} />
</ReactNativeModal>

); };

export default Modal;

shav95 commented 3 weeks ago

@wonday