Skip to content

Commit

Permalink
Open share sheet when long pressing link (#3317)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
mozzius and haileyok authored Apr 4, 2024
1 parent 4d28dcc commit 9f657fb
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 34 deletions.
52 changes: 43 additions & 9 deletions src/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import React from 'react'
import {GestureResponderEvent} from 'react-native'
import {useLinkProps, StackActions} from '@react-navigation/native'
import {sanitizeUrl} from '@braintree/sanitize-url'
import {StackActions, useLinkProps} from '@react-navigation/native'

import {useInteractionState} from '#/components/hooks/useInteractionState'
import {isWeb} from '#/platform/detection'
import {useTheme, web, flatten, TextStyleProp, atoms as a} from '#/alf'
import {Button, ButtonProps} from '#/components/Button'
import {AllNavigatorParams} from '#/lib/routes/types'
import {shareUrl} from '#/lib/sharing'
import {
convertBskyAppUrlIfNeeded,
isExternalUrl,
linkRequiresWarning,
} from '#/lib/strings/url-helpers'
import {isNative, isWeb} from '#/platform/detection'
import {useModalControls} from '#/state/modals'
import {router} from '#/routes'
import {Text, TextProps} from '#/components/Typography'
import {useOpenLink} from 'state/preferences/in-app-browser'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped'
import {atoms as a, flatten, TextStyleProp, useTheme, web} from '#/alf'
import {Button, ButtonProps} from '#/components/Button'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Text, TextProps} from '#/components/Typography'
import {router} from '#/routes'

/**
* Only available within a `Link`, since that inherits from `Button`.
Expand Down Expand Up @@ -60,6 +61,11 @@ type BaseLinkProps = Pick<
* Web-only attribute. Sets `download` attr on web.
*/
download?: string

/**
* Native-only attribute. If true, will open the share sheet on long press.
*/
shareOnLongPress?: boolean
}

