this repo has no description
1import {useCallback} from 'react'
2import {Pressable, View} from 'react-native'
3import Animated, {
4 runOnJS,
5 useAnimatedStyle,
6 useSharedValue,
7 withTiming,
8} from 'react-native-reanimated'
9import {useSafeAreaInsets} from 'react-native-safe-area-context'
10import {Trans} from '@lingui/react/macro'
11
12import {
13 ScaleAndFadeIn,
14 ScaleAndFadeOut,
15} from '#/lib/custom-animations/ScaleAndFade'
16import {useHaptics} from '#/lib/haptics'
17import {atoms as a, useTheme} from '#/alf'
18import {Text} from '#/components/Typography'
19import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env'
20
21const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
22
23export function NewMessagesPill({
24 onPress: onPressInner,
25}: {
26 onPress: () => void
27}) {
28 const t = useTheme()
29 const playHaptic = useHaptics()
30 const {bottom: bottomInset} = useSafeAreaInsets()
31 const bottomBarHeight = IS_IOS ? 42 : IS_ANDROID ? 60 : 0
32 const bottomOffset = IS_WEB ? 0 : bottomInset + bottomBarHeight
33
34 const scale = useSharedValue(1)
35
36 const onPressIn = useCallback(() => {
37 if (IS_WEB) return
38 scale.set(() => withTiming(1.075, {duration: 100}))
39 }, [scale])
40
41 const onPressOut = useCallback(() => {
42 if (IS_WEB) return
43 scale.set(() => withTiming(1, {duration: 100}))
44 }, [scale])
45
46 const onPress = useCallback(() => {
47 runOnJS(playHaptic)()
48 onPressInner?.()
49 }, [onPressInner, playHaptic])
50
51 const animatedStyle = useAnimatedStyle(() => ({
52 transform: [{scale: scale.get()}],
53 }))
54
55 return (
56 <View
57 style={[
58 a.absolute,
59 a.w_full,
60 a.z_10,
61 a.align_center,
62 {
63 bottom: bottomOffset + 70,
64 // Don't prevent scrolling in this area _except_ for in the pill itself
65 pointerEvents: 'box-none',
66 },
67 ]}>
68 <AnimatedPressable
69 style={[
70 a.py_sm,
71 a.rounded_full,
72 a.shadow_sm,
73 a.border,
74 t.atoms.bg_contrast_50,
75 t.atoms.border_contrast_medium,
76 {
77 width: 160,
78 alignItems: 'center',
79 shadowOpacity: 0.125,
80 shadowRadius: 12,
81 shadowOffset: {width: 0, height: 5},
82 pointerEvents: 'box-only',
83 },
84 animatedStyle,
85 ]}
86 entering={ScaleAndFadeIn}
87 exiting={ScaleAndFadeOut}
88 onPress={onPress}
89 onPressIn={onPressIn}
90 onPressOut={onPressOut}>
91 <Text style={[a.font_semi_bold]}>
92 <Trans>New messages</Trans>
93 </Text>
94 </AnimatedPressable>
95 </View>
96 )
97}