Bluesky app fork with some witchin' additions 馃挮
at post-text-option 100 lines 3.0 kB view raw
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 {useTerminology} from '#/lib/hooks/useTerminology' 14import {EventStopper} from '#/view/com/util/EventStopper' 15import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid' 16import {useMenuControl} from '#/components/Menu' 17import * as Menu from '#/components/Menu' 18import {PostControlButton, PostControlButtonIcon} from '../PostControlButton' 19import {PostMenuItems} from './PostMenuItems' 20 21let PostMenuButton = ({ 22 testID, 23 post, 24 postFeedContext, 25 postReqId, 26 big, 27 record, 28 richText, 29 timestamp, 30 threadgateRecord, 31 onShowLess, 32 hitSlop, 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}): React.ReactNode => { 46 const {_} = useLingui() 47 const terminology = useTerminology() 48 49 const menuControl = useMenuControl() 50 const [hasBeenOpen, setHasBeenOpen] = useState(false) 51 const lazyMenuControl = useMemo( 52 () => ({ 53 ...menuControl, 54 open() { 55 setHasBeenOpen(true) 56 // HACK. We need the state update to be flushed by the time 57 // menuControl.open() fires but RN doesn't expose flushSync. 58 setTimeout(menuControl.open) 59 }, 60 }), 61 [menuControl, setHasBeenOpen], 62 ) 63 return ( 64 <EventStopper onKeyDown={false}> 65 <Menu.Root control={lazyMenuControl}> 66 <Menu.Trigger label={_(msg`Open ${_(terminology.post)} options menu`)}> 67 {({props}) => { 68 return ( 69 <PostControlButton 70 testID="postDropdownBtn" 71 big={big} 72 label={props.accessibilityLabel} 73 {...props} 74 hitSlop={hitSlop}> 75 <PostControlButtonIcon icon={DotsHorizontal} /> 76 </PostControlButton> 77 ) 78 }} 79 </Menu.Trigger> 80 {hasBeenOpen && ( 81 // Lazily initialized. Once mounted, they stay mounted. 82 <PostMenuItems 83 testID={testID} 84 post={post} 85 postFeedContext={postFeedContext} 86 postReqId={postReqId} 87 record={record} 88 richText={richText} 89 timestamp={timestamp} 90 threadgateRecord={threadgateRecord} 91 onShowLess={onShowLess} 92 /> 93 )} 94 </Menu.Root> 95 </EventStopper> 96 ) 97} 98 99PostMenuButton = memo(PostMenuButton) 100export {PostMenuButton}