mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {createContext, useContext, useMemo} from 'react'
2import {type GestureResponderEvent, type View} from 'react-native'
3
4import {POST_CTRL_HITSLOP} from '#/lib/constants'
5import {useHaptics} from '#/lib/haptics'
6import {atoms as a, useTheme} from '#/alf'
7import {Button, type ButtonProps} from '#/components/Button'
8import {type Props as SVGIconProps} from '#/components/icons/common'
9import {Text, type TextProps} from '#/components/Typography'
10
11const PostControlContext = createContext<{
12 big?: boolean
13 active?: boolean
14 color?: {color: string}
15}>({})
16
17// Base button style, which the the other ones extend
18export function PostControlButton({
19 ref,
20 onPress,
21 onLongPress,
22 children,
23 big,
24 active,
25 activeColor,
26 ...props
27}: ButtonProps & {
28 ref?: React.Ref<View>
29 active?: boolean
30 big?: boolean
31 color?: string
32 activeColor?: string
33}) {
34 const t = useTheme()
35 const playHaptic = useHaptics()
36
37 const ctx = useMemo(
38 () => ({
39 big,
40 active,
41 color: {
42 color: activeColor && active ? activeColor : t.palette.contrast_500,
43 },
44 }),
45 [big, active, activeColor, t.palette.contrast_500],
46 )
47
48 const style = useMemo(
49 () => [
50 a.flex_row,
51 a.align_center,
52 a.gap_xs,
53 a.bg_transparent,
54 {padding: 5},
55 ],
56 [],
57 )
58
59 const handlePress = useMemo(() => {
60 if (!onPress) return
61 return (evt: GestureResponderEvent) => {
62 playHaptic('Light')
63 onPress(evt)
64 }
65 }, [onPress, playHaptic])
66
67 const handleLongPress = useMemo(() => {
68 if (!onLongPress) return
69 return (evt: GestureResponderEvent) => {
70 playHaptic('Heavy')
71 onLongPress(evt)
72 }
73 }, [onLongPress, playHaptic])
74
75 return (
76 <Button
77 ref={ref}
78 onPress={handlePress}
79 onLongPress={handleLongPress}
80 style={style}
81 hoverStyle={t.atoms.bg_contrast_25}
82 shape="round"
83 variant="ghost"
84 color="secondary"
85 hitSlop={POST_CTRL_HITSLOP}
86 {...props}>
87 {typeof children === 'function' ? (
88 args => (
89 <PostControlContext.Provider value={ctx}>
90 {children(args)}
91 </PostControlContext.Provider>
92 )
93 ) : (
94 <PostControlContext.Provider value={ctx}>
95 {children}
96 </PostControlContext.Provider>
97 )}
98 </Button>
99 )
100}
101
102export function PostControlButtonIcon({
103 icon: Comp,
104}: {
105 icon: React.ComponentType<SVGIconProps>
106}) {
107 const {big, color} = useContext(PostControlContext)
108
109 return <Comp style={[color, a.pointer_events_none]} width={big ? 22 : 18} />
110}
111
112export function PostControlButtonText({style, ...props}: TextProps) {
113 const {big, active, color} = useContext(PostControlContext)
114
115 return (
116 <Text
117 style={[color, big ? a.text_md : a.text_sm, active && a.font_bold, style]}
118 {...props}
119 />
120 )
121}