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