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