import { Dimensions, Image, StyleSheet, Text, View, type ViewStyle, type ImageSourcePropType, Platform } from 'react-native'
import React, { useEffect } from 'react'
import { GestureDetector } from 'react-native-gesture-handler'
import Animated, {Easing, useAnimatedStyle, useSharedValue, withSpring, withTiming} from 'react-native-reanimated'
const Toast = ({
message,
visible = false,
duration = 2000,
speed = 300,
progress = false,
bounce = false,
autoDismiss = false,
centerText = false,
dismissGesture,
icon = undefined,
style = {},
dismiss
}: {
message: string,
visible: boolean,
duration?: number,
speed?: number,
progress?: boolean,
bounce?: boolean,
autoDismiss?: boolean,
centerText?: boolean,
icon?: ImageSourcePropType,
dismissGesture: any,
style?: ViewStyle | undefined | ViewStyle[],
dismiss: () => void
}) => {
const initialToastPosition = -Dimensions.get('window').height
const toastVisiblePosition = Platform.OS == 'ios' ? 50 : 0
const progressValue = useSharedValue(Dimensions.get('window').width)
const topValue = useSharedValue(initialToastPosition)
let hideToastTimeout: NodeJS.Timeout
const dismissToast = () => {
topValue.value = withTiming(initialToastPosition, {
duration: 400
})
dismiss()
}
useEffect(() => {
if (visible) {
topValue.value = initialToastPosition
animateProgressBar()
if (bounce) {
topValue.value = withSpring(toastVisiblePosition, {
mass: .7,
damping: 10,
stiffness: 100,
overshootClamping: false,
restDisplacementThreshold: 0.01,
restSpeedThreshold: 2
})
} else {
topValue.value = withTiming(toastVisiblePosition, {
duration: speed,
easing: Easing.linear
})
}
hideToastTimeout = setTimeout(() => {
if (autoDismiss) {
dismissToast()
}
}, duration + 1800);
} else {
dismissToast()
}
return () => {
clearTimeout(hideToastTimeout)
}
}, [visible])
const animateProgressBar = () => {
progressValue.value = Dimensions.get('window').width - 20
progressValue.value = withTiming(0, {
duration: duration + 2000,
})
}
const animatedContainerStyle = useAnimatedStyle(() => {
return {
transform: [
{
translateY: topValue.value,
}
],
}
})
const animatedProgressBar = useAnimatedStyle(() => {
return {
width: progressValue.value
}
})
const Icon = () => {
if (!icon) {
return null
}
return (
)
}
return (
{message}
{
progress && (
)
}
)
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
zIndex: 10000000000,
width: Dimensions.get('window').width - 20,
marginHorizontal: 10,
marginTop: 15,
borderRadius: 5
}
})
export default Toast