import React, { useCallback, useContext, useEffect, useRef } from 'react'; import { Animated, Easing, KeyboardAvoidingView, Platform, Pressable, StyleSheet, View, Modal as ModalRN, BackHandler, } from 'react-native'; import { ApplicationContext, MiniAppContext } from '../Context'; import { Styles } from '../Consts'; import Navigation from './Navigation'; import { ModalParams } from './types'; import BottomSheet from './BottomSheet'; import { runOnJS } from 'react-native-reanimated'; const ModalScreen: React.FC = props => { if (props.route?.params?.isBottomSheet) { return ; } return ; }; const Modal: React.FC = props => { const { navigator } = useContext(ApplicationContext); const context = useContext(MiniAppContext); const modalParams = useRef(undefined); const { screen, barrierDismissible, modalStyle, useNativeModal = false, } = props.route.params; const Component = useRef(screen).current; const opacity = useRef(new Animated.Value(0)).current; const scale = useRef(new Animated.Value(0.8)).current; const navigation = new Navigation(props.navigation); const params = { ...props.route.params, navigation, }; delete params.screen; let Container: any = View; if (useNativeModal) { Container = ModalRN; } if (screen != null) { const screenProps = screen?.()?.props || {}; modalParams.current = { title: screenProps?.title || '', description: screenProps?.description || '', }; } useEffect(() => { const item: any = { screenName: params.screen, componentName: 'Modal', ...modalParams.current, }; context?.autoTracking?.({ ...context, ...item, }); }, [context, params.screen]); useEffect(() => { Animated.parallel([ Animated.timing(opacity, { toValue: 1, duration: 250, useNativeDriver: true, }), Animated.timing(scale, { toValue: 1, duration: 250, easing: Easing.bezier(0.2, 0.0, 0, 1.0), useNativeDriver: true, }), ]).start(); return () => { props.route.params?.onDismiss?.(); }; }, [opacity, props.route.params, scale]); const onDismiss = useCallback( (callback = () => {}, preventClose = false) => { if (preventClose) { return; } Animated.parallel([ Animated.timing(opacity, { toValue: 0, duration: 200, useNativeDriver: true, }), Animated.timing(scale, { toValue: 0.8, duration: 200, easing: Easing.linear, useNativeDriver: true, }), ]).start(() => { navigator?.pop(); runOnJS(callback)(); }); }, [navigator, opacity, scale], ); useEffect(() => { const backHandler = BackHandler.addEventListener( 'hardwareBackPress', () => { onDismiss(undefined, barrierDismissible); return true; }, ); return () => backHandler.remove(); }, [barrierDismissible, onDismiss]); return ( onDismiss(undefined, barrierDismissible)} > ); }; const styles = StyleSheet.create({ overlayContent: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', }, }); export default ModalScreen;