mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {memo, useMemo, useState} from 'react'
2import {type Insets} from 'react-native'
3import {
4 type AppBskyFeedDefs,
5 type AppBskyFeedPost,
6 type AppBskyFeedThreadgate,
7 type RichText as RichTextAPI,
8} from '@atproto/api'
9import {msg} from '@lingui/macro'
10import {useLingui} from '@lingui/react'
11
12import {type Shadow} from '#/state/cache/post-shadow'
13import {EventStopper} from '#/view/com/util/EventStopper'
14import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
15import {useMenuControl} from '#/components/Menu'
16import * as Menu from '#/components/Menu'
17import {PostControlButton, PostControlButtonIcon} from '../PostControlButton'
18import {PostMenuItems} from './PostMenuItems'
19
20let PostMenuButton = ({
21 testID,
22 post,
23 postFeedContext,
24 postReqId,
25 big,
26 record,
27 richText,
28 timestamp,
29 threadgateRecord,
30 onShowLess,
31 hitSlop,
32}: {
33 testID: string
34 post: Shadow<AppBskyFeedDefs.PostView>
35 postFeedContext: string | undefined
36 postReqId: string | undefined
37 big?: boolean
38 record: AppBskyFeedPost.Record
39 richText: RichTextAPI
40 timestamp: string
41 threadgateRecord?: AppBskyFeedThreadgate.Record
42 onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void
43 hitSlop?: Insets
44}): React.ReactNode => {
45 const {_} = useLingui()
46
47 const menuControl = useMenuControl()
48 const [hasBeenOpen, setHasBeenOpen] = useState(false)
49 const lazyMenuControl = useMemo(
50 () => ({
51 ...menuControl,
52 open() {
53 setHasBeenOpen(true)
54 // HACK. We need the state update to be flushed by the time
55 // menuControl.open() fires but RN doesn't expose flushSync.
56 setTimeout(menuControl.open)
57 },
58 }),
59 [menuControl, setHasBeenOpen],
60 )
61 return (
62 <EventStopper onKeyDown={false}>
63 <Menu.Root control={lazyMenuControl}>
64 <Menu.Trigger label={_(msg`Open post options menu`)}>
65 {({props}) => {
66 return (
67 <PostControlButton
68 testID="postDropdownBtn"
69 big={big}
70 label={props.accessibilityLabel}
71 {...props}
72 hitSlop={hitSlop}>
73 <PostControlButtonIcon icon={DotsHorizontal} />
74 </PostControlButton>
75 )
76 }}
77 </Menu.Trigger>
78 {hasBeenOpen && (
79 // Lazily initialized. Once mounted, they stay mounted.
80 <PostMenuItems
81 testID={testID}
82 post={post}
83 postFeedContext={postFeedContext}
84 postReqId={postReqId}
85 record={record}
86 richText={richText}
87 timestamp={timestamp}
88 threadgateRecord={threadgateRecord}
89 onShowLess={onShowLess}
90 />
91 )}
92 </Menu.Root>
93 </EventStopper>
94 )
95}
96
97PostMenuButton = memo(PostMenuButton)
98export {PostMenuButton}