forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import React from 'react'
2import {Pressable, View} from 'react-native'
3import Animated, {
4 runOnJS,
5 useAnimatedStyle,
6 useSharedValue,
7 withTiming,
8} from 'react-native-reanimated'
9import {msg} from '@lingui/macro'
10import {useLingui} from '@lingui/react'
11
12import {ScaleAndFadeIn} from '#/lib/custom-animations/ScaleAndFade'
13import {ShrinkAndPop} from '#/lib/custom-animations/ShrinkAndPop'
14import {useHaptics} from '#/lib/haptics'
15import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
16import {atoms as a, useTheme} from '#/alf'
17import {Text} from '#/components/Typography'
18import {IS_WEB} from '#/env'
19
20const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
21
22let lastIndex = 0
23
24export function ChatEmptyPill() {
25 const t = useTheme()
26 const {_} = useLingui()
27 const playHaptic = useHaptics()
28 const [promptIndex, setPromptIndex] = React.useState(lastIndex)
29
30 const scale = useSharedValue(1)
31
32 const enableSquareButtons = useEnableSquareButtons()
33
34 const prompts = React.useMemo(() => {
35 return [
36 _(msg`Say hi!`),
37 _(msg`Share your favorite feed!`),
38 _(msg`Say something funny!`),
39 _(msg`Share a fun fact!`),
40 _(msg`Share a cool story!`),
41 _(msg`Send a neat website!`),
42 _(msg`Clip 馃惔 clop 馃惔 #horsefacts`),
43 ]
44 }, [_])
45
46 const onPressIn = React.useCallback(() => {
47 if (IS_WEB) return
48 scale.set(() => withTiming(1.075, {duration: 100}))
49 }, [scale])
50
51 const onPressOut = React.useCallback(() => {
52 if (IS_WEB) return
53 scale.set(() => withTiming(1, {duration: 100}))
54 }, [scale])
55
56 const onPress = React.useCallback(() => {
57 runOnJS(playHaptic)()
58 let randomPromptIndex = Math.floor(Math.random() * prompts.length)
59 while (randomPromptIndex === lastIndex) {
60 randomPromptIndex = Math.floor(Math.random() * prompts.length)
61 }
62 setPromptIndex(randomPromptIndex)
63 lastIndex = randomPromptIndex
64 }, [playHaptic, prompts.length])
65
66 const animatedStyle = useAnimatedStyle(() => ({
67 transform: [{scale: scale.get()}],
68 }))
69
70 return (
71 <View
72 style={[
73 a.absolute,
74 a.w_full,
75 a.z_10,
76 a.align_center,
77 {
78 top: -50,
79 },
80 ]}>
81 <AnimatedPressable
82 style={[
83 a.px_xl,
84 a.py_md,
85 enableSquareButtons ? a.rounded_sm : a.rounded_full,
86 t.atoms.bg_contrast_25,
87 a.align_center,
88 animatedStyle,
89 ]}
90 entering={ScaleAndFadeIn}
91 exiting={ShrinkAndPop}
92 onPress={onPress}
93 onPressIn={onPressIn}
94 onPressOut={onPressOut}>
95 <Text
96 style={[a.font_semi_bold, a.pointer_events_none]}
97 selectable={false}>
98 {prompts[promptIndex]}
99 </Text>
100 </AnimatedPressable>
101 </View>
102 )
103}