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