import React, { useEffect, useRef } from 'react'; import { Animated, Easing, StyleSheet, View, PanResponder, type PanResponderGestureState, } from 'react-native'; import { moderateScale } from 'react-native-size-matters'; import { defaultScale } from '../../utils/Common'; import { withTheme, useTheme } from '../../core/theming'; import type { Theme } from '../../utils/types'; import TTypography from '../TTypography/TTypography'; import TButton from '../TButton/TButton'; import { TypographyVariant } from '../TTypography/TTypographyEnum'; import IconSVG from '../../assets/svgs'; interface Props { variant: 'success' | 'failure'; message: string; onDismiss: () => void; action?: () => void; actionTitle?: string; duration?: number; offset?: number; theme: Theme; } const TToast: React.FC = ({ variant = 'success', message, action, actionTitle, onDismiss, duration = 30000, offset = 100, }): any => { const { colors } = useTheme(); const styleWithProps = styles({ colors }); const popAnim = useRef(new Animated.Value(-offset)).current; let id: any; const panResponder = useRef( PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove(_e, gestureState) { animateMovement(gestureState); }, onPanResponderRelease(_e, gestureState) { animateRelease(gestureState); }, }) ).current; const animateMovement = (gestureState: PanResponderGestureState) => { const { dy } = gestureState; let value = 1 + dy / 100; if (value < 1) { popAnim.setValue(value); } }; const animateRelease = (gestureState: PanResponderGestureState) => { const { dy, vy } = gestureState; let value = 1 + dy / 100; if (value < 0.65) { Animated.spring(popAnim, { toValue: -500, speed: -vy, useNativeDriver: true, }).start(({ finished }) => { if (finished) { resetAnim(); onDismiss(); } }); } else if (value < 0.95) { Animated.spring(popAnim, { toValue: 1, velocity: vy, useNativeDriver: true, }).start(); } }; useEffect(() => { popIn(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const resetAnim = () => { clearTimeout(id); // popAnim.stopAnimation((value) => { // //console.log(value, '////val'); // }); //console.log(id, '=====//'); }; const popIn = () => { Animated.timing(popAnim, { toValue: 10, duration: 300, useNativeDriver: true, easing: Easing.linear, }).start(() => popOut()); }; const popOut = () => { setTimeout(() => { Animated.timing(popAnim, { toValue: -offset, duration: 300, useNativeDriver: true, easing: Easing.linear, }).start(({ finished }) => { if (finished) { resetAnim(); onDismiss(); } }); }, duration); }; const instantPopOut = () => { Animated.timing(popAnim, { toValue: -offset, duration: 150, useNativeDriver: true, easing: Easing.linear, }).start(({ finished }) => { if (finished) { resetAnim(); } }); }; return ( {message} {actionTitle !== undefined && ( { if (action) { action(); } onDismiss(); instantPopOut(); }} backgroundColor={colors.background} /> )} ); }; export default withTheme(TToast); const styles = (props: { colors: any }) => StyleSheet.create({ toastContainer: { justifyContent: 'center', alignItems: 'center', borderRadius: moderateScale(4, defaultScale), shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 3.84, elevation: 5, marginLeft: moderateScale(8, defaultScale), marginRight: moderateScale(8, defaultScale), backgroundColor: props.colors.white, position: 'absolute', top: 40, left: 8, right: 8, }, rowContainer: { flex: 1, flexDirection: 'row', }, variantContainer: { width: 36, height: 64, justifyContent: 'center', alignItems: 'center', }, messageContainer: { flex: 1, justifyContent: 'center', alignItems: 'flex-start', padding: 10, paddingHorizontal: moderateScale(12, defaultScale), }, messageText: { fontSize: moderateScale(16, defaultScale), }, actionContainer: { flex: 1, justifyContent: 'center', alignItems: 'flex-start', paddingBottom: 4, paddingTop: 10, }, commanStyle: { borderBottomLeftRadius: 4, borderTopLeftRadius: 4, }, successBackColor: { backgroundColor: props.colors.success, }, errorBackColor: { backgroundColor: props.colors.failure, }, });