tangled mirror of catsky-馃惐 Soothing soft social-app fork with all the niche toggles! (Unofficial); for issues and PRs please put them on github:NekoDrone/catsky-social
15
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 224 lines 7.7 kB view raw
1import {memo, useMemo} from 'react' 2import * as ExpoClipboard from 'expo-clipboard' 3import {AtUri} from '@atproto/api' 4import {msg, Trans} from '@lingui/macro' 5import {useLingui} from '@lingui/react' 6import {useNavigation} from '@react-navigation/native' 7 8import {useOpenLink} from '#/lib/hooks/useOpenLink' 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 {logger} from '#/logger' 14import {isIOS} from '#/platform/detection' 15import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance' 16import {useProfileShadow} from '#/state/cache/profile-shadow' 17import {useShowExternalShareButtons} from '#/state/preferences/external-share-buttons' 18import {useSession} from '#/state/session' 19import * as Toast from '#/view/com/util/Toast' 20import {atoms as a} from '#/alf' 21import {Admonition} from '#/components/Admonition' 22import {useDialogControl} from '#/components/Dialog' 23import {SendViaChatDialog} from '#/components/dms/dialogs/ShareViaChatDialog' 24import {ArrowOutOfBoxModified_Stroke2_Corner2_Rounded as ArrowOutOfBoxIcon} from '#/components/icons/ArrowOutOfBox' 25import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink' 26import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard' 27import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane' 28import {SquareArrowTopRight_Stroke2_Corner0_Rounded as ExternalIcon} from '#/components/icons/SquareArrowTopRight' 29import * as Menu from '#/components/Menu' 30import {useDevMode} from '#/storage/hooks/dev-mode' 31import {RecentChats} from './RecentChats' 32import {type ShareMenuItemsProps} from './ShareMenuItems.types' 33 34let ShareMenuItems = ({ 35 post, 36 onShare: onShareProp, 37}: ShareMenuItemsProps): React.ReactNode => { 38 const {hasSession} = useSession() 39 const {_} = useLingui() 40 const navigation = useNavigation<NavigationProp>() 41 const sendViaChatControl = useDialogControl() 42 const [devModeEnabled] = useDevMode() 43 const {isAgeRestricted} = useAgeAssurance() 44 const openLink = useOpenLink() 45 46 const postUri = post.uri 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 onSharePost = () => { 61 logger.metric('share:press:nativeShare', {}, {statsig: true}) 62 const url = toShareUrl(href) 63 shareUrl(url) 64 onShareProp() 65 } 66 67 const onCopyLink = async () => { 68 logger.metric('share:press:copyLink', {}, {statsig: true}) 69 const url = toShareUrl(href) 70 if (isIOS) { 71 // iOS only 72 await ExpoClipboard.setUrlAsync(url) 73 } else { 74 await ExpoClipboard.setStringAsync(url) 75 } 76 Toast.show(_(msg`Copied to clipboard`), 'clipboard-check') 77 onShareProp() 78 } 79 80 const onSelectChatToShareTo = (conversation: string) => { 81 navigation.navigate('MessagesConversation', { 82 conversation, 83 embed: postUri, 84 }) 85 } 86 87 const onShareATURI = () => { 88 shareText(postUri) 89 } 90 91 const onShareAuthorDID = () => { 92 shareText(postAuthor.did) 93 } 94 95 const showExternalShareButtons = useShowExternalShareButtons() 96 const isBridgedPost = 97 !!post.record.bridgyOriginalUrl || !!post.record.fediverseId 98 const originalPostUrl = (post.record.bridgyOriginalUrl || 99 post.record.fediverseId) as string | undefined 100 101 const onOpenOriginalPost = () => { 102 originalPostUrl && openLink(originalPostUrl, true) 103 } 104 105 const onOpenPostInPdsls = () => { 106 openLink(`https://pdsls.dev/${post.uri}`, true) 107 } 108 109 return ( 110 <> 111 <Menu.Outer> 112 {hasSession && !isAgeRestricted && ( 113 <Menu.Group> 114 <Menu.ContainerItem> 115 <RecentChats postUri={postUri} /> 116 </Menu.ContainerItem> 117 <Menu.Item 118 testID="postDropdownSendViaDMBtn" 119 label={_(msg`Send via direct message`)} 120 onPress={() => { 121 logger.metric('share:press:openDmSearch', {}, {statsig: true}) 122 sendViaChatControl.open() 123 }}> 124 <Menu.ItemText> 125 <Trans>Send via direct message</Trans> 126 </Menu.ItemText> 127 <Menu.ItemIcon icon={PaperPlaneIcon} position="right" /> 128 </Menu.Item> 129 </Menu.Group> 130 )} 131 132 {showExternalShareButtons && ( 133 <Menu.Group> 134 {isBridgedPost && ( 135 <Menu.Item 136 testID="postDropdownOpenOriginalPost" 137 label={_(msg`Open original post`)} 138 onPress={onOpenOriginalPost}> 139 <Menu.ItemText> 140 <Trans>Open original post</Trans> 141 </Menu.ItemText> 142 <Menu.ItemIcon icon={ExternalIcon} position="right" /> 143 </Menu.Item> 144 )} 145 146 <Menu.Item 147 testID="postDropdownOpenInPdsls" 148 label={_(msg`Open post in PDSls`)} 149 onPress={onOpenPostInPdsls}> 150 <Menu.ItemText> 151 <Trans>Open post in PDSls</Trans> 152 </Menu.ItemText> 153 <Menu.ItemIcon icon={ExternalIcon} position="right" /> 154 </Menu.Item> 155 </Menu.Group> 156 )} 157 158 <Menu.Group> 159 <Menu.Item 160 testID="postDropdownShareBtn" 161 label={_(msg`Share via...`)} 162 onPress={onSharePost}> 163 <Menu.ItemText> 164 <Trans>Share via...</Trans> 165 </Menu.ItemText> 166 <Menu.ItemIcon icon={ArrowOutOfBoxIcon} position="right" /> 167 </Menu.Item> 168 169 <Menu.Item 170 testID="postDropdownShareBtn" 171 label={_(msg`Copy link to post`)} 172 onPress={onCopyLink}> 173 <Menu.ItemText> 174 <Trans>Copy link to post</Trans> 175 </Menu.ItemText> 176 <Menu.ItemIcon icon={ChainLinkIcon} position="right" /> 177 </Menu.Item> 178 </Menu.Group> 179 180 {hideInPWI && ( 181 <Menu.Group> 182 <Menu.ContainerItem> 183 <Admonition 184 type="warning" 185 style={[a.flex_1, a.border_0, a.p_0, a.bg_transparent]}> 186 <Trans>This post is only visible to logged-in users.</Trans> 187 </Admonition> 188 </Menu.ContainerItem> 189 </Menu.Group> 190 )} 191 192 {devModeEnabled && ( 193 <Menu.Group> 194 <Menu.Item 195 testID="postAtUriShareBtn" 196 label={_(msg`Share post at:// URI`)} 197 onPress={onShareATURI}> 198 <Menu.ItemText> 199 <Trans>Share post at:// URI</Trans> 200 </Menu.ItemText> 201 <Menu.ItemIcon icon={ClipboardIcon} position="right" /> 202 </Menu.Item> 203 <Menu.Item 204 testID="postAuthorDIDShareBtn" 205 label={_(msg`Share author DID`)} 206 onPress={onShareAuthorDID}> 207 <Menu.ItemText> 208 <Trans>Share author DID</Trans> 209 </Menu.ItemText> 210 <Menu.ItemIcon icon={ClipboardIcon} position="right" /> 211 </Menu.Item> 212 </Menu.Group> 213 )} 214 </Menu.Outer> 215 216 <SendViaChatDialog 217 control={sendViaChatControl} 218 onSelectChat={onSelectChatToShareTo} 219 /> 220 </> 221 ) 222} 223ShareMenuItems = memo(ShareMenuItems) 224export {ShareMenuItems}