Bluesky app fork with some witchin' additions 馃挮
at 5ee667f307bc459ba53cdaabdad00a0ea1ee6846 184 lines 5.8 kB view raw
1import {memo, useMemo} from 'react' 2import {AtUri} from '@atproto/api' 3import {msg} from '@lingui/core/macro' 4import {useLingui} from '@lingui/react' 5import {Trans} from '@lingui/react/macro' 6import {useNavigation} from '@react-navigation/native' 7 8import {makeProfileLink} from '#/lib/routes/links' 9import {type NavigationProp} from '#/lib/routes/types' 10import {shareText, shareUrl} from '#/lib/sharing' 11import {toShareUrl} from '#/lib/strings/url-helpers' 12import {useProfileShadow} from '#/state/cache/profile-shadow' 13import {useSession} from '#/state/session' 14import {useBreakpoints} from '#/alf' 15import {useDialogControl} from '#/components/Dialog' 16import {EmbedDialog} from '#/components/dialogs/Embed' 17import {SendViaChatDialog} from '#/components/dms/dialogs/ShareViaChatDialog' 18import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink' 19import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard' 20import {CodeBrackets_Stroke2_Corner0_Rounded as CodeBracketsIcon} from '#/components/icons/CodeBrackets' 21import {PaperPlane_Stroke2_Corner0_Rounded as Send} from '#/components/icons/PaperPlane' 22import * as Menu from '#/components/Menu' 23import {useAgeAssurance} from '#/ageAssurance' 24import {useAnalytics} from '#/analytics' 25import {IS_WEB} from '#/env' 26import {useDevMode} from '#/storage/hooks/dev-mode' 27import {type ShareMenuItemsProps} from './ShareMenuItems.types' 28 29let ShareMenuItems = ({ 30 post, 31 record, 32 timestamp, 33 onShare: onShareProp, 34}: ShareMenuItemsProps): React.ReactNode => { 35 const ax = useAnalytics() 36 const {hasSession} = useSession() 37 const {gtMobile} = useBreakpoints() 38 const {_} = useLingui() 39 const navigation = useNavigation<NavigationProp>() 40 const embedPostControl = useDialogControl() 41 const sendViaChatControl = useDialogControl() 42 const [devModeEnabled] = useDevMode() 43 const aa = useAgeAssurance() 44 45 const postUri = post.uri 46 const postCid = post.cid 47 const postAuthor = useProfileShadow(post.author) 48 49 const href = useMemo(() => { 50 const urip = new AtUri(postUri) 51 return makeProfileLink(postAuthor, 'post', urip.rkey) 52 }, [postUri, postAuthor]) 53 54 const hideInPWI = useMemo(() => { 55 return !!postAuthor.labels?.find( 56 label => label.val === '!no-unauthenticated', 57 ) 58 }, [postAuthor]) 59 60 const onCopyLink = () => { 61 ax.metric('share:press:copyLink', {}) 62 const url = toShareUrl(href) 63 shareUrl(url) 64 onShareProp() 65 } 66 67 const onSelectChatToShareTo = (conversation: string) => { 68 ax.metric('share:press:dmSelected', {}) 69 navigation.navigate('MessagesConversation', { 70 conversation, 71 embed: postUri, 72 }) 73 } 74 75 const canEmbed = IS_WEB && gtMobile && !hideInPWI 76 77 const onShareATURI = () => { 78 shareText(postUri) 79 } 80 81 const onShareAuthorDID = () => { 82 shareText(postAuthor.did) 83 } 84 85 const copyLinkItem = ( 86 <Menu.Item 87 testID="postDropdownShareBtn" 88 label={_(msg`Copy link to post`)} 89 onPress={onCopyLink}> 90 <Menu.ItemText> 91 <Trans>Copy link to post</Trans> 92 </Menu.ItemText> 93 <Menu.ItemIcon icon={ChainLinkIcon} position="right" /> 94 </Menu.Item> 95 ) 96 97 return ( 98 <> 99 <Menu.Outer> 100 {!hideInPWI && copyLinkItem} 101 102 {hasSession && aa.state.access === aa.Access.Full && ( 103 <Menu.Item 104 testID="postDropdownSendViaDMBtn" 105 label={_(msg`Send via direct message`)} 106 onPress={() => { 107 ax.metric('share:press:openDmSearch', {}) 108 sendViaChatControl.open() 109 }}> 110 <Menu.ItemText> 111 <Trans>Send via direct message</Trans> 112 </Menu.ItemText> 113 <Menu.ItemIcon icon={Send} position="right" /> 114 </Menu.Item> 115 )} 116 117 {canEmbed && ( 118 <Menu.Item 119 testID="postDropdownEmbedBtn" 120 label={_(msg`Embed post`)} 121 onPress={() => { 122 ax.metric('share:press:embed', {}) 123 embedPostControl.open() 124 }}> 125 <Menu.ItemText>{_(msg`Embed post`)}</Menu.ItemText> 126 <Menu.ItemIcon icon={CodeBracketsIcon} position="right" /> 127 </Menu.Item> 128 )} 129 130 {hideInPWI && ( 131 <> 132 {hasSession && <Menu.Divider />} 133 {copyLinkItem} 134 <Menu.LabelText style={{maxWidth: 220}}> 135 <Trans>Note: This post is only visible to logged-in users.</Trans> 136 </Menu.LabelText> 137 </> 138 )} 139 140 {devModeEnabled && ( 141 <> 142 <Menu.Divider /> 143 <Menu.Item 144 testID="postAtUriShareBtn" 145 label={_(msg`Copy post at:// URI`)} 146 onPress={onShareATURI}> 147 <Menu.ItemText> 148 <Trans>Copy post at:// URI</Trans> 149 </Menu.ItemText> 150 <Menu.ItemIcon icon={ClipboardIcon} position="right" /> 151 </Menu.Item> 152 <Menu.Item 153 testID="postAuthorDIDShareBtn" 154 label={_(msg`Copy author DID`)} 155 onPress={onShareAuthorDID}> 156 <Menu.ItemText> 157 <Trans>Copy author DID</Trans> 158 </Menu.ItemText> 159 <Menu.ItemIcon icon={ClipboardIcon} position="right" /> 160 </Menu.Item> 161 </> 162 )} 163 </Menu.Outer> 164 165 {canEmbed && ( 166 <EmbedDialog 167 control={embedPostControl} 168 postCid={postCid} 169 postUri={postUri} 170 record={record} 171 postAuthor={postAuthor} 172 timestamp={timestamp} 173 /> 174 )} 175 176 <SendViaChatDialog 177 control={sendViaChatControl} 178 onSelectChat={onSelectChatToShareTo} 179 /> 180 </> 181 ) 182} 183ShareMenuItems = memo(ShareMenuItems) 184export {ShareMenuItems}