[🐴] Empty chat prompt (#4132)

* Add empty chat pill

* Tweak padding

* move to `components`, place inside `KeyboardStickyView`

* cleanup unused vars

* add a new animation type

* (unrelated) add haptic to long press

* adjust shrink and pop

---------

Co-authored-by: Hailey <me@haileyok.com>
This commit is contained in:
Eric Bailey 2024-05-20 18:56:44 -05:00 committed by GitHub
parent 6dde487563
commit a7b0242cc8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 143 additions and 12 deletions

View file

@ -0,0 +1,98 @@
import React from 'react'
import {Pressable, View} from 'react-native'
import Animated, {
runOnJS,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {ScaleAndFadeIn} from 'lib/custom-animations/ScaleAndFade'
import {ShrinkAndPop} from 'lib/custom-animations/ShrinkAndPop'
import {useHaptics} from 'lib/haptics'
import {isWeb} from 'platform/detection'
import {atoms as a, useTheme} from '#/alf'
import {Text} from '#/components/Typography'
const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
let lastIndex = 0
export function ChatEmptyPill() {
const t = useTheme()
const {_} = useLingui()
const playHaptic = useHaptics()
const [promptIndex, setPromptIndex] = React.useState(lastIndex)
const scale = useSharedValue(1)
const prompts = React.useMemo(() => {
return [
_(msg`Say hello!`),
_(msg`Share your favorite feed!`),
_(msg`Tell a joke!`),
_(msg`Share a fun fact!`),
_(msg`Share a cool story!`),
_(msg`Send a neat website!`),
_(msg`Clip 🐴 clop 🐴`),
]
}, [_])
const onPressIn = React.useCallback(() => {
if (isWeb) return
scale.value = withTiming(1.075, {duration: 100})
}, [scale])
const onPressOut = React.useCallback(() => {
if (isWeb) return
scale.value = withTiming(1, {duration: 100})
}, [scale])
const onPress = React.useCallback(() => {
runOnJS(playHaptic)()
let randomPromptIndex = Math.floor(Math.random() * prompts.length)
while (randomPromptIndex === lastIndex) {
randomPromptIndex = Math.floor(Math.random() * prompts.length)
}
setPromptIndex(randomPromptIndex)
lastIndex = randomPromptIndex
}, [playHaptic, prompts.length])
const animatedStyle = useAnimatedStyle(() => ({
transform: [{scale: scale.value}],
}))
return (
<View
style={[
a.absolute,
a.w_full,
a.z_10,
a.align_center,
{
bottom: 70,
},
]}>
<AnimatedPressable
style={[
a.px_xl,
a.py_md,
a.rounded_full,
t.atoms.bg_contrast_25,
a.align_center,
animatedStyle,
]}
entering={ScaleAndFadeIn}
exiting={ShrinkAndPop}
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}>
<Text style={[a.font_bold, a.pointer_events_none]} selectable={false}>
{prompts[promptIndex]}
</Text>
</AnimatedPressable>
</View>
)
}