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