Bluesky app fork with some witchin' additions 馃挮
at readme-update 103 lines 2.8 kB view raw
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}