diff --git a/src/lib/sharing.ts b/src/lib/sharing.ts new file mode 100644 index 00000000..95ebf8ee --- /dev/null +++ b/src/lib/sharing.ts @@ -0,0 +1,22 @@ +import {isNative} from 'platform/detection' +// 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' + +/** + * This function shares a URL using the native Share API if available, or copies it to the clipboard + * and displays a toast message if not (mostly on web) + * @param {string} url - A string representing the URL that needs to be shared or copied to the + * clipboard. + */ +export async function shareUrl(url: string) { + if (isNative) { + Share.share({url: url}) + } else { + // React Native Share is not supported by web. Web Share API + // has increasing but not full support, so default to clipboard + Clipboard.setString(url) + Toast.show('Copied to clipboard') + } +} diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx index e7597608..c295b271 100644 --- a/src/view/com/profile/ProfileHeader.tsx +++ b/src/view/com/profile/ProfileHeader.tsx @@ -1,7 +1,6 @@ import React from 'react' import {observer} from 'mobx-react-lite' import { - Share, StyleSheet, TouchableOpacity, TouchableWithoutFeedback, @@ -31,9 +30,9 @@ import {ProfileHeaderLabels} from '../util/moderation/ProfileHeaderLabels' import {usePalette} from 'lib/hooks/usePalette' import {useAnalytics} from 'lib/analytics' import {NavigationProp} from 'lib/routes/types' -import {isAndroid, isDesktopWeb, isIOS} from 'platform/detection' +import {isDesktopWeb} from 'platform/detection' import {FollowState} from 'state/models/cache/my-follows' -import Clipboard from '@react-native-clipboard/clipboard' +import {shareUrl} from 'lib/sharing' const BACK_HITSLOP = {left: 30, top: 30, right: 30, bottom: 30} @@ -152,15 +151,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoaded({ const onPressShare = React.useCallback(async () => { track('ProfileHeader:ShareButtonClicked') const url = toShareUrl(`/profile/${view.handle}`) - - if (isIOS || isAndroid) { - Share.share({url}) - } else { - // React Native Share is not supported by web. Web Share API - // has increasing but not full support, so default to clipboard - Clipboard.setString(url) - Toast.show('Copied to clipboard') - } + shareUrl(url) }, [track, view]) const onPressMuteAccount = React.useCallback(async () => { diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx index fcb20900..725d45c1 100644 --- a/src/view/com/util/forms/DropdownButton.tsx +++ b/src/view/com/util/forms/DropdownButton.tsx @@ -1,7 +1,6 @@ import React, {useRef} from 'react' import { Dimensions, - Share, StyleProp, StyleSheet, TouchableOpacity, @@ -19,10 +18,8 @@ import {toShareUrl} from 'lib/strings/url-helpers' import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' -import {isAndroid, isIOS} from 'platform/detection' -import Clipboard from '@react-native-clipboard/clipboard' -import * as Toast from '../../util/Toast' import {isWeb} from 'platform/detection' +import {shareUrl} from 'lib/sharing' const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} const ESTIMATED_BTN_HEIGHT = 50 @@ -182,15 +179,7 @@ export function PostDropdownBtn({ label: 'Share...', onPress() { const url = toShareUrl(itemHref) - - if (isIOS || isAndroid) { - Share.share({url}) - } else { - // React Native Share is not supported by web. Web Share API - // has increasing but not full support, so default to clipboard - Clipboard.setString(url) - Toast.show('Copied to clipboard') - } + shareUrl(url) }, }, {sep: true},