mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at thread-bug 2.9 kB view raw
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}