mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {useCallback, useEffect, useState} from 'react'
2import {type GestureResponderEvent, View} from 'react-native'
3import Animated, {
4 FadeOutUp,
5 useReducedMotion,
6 ZoomIn,
7} from 'react-native-reanimated'
8import * as Clipboard from 'expo-clipboard'
9import {Trans} from '@lingui/macro'
10
11import {atoms as a, useTheme} from '#/alf'
12import {Button, type ButtonProps} from '#/components/Button'
13import {Text} from '#/components/Typography'
14
15export function CopyButton({
16 style,
17 value,
18 onPress: onPressProp,
19 ...props
20}: ButtonProps & {value: string}) {
21 const [hasBeenCopied, setHasBeenCopied] = useState(false)
22 const t = useTheme()
23 const isReducedMotionEnabled = useReducedMotion()
24
25 useEffect(() => {
26 if (hasBeenCopied) {
27 const timeout = setTimeout(
28 () => setHasBeenCopied(false),
29 isReducedMotionEnabled ? 2000 : 100,
30 )
31 return () => clearTimeout(timeout)
32 }
33 }, [hasBeenCopied, isReducedMotionEnabled])
34
35 const onPress = useCallback(
36 (evt: GestureResponderEvent) => {
37 Clipboard.setStringAsync(value)
38 setHasBeenCopied(true)
39 onPressProp?.(evt)
40 },
41 [value, onPressProp],
42 )
43
44 return (
45 <View style={[a.relative]}>
46 {hasBeenCopied && (
47 <Animated.View
48 entering={ZoomIn.duration(100)}
49 exiting={FadeOutUp.duration(2000)}
50 style={[
51 a.absolute,
52 {bottom: '100%', right: 0},
53 a.justify_center,
54 a.gap_sm,
55 a.z_10,
56 a.pb_sm,
57 ]}
58 pointerEvents="none">
59 <Text
60 style={[
61 a.font_semi_bold,
62 a.text_right,
63 a.text_md,
64 t.atoms.text_contrast_high,
65 ]}>
66 <Trans>Copied!</Trans>
67 </Text>
68 </Animated.View>
69 )}
70 <Button
71 style={[a.flex_1, a.justify_between, style]}
72 onPress={onPress}
73 {...props}
74 />
75 </View>
76 )
77}