forked from
jollywhoppers.com/witchsky.app
fork
Configure Feed
Select the types of activity you want to include in your feed.
Bluesky app fork with some witchin' additions 馃挮
fork
Configure Feed
Select the types of activity you want to include in your feed.
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 {useSafeAreaInsets} from 'react-native-safe-area-context'
10import {Trans} from '@lingui/macro'
11
12import {
13 ScaleAndFadeIn,
14 ScaleAndFadeOut,
15} from '#/lib/custom-animations/ScaleAndFade'
16import {useHaptics} from '#/lib/haptics'
17import {isAndroid, isIOS, isWeb} from '#/platform/detection'
18import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
19import {atoms as a, useTheme} from '#/alf'
20import {Text} from '#/components/Typography'
21
22const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
23
24export function NewMessagesPill({
25 onPress: onPressInner,
26}: {
27 onPress: () => void
28}) {
29 const t = useTheme()
30 const playHaptic = useHaptics()
31 const {bottom: bottomInset} = useSafeAreaInsets()
32 const bottomBarHeight = isIOS ? 42 : isAndroid ? 60 : 0
33 const bottomOffset = isWeb ? 0 : bottomInset + bottomBarHeight
34
35 const scale = useSharedValue(1)
36
37 const enableSquareButtons = useEnableSquareButtons()
38
39 const onPressIn = React.useCallback(() => {
40 if (isWeb) return
41 scale.set(() => withTiming(1.075, {duration: 100}))
42 }, [scale])
43
44 const onPressOut = React.useCallback(() => {
45 if (isWeb) return
46 scale.set(() => withTiming(1, {duration: 100}))
47 }, [scale])
48
49 const onPress = React.useCallback(() => {
50 runOnJS(playHaptic)()
51 onPressInner?.()
52 }, [onPressInner, playHaptic])
53
54 const animatedStyle = useAnimatedStyle(() => ({
55 transform: [{scale: scale.get()}],
56 }))
57
58 return (
59 <View
60 style={[
61 a.absolute,
62 a.w_full,
63 a.z_10,
64 a.align_center,
65 {
66 bottom: bottomOffset + 70,
67 // Don't prevent scrolling in this area _except_ for in the pill itself
68 pointerEvents: 'box-none',
69 },
70 ]}>
71 <AnimatedPressable
72 style={[
73 a.py_sm,
74 enableSquareButtons ? a.rounded_sm : a.rounded_full,
75 a.shadow_sm,
76 a.border,
77 t.atoms.bg_contrast_50,
78 t.atoms.border_contrast_medium,
79 {
80 width: 160,
81 alignItems: 'center',
82 shadowOpacity: 0.125,
83 shadowRadius: 12,
84 shadowOffset: {width: 0, height: 5},
85 pointerEvents: 'box-only',
86 },
87 animatedStyle,
88 ]}
89 entering={ScaleAndFadeIn}
90 exiting={ScaleAndFadeOut}
91 onPress={onPress}
92 onPressIn={onPressIn}
93 onPressOut={onPressOut}>
94 <Text style={[a.font_semi_bold]}>
95 <Trans>New messages</Trans>
96 </Text>
97 </AnimatedPressable>
98 </View>
99 )
100}