wonday / react-native-pdf

A <Pdf /> component for react-native

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot scroll inside GestureDetector on Android

shav95 opened this issue · comments

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}>


<Animated.View
style={[
modalStyles({type, ...props}).contentContainer,
animatedStyle,
]}>
<CardWrapper
backgroundColor={backgroundColor}
containerStyles={[
modalStyles({type, ...props}).container,
contentContainerStyles,
]}>
{showCloseButton && (



)}

            {type === 'bottom-sheet' && showGrabber ? (
              <View style={modalStyles({color}).grabber} />
            ) : null}

            {children}
          </CardWrapper>
        </Animated.View>
      </GestureDetector>
    </GestureHandlerRootView>
  </Animated.View>

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

);
};

export default Modal;