diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx index f683c39c6..dcf2479df 100644 --- a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx +++ b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx @@ -5,6 +5,7 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' +import {useOpenLink} from '#/lib/hooks/useOpenLink' import {makeProfileLink} from '#/lib/routes/links' import {type NavigationProp} from '#/lib/routes/types' import {shareText, shareUrl} from '#/lib/sharing' @@ -13,6 +14,7 @@ import {logger} from '#/logger' import {isIOS} from '#/platform/detection' import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance' import {useProfileShadow} from '#/state/cache/profile-shadow' +import {useShowExternalShareButtons} from '#/state/preferences/external-share-buttons' import {useSession} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' @@ -23,6 +25,7 @@ import {ArrowOutOfBoxModified_Stroke2_Corner2_Rounded as ArrowOutOfBoxIcon} from import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink' import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane' +import {SquareArrowTopRight_Stroke2_Corner0_Rounded as ExternalIcon} from '#/components/icons/SquareArrowTopRight' import * as Menu from '#/components/Menu' import {useDevMode} from '#/storage/hooks/dev-mode' import {RecentChats} from './RecentChats' @@ -38,6 +41,7 @@ let ShareMenuItems = ({ const sendViaChatControl = useDialogControl() const [devModeEnabled] = useDevMode() const {isAgeRestricted} = useAgeAssurance() + const openLink = useOpenLink() const postUri = post.uri const postAuthor = useProfileShadow(post.author) @@ -108,6 +112,18 @@ let ShareMenuItems = ({ shareText(postAuthor.did) } + const showExternalShareButtons = useShowExternalShareButtons() + const isBridgyPost = !!post.record.bridgyOriginalUrl + const bridgyOriginalUrl = post.record.bridgyOriginalUrl as string | undefined + + const onOpenOriginalPost = () => { + bridgyOriginalUrl && openLink(bridgyOriginalUrl, true) + } + + const onOpenPostInPdsls = () => { + openLink(`https://pdsls.dev/${post.uri}`, true) + } + return ( <> @@ -131,6 +147,32 @@ let ShareMenuItems = ({ )} + {showExternalShareButtons && ( + + {isBridgyPost && ( + + + Open original post + + + + )} + + + + Open post in pdsls + + + + + )} + { + bridgyOriginalUrl && openLink(bridgyOriginalUrl, true) + } + + const onOpenPostInPdsls = () => { + openLink(`https://pdsls.dev/${post.uri}`, true) + } + const copyLinkItem = ( {copyLinkItem} + {showExternalShareButtons && isBridgyPost && ( + + + Open original post + + + + )} + + {showExternalShareButtons && ( + + + Open post in pdsls + + + + )} + {hasSession && !isAgeRestricted && ( + + + + Bridging and Fediverse + + setShowExternalShareButtons(value)} + style={[a.w_full]}> + + + Show "Open original post" and "Open post in pdsls" buttons + + + + + + diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index 79e2d0185..79b5ce7b8 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -149,6 +149,8 @@ const schema = z.object({ .optional(), highQualityImages: z.boolean().optional(), + showExternalShareButtons: z.boolean().optional(), + /** @deprecated */ mutedThreads: z.array(z.string()), trendingDisabled: z.boolean().optional(), @@ -240,6 +242,7 @@ export const defaults: Schema = { ], }, highQualityImages: false, + showExternalShareButtons: false, } export function tryParse(rawData: string): Schema | undefined { diff --git a/src/state/preferences/external-share-buttons.tsx b/src/state/preferences/external-share-buttons.tsx new file mode 100644 index 000000000..4bb8718ff --- /dev/null +++ b/src/state/preferences/external-share-buttons.tsx @@ -0,0 +1,54 @@ +import React from 'react' + +import * as persisted from '#/state/persisted' + +type StateContext = persisted.Schema['showExternalShareButtons'] +type SetContext = (v: persisted.Schema['showExternalShareButtons']) => void + +const stateContext = React.createContext( + persisted.defaults.showExternalShareButtons, +) +const setContext = React.createContext( + (_: persisted.Schema['showExternalShareButtons']) => {}, +) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState( + persisted.get('showExternalShareButtons'), + ) + + const setStateWrapped = React.useCallback( + ( + showExternalShareButtons: persisted.Schema['showExternalShareButtons'], + ) => { + setState(showExternalShareButtons) + persisted.write('showExternalShareButtons', showExternalShareButtons) + }, + [setState], + ) + + React.useEffect(() => { + return persisted.onUpdate( + 'showExternalShareButtons', + nextShowExternalShareButtons => { + setState(nextShowExternalShareButtons) + }, + ) + }, [setStateWrapped]) + + return ( + + + {children} + + + ) +} + +export function useShowExternalShareButtons() { + return React.useContext(stateContext) +} + +export function useSetShowExternalShareButtons() { + return React.useContext(setContext) +} diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index 83fd5acd4..a4ab04eee 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -14,6 +14,7 @@ import {Provider as DisableRepostsMetricsProvider} from './disable-reposts-metri import {Provider as DisableSavesMetricsProvider} from './disable-saves-metrics' import {Provider as DisableViaRepostNotificationProvider} from './disable-via-repost-notification' import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs' +import {Provider as ExternalShareButtonsProvider} from './external-share-buttons' import {Provider as GoLinksProvider} from './go-links-enabled' import {Provider as HiddenPostsProvider} from './hidden-posts' import {Provider as HideFeedsPromoTabProvider} from './hide-feeds-promo-tab' @@ -55,25 +56,26 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return ( - + + - - + + - - - + + + - - - - - - - + + + + + + + @@ -94,24 +96,25 @@ export function Provider({children}: React.PropsWithChildren<{}>) { - - - - - - + + + + + + - - - + + + - - + + - + + )