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