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