this repo has no description
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 {atoms as a} from '#/alf'
16import {Admonition} from '#/components/Admonition'
17import {useDialogControl} from '#/components/Dialog'
18import {SendViaChatDialog} from '#/components/dms/dialogs/ShareViaChatDialog'
19import {ArrowOutOfBoxModified_Stroke2_Corner2_Rounded as ArrowOutOfBoxIcon} from '#/components/icons/ArrowOutOfBox'
20import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
21import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard'
22import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane'
23import * as Menu from '#/components/Menu'
24import * as Toast from '#/components/Toast'
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`), {
75 type: 'success',
76 })
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 return (
96 <>
97 <Menu.Outer>
98 {hasSession && aa.state.access === aa.Access.Full && (
99 <Menu.Group>
100 <Menu.ContainerItem>
101 <RecentChats postUri={postUri} />
102 </Menu.ContainerItem>
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={PaperPlaneIcon} position="right" />
114 </Menu.Item>
115 </Menu.Group>
116 )}
117
118 <Menu.Group>
119 <Menu.Item
120 testID="postDropdownShareBtn"
121 label={_(msg`Share via...`)}
122 onPress={onSharePost}>
123 <Menu.ItemText>
124 <Trans>Share via...</Trans>
125 </Menu.ItemText>
126 <Menu.ItemIcon icon={ArrowOutOfBoxIcon} position="right" />
127 </Menu.Item>
128
129 <Menu.Item
130 testID="postDropdownShareBtn"
131 label={_(msg`Copy link to post`)}
132 onPress={onCopyLink}>
133 <Menu.ItemText>
134 <Trans>Copy link to post</Trans>
135 </Menu.ItemText>
136 <Menu.ItemIcon icon={ChainLinkIcon} position="right" />
137 </Menu.Item>
138 </Menu.Group>
139
140 {hideInPWI && (
141 <Menu.Group>
142 <Menu.ContainerItem>
143 <Admonition
144 type="warning"
145 style={[a.flex_1, a.border_0, a.p_0, a.bg_transparent]}>
146 <Trans>This post is only visible to logged-in users.</Trans>
147 </Admonition>
148 </Menu.ContainerItem>
149 </Menu.Group>
150 )}
151
152 {devModeEnabled && (
153 <Menu.Group>
154 <Menu.Item
155 testID="postAtUriShareBtn"
156 label={_(msg`Share post at:// URI`)}
157 onPress={onShareATURI}>
158 <Menu.ItemText>
159 <Trans>Share post at:// URI</Trans>
160 </Menu.ItemText>
161 <Menu.ItemIcon icon={ClipboardIcon} position="right" />
162 </Menu.Item>
163 <Menu.Item
164 testID="postAuthorDIDShareBtn"
165 label={_(msg`Share author DID`)}
166 onPress={onShareAuthorDID}>
167 <Menu.ItemText>
168 <Trans>Share author DID</Trans>
169 </Menu.ItemText>
170 <Menu.ItemIcon icon={ClipboardIcon} position="right" />
171 </Menu.Item>
172 </Menu.Group>
173 )}
174 </Menu.Outer>
175
176 <SendViaChatDialog
177 control={sendViaChatControl}
178 onSelectChat={onSelectChatToShareTo}
179 />
180 </>
181 )
182}
183ShareMenuItems = memo(ShareMenuItems)
184export {ShareMenuItems}