export function useLink({
Expand All @@ -68,6 +74,7 @@ export function useLink({
action = 'push',
disableMismatchWarning,
onPress: outerOnPress,
shareOnLongPress,
}: BaseLinkProps & {
displayText: string
}) {
Expand Down Expand Up @@ -157,10 +164,34 @@ export function useLink({
],
)

const handleLongPress = React.useCallback(() => {
const requiresWarning = Boolean(
!disableMismatchWarning &&
displayText &&
isExternal &&
linkRequiresWarning(href, displayText),
)

if (requiresWarning) {
openModal({
name: 'link-warning',
text: displayText,
href: href,
share: true,
})
} else {
shareUrl(href)
}
}, [disableMismatchWarning, displayText, href, isExternal, openModal])

const onLongPress =
isNative && isExternal && shareOnLongPress ? handleLongPress : undefined

return {
isExternal,
href,
onPress,
onLongPress,
}
}

Expand Down Expand Up @@ -229,16 +260,18 @@ export function InlineLink({
download,
selectable,
label,
shareOnLongPress,
...rest
}: InlineLinkProps) {
const t = useTheme()
const stringChildren = typeof children === 'string'
const {href, isExternal, onPress} = useLink({
const {href, isExternal, onPress, onLongPress} = useLink({
to,
displayText: stringChildren ? children : '',
action,
disableMismatchWarning,
onPress: outerOnPress,
shareOnLongPress,
})
const {
state: hovered,
Expand Down Expand Up @@ -270,6 +303,7 @@ export function InlineLink({
]}
role="link"
onPress={download ? undefined : onPress}
onLongPress={onLongPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
onFocus={onFocus}
Expand Down
17 changes: 9 additions & 8 deletions src/components/RichText.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react'
import {RichText as RichTextAPI, AppBskyRichtextFacet} from '@atproto/api'
import {useLingui} from '@lingui/react'
import {AppBskyRichtextFacet, RichText as RichTextAPI} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'

import {atoms as a, TextStyleProp, flatten, useTheme, web, native} from '#/alf'
import {InlineLink} from '#/components/Link'
import {Text, TextProps} from '#/components/Typography'
import {toShortUrl} from 'lib/strings/url-helpers'
import {TagMenu, useTagMenuControl} from '#/components/TagMenu'
import {toShortUrl} from '#/lib/strings/url-helpers'
import {isNative} from '#/platform/detection'
import {atoms as a, flatten, native, TextStyleProp, useTheme, web} from '#/alf'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {InlineLink} from '#/components/Link'
import {TagMenu, useTagMenuControl} from '#/components/TagMenu'
import {Text, TextProps} from '#/components/Typography'

const WORD_WRAP = {wordWrap: 1}

Expand Down Expand Up @@ -105,7 +105,8 @@ export function RichText({
to={link.uri}
style={[...styles, {pointerEvents: 'auto'}]}
// @ts-ignore TODO
dataSet={WORD_WRAP}>
dataSet={WORD_WRAP}
shareOnLongPress>
{toShortUrl(segment.text)}
</InlineLink>,
)
Expand Down
7 changes: 4 additions & 3 deletions src/lib/sharing.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {isIOS, isAndroid} from 'platform/detection'
import {Share} from 'react-native'
// import * as Sharing from 'expo-sharing'
import Clipboard from '@react-native-clipboard/clipboard'
import * as Toast from '../view/com/util/Toast'
import {Share} from 'react-native'

import {isAndroid, isIOS} from 'platform/detection'
import * as Toast from '#/view/com/util/Toast'

/**
* This function shares a URL using the native Share API if available, or copies it to the clipboard
Expand Down
1 change: 1 addition & 0 deletions src/state/modals/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export interface LinkWarningModal {
name: 'link-warning'
text: string
href: string
share?: boolean
}

export interface EmbedConsentModal {
Expand Down
46 changes: 32 additions & 14 deletions src/view/com/modals/LinkWarning.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
import React from 'react'
import {SafeAreaView, StyleSheet, View} from 'react-native'
import {ScrollView} from './util'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
import {s, colors} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {isWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {isPossiblyAUrl, splitApexDomain} from 'lib/strings/url-helpers'
import {Trans, msg} from '@lingui/macro'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'

import {usePalette} from '#/lib/hooks/usePalette'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {shareUrl} from '#/lib/sharing'
import {isPossiblyAUrl, splitApexDomain} from '#/lib/strings/url-helpers'
import {colors, s} from '#/lib/styles'
import {isWeb} from '#/platform/detection'
import {useModalControls} from '#/state/modals'
import {useOpenLink} from '#/state/preferences/in-app-browser'
import {Button} from '#/view/com/util/forms/Button'
import {Text} from '#/view/com/util/text/Text'
import {ScrollView} from './util'

export const snapPoints = ['50%']

export function Component({text, href}: {text: string; href: string}) {
export function Component({
text,
href,
share,
}: {
text: string
href: string
share?: boolean
}) {
const pal = usePalette('default')
const {closeModal} = useModalControls()
const {isMobile} = useWebMediaQueries()
Expand All @@ -26,7 +36,11 @@ export function Component({text, href}: {text: string; href: string}) {

const onPressVisit = () => {
closeModal()
openLink(href)
if (share) {
shareUrl(href)
} else {
openLink(href)
}
}

return (
Expand Down Expand Up @@ -72,9 +86,13 @@ export function Component({text, href}: {text: string; href: string}) {
testID="confirmBtn"
type="primary"
onPress={onPressVisit}
accessibilityLabel={_(msg`Visit Site`)}
accessibilityHint={_(msg`Opens the linked website`)}
label={_(msg`Visit Site`)}
accessibilityLabel={share ? _(msg`Share Link`) : _(msg`Visit Site`)}
accessibilityHint={
share
? _(msg`Shares the linked website`)
: _(msg`Opens the linked website`)
}
label={share ? _(msg`Share Link`) : _(msg`Visit Site`)}
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
Expand Down

0 comments on commit 9f657fb

Please sign in to comment.