mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React, {memo, useMemo, useState} from 'react'
2import {
3 Pressable,
4 type PressableProps,
5 type StyleProp,
6 type ViewStyle,
7} from 'react-native'
8import {
9 AppBskyFeedDefs,
10 AppBskyFeedPost,
11 AppBskyFeedThreadgate,
12 RichText as RichTextAPI,
13} from '@atproto/api'
14import {msg} from '@lingui/macro'
15import {useLingui} from '@lingui/react'
16
17import {useTheme} from '#/lib/ThemeContext'
18import {Shadow} from '#/state/cache/post-shadow'
19import {atoms as a, useTheme as useAlf} from '#/alf'
20import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
21import {useMenuControl} from '#/components/Menu'
22import * as Menu from '#/components/Menu'
23import {EventStopper} from '../EventStopper'
24import {PostDropdownMenuItems} from './PostDropdownBtnMenuItems'
25
26let PostDropdownBtn = ({
27 testID,
28 post,
29 postFeedContext,
30 record,
31 richText,
32 style,
33 hitSlop,
34 size,
35 timestamp,
36 threadgateRecord,
37}: {
38 testID: string
39 post: Shadow<AppBskyFeedDefs.PostView>
40 postFeedContext: string | undefined
41 record: AppBskyFeedPost.Record
42 richText: RichTextAPI
43 style?: StyleProp<ViewStyle>
44 hitSlop?: PressableProps['hitSlop']
45 size?: 'lg' | 'md' | 'sm'
46 timestamp: string
47 threadgateRecord?: AppBskyFeedThreadgate.Record
48}): React.ReactNode => {
49 const theme = useTheme()
50 const alf = useAlf()
51 const {_} = useLingui()
52 const defaultCtrlColor = theme.palette.default.postCtrl
53 const menuControl = useMenuControl()
54 const [hasBeenOpen, setHasBeenOpen] = useState(false)
55 const lazyMenuControl = useMemo(
56 () => ({
57 ...menuControl,
58 open() {
59 setHasBeenOpen(true)
60 // HACK. We need the state update to be flushed by the time
61 // menuControl.open() fires but RN doesn't expose flushSync.
62 setTimeout(menuControl.open)
63 },
64 }),
65 [menuControl, setHasBeenOpen],
66 )
67 return (
68 <EventStopper onKeyDown={false}>
69 <Menu.Root control={lazyMenuControl}>
70 <Menu.Trigger label={_(msg`Open post options menu`)}>
71 {({props, state}) => {
72 return (
73 <Pressable
74 {...props}
75 hitSlop={hitSlop}
76 testID={testID}
77 style={[
78 style,
79 a.rounded_full,
80 (state.hovered || state.pressed) && [
81 alf.atoms.bg_contrast_25,
82 ],
83 ]}>
84 <DotsHorizontal
85 fill={defaultCtrlColor}
86 style={{pointerEvents: 'none'}}
87 size={size}
88 />
89 </Pressable>
90 )
91 }}
92 </Menu.Trigger>
93 {hasBeenOpen && (
94 // Lazily initialized. Once mounted, they stay mounted.
95 <PostDropdownMenuItems
96 testID={testID}
97 post={post}
98 postFeedContext={postFeedContext}
99 record={record}
100 richText={richText}
101 timestamp={timestamp}
102 threadgateRecord={threadgateRecord}
103 />
104 )}
105 </Menu.Root>
106 </EventStopper>
107 )
108}
109
110PostDropdownBtn = memo(PostDropdownBtn)
111export {PostDropdownBtn}