mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

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

Open share sheet when long pressing link (#3317)

* uitextview use library w/ fixes

bump

bump

multiple uitextview fixes

* bump

* Open share sheet on link long press

* rm package manager field

* add link warning to longpress

---------

Co-authored-by: Hailey <me@haileyok.com>

authored by samuel.fm

Hailey and committed by
GitHub
9f657fba 4d28dcc4

+89 -34
+43 -9
src/components/Link.tsx
··· 1 1 import React from 'react' 2 2 import {GestureResponderEvent} from 'react-native' 3 - import {useLinkProps, StackActions} from '@react-navigation/native' 4 3 import {sanitizeUrl} from '@braintree/sanitize-url' 4 + import {StackActions, useLinkProps} from '@react-navigation/native' 5 5 6 - import {useInteractionState} from '#/components/hooks/useInteractionState' 7 - import {isWeb} from '#/platform/detection' 8 - import {useTheme, web, flatten, TextStyleProp, atoms as a} from '#/alf' 9 - import {Button, ButtonProps} from '#/components/Button' 10 6 import {AllNavigatorParams} from '#/lib/routes/types' 7 + import {shareUrl} from '#/lib/sharing' 11 8 import { 12 9 convertBskyAppUrlIfNeeded, 13 10 isExternalUrl, 14 11 linkRequiresWarning, 15 12 } from '#/lib/strings/url-helpers' 13 + import {isNative, isWeb} from '#/platform/detection' 16 14 import {useModalControls} from '#/state/modals' 17 - import {router} from '#/routes' 18 - import {Text, TextProps} from '#/components/Typography' 19 - import {useOpenLink} from 'state/preferences/in-app-browser' 15 + import {useOpenLink} from '#/state/preferences/in-app-browser' 20 16 import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped' 17 + import {atoms as a, flatten, TextStyleProp, useTheme, web} from '#/alf' 18 + import {Button, ButtonProps} from '#/components/Button' 19 + import {useInteractionState} from '#/components/hooks/useInteractionState' 20 + import {Text, TextProps} from '#/components/Typography' 21 + import {router} from '#/routes' 21 22 22 23 /** 23 24 * Only available within a `Link`, since that inherits from `Button`. ··· 60 61 * Web-only attribute. Sets `download` attr on web. 61 62 */ 62 63 download?: string 64 + 65 + /** 66 + * Native-only attribute. If true, will open the share sheet on long press. 67 + */ 68 + shareOnLongPress?: boolean 63 69 } 64 70 65 71 export function useLink({ ··· 68 74 action = 'push', 69 75 disableMismatchWarning, 70 76 onPress: outerOnPress, 77 + shareOnLongPress, 71 78 }: BaseLinkProps & { 72 79 displayText: string 73 80 }) { ··· 157 164 ], 158 165 ) 159 166 167 + const handleLongPress = React.useCallback(() => { 168 + const requiresWarning = Boolean( 169 + !disableMismatchWarning && 170 + displayText && 171 + isExternal && 172 + linkRequiresWarning(href, displayText), 173 + ) 174 + 175 + if (requiresWarning) { 176 + openModal({ 177 + name: 'link-warning', 178 + text: displayText, 179 + href: href, 180 + share: true, 181 + }) 182 + } else { 183 + shareUrl(href) 184 + } 185 + }, [disableMismatchWarning, displayText, href, isExternal, openModal]) 186 + 187 + const onLongPress = 188 + isNative && isExternal && shareOnLongPress ? handleLongPress : undefined 189 + 160 190 return { 161 191 isExternal, 162 192 href, 163 193 onPress, 194 + onLongPress, 164 195 } 165 196 } 166 197 ··· 229 260 download, 230 261 selectable, 231 262 label, 263 + shareOnLongPress, 232 264 ...rest 233 265 }: InlineLinkProps) { 234 266 const t = useTheme() 235 267 const stringChildren = typeof children === 'string' 236 - const {href, isExternal, onPress} = useLink({ 268 + const {href, isExternal, onPress, onLongPress} = useLink({ 237 269 to, 238 270 displayText: stringChildren ? children : '', 239 271 action, 240 272 disableMismatchWarning, 241 273 onPress: outerOnPress, 274 + shareOnLongPress, 242 275 }) 243 276 const { 244 277 state: hovered, ··· 270 303 ]} 271 304 role="link" 272 305 onPress={download ? undefined : onPress} 306 + onLongPress={onLongPress} 273 307 onPressIn={onPressIn} 274 308 onPressOut={onPressOut} 275 309 onFocus={onFocus}
+9 -8
src/components/RichText.tsx
··· 1 1 import React from 'react' 2 - import {RichText as RichTextAPI, AppBskyRichtextFacet} from '@atproto/api' 3 - import {useLingui} from '@lingui/react' 2 + import {AppBskyRichtextFacet, RichText as RichTextAPI} from '@atproto/api' 4 3 import {msg} from '@lingui/macro' 4 + import {useLingui} from '@lingui/react' 5 5 6 - import {atoms as a, TextStyleProp, flatten, useTheme, web, native} from '#/alf' 7 - import {InlineLink} from '#/components/Link' 8 - import {Text, TextProps} from '#/components/Typography' 9 - import {toShortUrl} from 'lib/strings/url-helpers' 10 - import {TagMenu, useTagMenuControl} from '#/components/TagMenu' 6 + import {toShortUrl} from '#/lib/strings/url-helpers' 11 7 import {isNative} from '#/platform/detection' 8 + import {atoms as a, flatten, native, TextStyleProp, useTheme, web} from '#/alf' 12 9 import {useInteractionState} from '#/components/hooks/useInteractionState' 10 + import {InlineLink} from '#/components/Link' 11 + import {TagMenu, useTagMenuControl} from '#/components/TagMenu' 12 + import {Text, TextProps} from '#/components/Typography' 13 13 14 14 const WORD_WRAP = {wordWrap: 1} 15 15 ··· 105 105 to={link.uri} 106 106 style={[...styles, {pointerEvents: 'auto'}]} 107 107 // @ts-ignore TODO 108 - dataSet={WORD_WRAP}> 108 + dataSet={WORD_WRAP} 109 + shareOnLongPress> 109 110 {toShortUrl(segment.text)} 110 111 </InlineLink>, 111 112 )
+4 -3
src/lib/sharing.ts
··· 1 - import {isIOS, isAndroid} from 'platform/detection' 1 + import {Share} from 'react-native' 2 2 // import * as Sharing from 'expo-sharing' 3 3 import Clipboard from '@react-native-clipboard/clipboard' 4 - import * as Toast from '../view/com/util/Toast' 5 - import {Share} from 'react-native' 4 + 5 + import {isAndroid, isIOS} from 'platform/detection' 6 + import * as Toast from '#/view/com/util/Toast' 6 7 7 8 /** 8 9 * This function shares a URL using the native Share API if available, or copies it to the clipboard
+1
src/state/modals/index.tsx
··· 122 122 name: 'link-warning' 123 123 text: string 124 124 href: string 125 + share?: boolean 125 126 } 126 127 127 128 export interface EmbedConsentModal {
+32 -14
src/view/com/modals/LinkWarning.tsx
··· 1 1 import React from 'react' 2 2 import {SafeAreaView, StyleSheet, View} from 'react-native' 3 - import {ScrollView} from './util' 4 3 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 - import {Text} from '../util/text/Text' 6 - import {Button} from '../util/forms/Button' 7 - import {s, colors} from 'lib/styles' 8 - import {usePalette} from 'lib/hooks/usePalette' 9 - import {isWeb} from 'platform/detection' 10 - import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 11 - import {isPossiblyAUrl, splitApexDomain} from 'lib/strings/url-helpers' 12 - import {Trans, msg} from '@lingui/macro' 4 + import {msg, Trans} from '@lingui/macro' 13 5 import {useLingui} from '@lingui/react' 6 + 7 + import {usePalette} from '#/lib/hooks/usePalette' 8 + import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 9 + import {shareUrl} from '#/lib/sharing' 10 + import {isPossiblyAUrl, splitApexDomain} from '#/lib/strings/url-helpers' 11 + import {colors, s} from '#/lib/styles' 12 + import {isWeb} from '#/platform/detection' 14 13 import {useModalControls} from '#/state/modals' 15 14 import {useOpenLink} from '#/state/preferences/in-app-browser' 15 + import {Button} from '#/view/com/util/forms/Button' 16 + import {Text} from '#/view/com/util/text/Text' 17 + import {ScrollView} from './util' 16 18 17 19 export const snapPoints = ['50%'] 18 20 19 - export function Component({text, href}: {text: string; href: string}) { 21 + export function Component({ 22 + text, 23 + href, 24 + share, 25 + }: { 26 + text: string 27 + href: string 28 + share?: boolean 29 + }) { 20 30 const pal = usePalette('default') 21 31 const {closeModal} = useModalControls() 22 32 const {isMobile} = useWebMediaQueries() ··· 26 36 27 37 const onPressVisit = () => { 28 38 closeModal() 29 - openLink(href) 39 + if (share) { 40 + shareUrl(href) 41 + } else { 42 + openLink(href) 43 + } 30 44 } 31 45 32 46 return ( ··· 72 86 testID="confirmBtn" 73 87 type="primary" 74 88 onPress={onPressVisit} 75 - accessibilityLabel={_(msg`Visit Site`)} 76 - accessibilityHint={_(msg`Opens the linked website`)} 77 - label={_(msg`Visit Site`)} 89 + accessibilityLabel={share ? _(msg`Share Link`) : _(msg`Visit Site`)} 90 + accessibilityHint={ 91 + share 92 + ? _(msg`Shares the linked website`) 93 + : _(msg`Opens the linked website`) 94 + } 95 + label={share ? _(msg`Share Link`) : _(msg`Visit Site`)} 78 96 labelContainerStyle={{justifyContent: 'center', padding: 4}} 79 97 labelStyle={[s.f18]} 80 98 />