diff options
author | Tom Sherman <the.tomsherman@gmail.com> | 2025-02-13 01:11:13 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-13 01:11:13 +0000 |
commit | d56efe250e8b83930d71793c44e6ba58cdecdaf4 (patch) | |
tree | 8cb6557b76e70c7c6b144f1694be9b1f822deb38 | |
parent | db25f95c33121da9d04a02dc2e77929a5d24a5ce (diff) | |
download | voidsky-d56efe250e8b83930d71793c44e6ba58cdecdaf4.tar.zst |
Add dev mode for easy copying of at:// URIs and DIDs (#7723)
* Add dev mode for easy copying at:// URIs and DIDs * Use storage API * Share text instead of URL * Cleanup persisted schema * Change translation msg
-rw-r--r-- | src/lib/sharing.ts | 16 | ||||
-rw-r--r-- | src/screens/Settings/AboutSettings.tsx | 11 | ||||
-rw-r--r-- | src/state/preferences/dev-mode.ts | 9 | ||||
-rw-r--r-- | src/storage/schema.ts | 1 | ||||
-rw-r--r-- | src/view/com/profile/ProfileMenu.tsx | 37 | ||||
-rw-r--r-- | src/view/com/util/forms/PostDropdownBtnMenuItems.tsx | 34 |
6 files changed, 106 insertions, 2 deletions
diff --git a/src/lib/sharing.ts b/src/lib/sharing.ts index c89d2d7a6..cdad6afe5 100644 --- a/src/lib/sharing.ts +++ b/src/lib/sharing.ts @@ -25,3 +25,19 @@ export async function shareUrl(url: string) { Toast.show(t`Copied to clipboard`, 'clipboard-check') } } + +/** + * This function shares a text 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} text - A string representing the text that needs to be shared or copied to the + * clipboard. + */ +export async function shareText(text: string) { + if (isAndroid || isIOS) { + await Share.share({message: text}) + } else { + await setStringAsync(text) + Toast.show(t`Copied to clipboard`, 'clipboard-check') + } +} diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx index 92ba2c1be..4d009281d 100644 --- a/src/screens/Settings/AboutSettings.tsx +++ b/src/screens/Settings/AboutSettings.tsx @@ -7,6 +7,7 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack' import {appVersion, BUNDLE_DATE, bundleInfo} from '#/lib/app-info' import {STATUS_PAGE_URL} from '#/lib/constants' import {CommonNavigatorParams} from '#/lib/routes/types' +import {useDevModeEnabled} from '#/state/preferences/dev-mode' import * as Toast from '#/view/com/util/Toast' import * as SettingsList from '#/screens/Settings/components/SettingsList' import {CodeLines_Stroke2_Corner2_Rounded as CodeLinesIcon} from '#/components/icons/CodeLines' @@ -18,6 +19,7 @@ import * as Layout from '#/components/Layout' type Props = NativeStackScreenProps<CommonNavigatorParams, 'AboutSettings'> export function AboutSettingsScreen({}: Props) { const {_} = useLingui() + const [devModeEnabled, setDevModeEnabled] = useDevModeEnabled() return ( <Layout.Screen> @@ -66,6 +68,15 @@ export function AboutSettingsScreen({}: Props) { <SettingsList.PressableItem label={_(msg`Version ${appVersion}`)} accessibilityHint={_(msg`Copies build version to clipboard`)} + onLongPress={() => { + const newDevModeEnabled = !devModeEnabled + setDevModeEnabled(newDevModeEnabled) + Toast.show( + newDevModeEnabled + ? _(msg`Developer mode enabled`) + : _(msg`Developer mode disabled`), + ) + }} onPress={() => { setStringAsync( `Build version: ${appVersion}; Bundle info: ${bundleInfo}; Bundle date: ${BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}`, diff --git a/src/state/preferences/dev-mode.ts b/src/state/preferences/dev-mode.ts new file mode 100644 index 000000000..ace283895 --- /dev/null +++ b/src/state/preferences/dev-mode.ts @@ -0,0 +1,9 @@ +import {device, useStorage} from '#/storage' + +export function useDevModeEnabled() { + const [devModeEnabled = false, setDevModeEnabled] = useStorage(device, [ + 'devMode', + ]) + + return [devModeEnabled, setDevModeEnabled] as const +} diff --git a/src/storage/schema.ts b/src/storage/schema.ts index 667b43208..0e9b1985c 100644 --- a/src/storage/schema.ts +++ b/src/storage/schema.ts @@ -9,6 +9,7 @@ export type Device = { countryCode: string | undefined } trendingBetaEnabled: boolean + devMode: boolean } export type Account = { diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx index f01fb5e17..770d17f48 100644 --- a/src/view/com/profile/ProfileMenu.tsx +++ b/src/view/com/profile/ProfileMenu.tsx @@ -6,11 +6,12 @@ import {useQueryClient} from '@tanstack/react-query' import {HITSLOP_20} from '#/lib/constants' import {makeProfileLink} from '#/lib/routes/links' -import {shareUrl} from '#/lib/sharing' +import {shareText, shareUrl} from '#/lib/sharing' import {toShareUrl} from '#/lib/strings/url-helpers' import {logger} from '#/logger' import {Shadow} from '#/state/cache/types' import {useModalControls} from '#/state/modals' +import {useDevModeEnabled} from '#/state/preferences/dev-mode' import { RQKEY as profileQueryKey, useProfileBlockMutationQueue, @@ -52,6 +53,7 @@ let ProfileMenu = ({ const isBlocked = profile.viewer?.blocking || profile.viewer?.blockedBy const isFollowingBlockedAccount = isFollowing && isBlocked const isLabelerAndNotBlocked = !!profile.associated?.labeler && !isBlocked + const [devModeEnabled] = useDevModeEnabled() const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) @@ -167,6 +169,14 @@ let ProfileMenu = ({ reportDialogControl.open() }, [reportDialogControl]) + const onPressShareATUri = React.useCallback(() => { + shareText(`at://${profile.did}`) + }, [profile.did]) + + const onPressShareDID = React.useCallback(() => { + shareText(profile.did) + }, [profile.did]) + return ( <EventStopper onKeyDown={false}> <Menu.Root> @@ -308,6 +318,31 @@ let ProfileMenu = ({ </Menu.Group> </> )} + {devModeEnabled ? ( + <> + <Menu.Divider /> + <Menu.Group> + <Menu.Item + testID="profileHeaderDropdownShareATURIBtn" + label={_(msg`Copy at:// URI`)} + onPress={onPressShareATUri}> + <Menu.ItemText> + <Trans>Copy at:// URI</Trans> + </Menu.ItemText> + <Menu.ItemIcon icon={Share} /> + </Menu.Item> + <Menu.Item + testID="profileHeaderDropdownShareDIDBtn" + label={_(msg`Copy DID`)} + onPress={onPressShareDID}> + <Menu.ItemText> + <Trans>Copy DID</Trans> + </Menu.ItemText> + <Menu.ItemIcon icon={Share} /> + </Menu.Item> + </Menu.Group> + </> + ) : null} </Menu.Outer> </Menu.Root> diff --git a/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx b/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx index 149bb9ad2..41f7e74a6 100644 --- a/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx +++ b/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx @@ -21,7 +21,7 @@ import {useOpenLink} from '#/lib/hooks/useOpenLink' import {getCurrentRoute} from '#/lib/routes/helpers' import {makeProfileLink} from '#/lib/routes/links' import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types' -import {shareUrl} from '#/lib/sharing' +import {shareText, shareUrl} from '#/lib/sharing' import {logEvent} from '#/lib/statsig/statsig' import {richTextToString} from '#/lib/strings/rich-text-helpers' import {toShareUrl} from '#/lib/strings/url-helpers' @@ -33,6 +33,7 @@ import {useProfileShadow} from '#/state/cache/profile-shadow' import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useLanguagePrefs} from '#/state/preferences' import {useHiddenPosts, useHiddenPostsApi} from '#/state/preferences' +import {useDevModeEnabled} from '#/state/preferences/dev-mode' import {usePinnedPostMutation} from '#/state/queries/pinned-post' import { usePostDeleteMutation, @@ -122,6 +123,7 @@ let PostDropdownMenuItems = ({ const hideReplyConfirmControl = useDialogControl() const {mutateAsync: toggleReplyVisibility} = useToggleReplyVisibilityMutation() + const [devModeEnabled] = useDevModeEnabled() const postUri = post.uri const postCid = post.cid @@ -366,6 +368,14 @@ let PostDropdownMenuItems = ({ } }, [_, queueBlock]) + const onShareATURI = useCallback(() => { + shareText(postUri) + }, [postUri]) + + const onShareAuthorDID = useCallback(() => { + shareText(postAuthor.did) + }, [postAuthor.did]) + return ( <> <Menu.Outer> @@ -647,6 +657,28 @@ let PostDropdownMenuItems = ({ </> )} </Menu.Group> + + {devModeEnabled ? ( + <> + <Menu.Divider /> + <Menu.Group> + <Menu.Item + testID="postAtUriShareBtn" + label={_(msg`Copy post at:// URI`)} + onPress={onShareATURI}> + <Menu.ItemText>{_(msg`Copy post at:// URI`)}</Menu.ItemText> + <Menu.ItemIcon icon={Share} position="right" /> + </Menu.Item> + <Menu.Item + testID="postAuthorDIDShareBtn" + label={_(msg`Copy author DID`)} + onPress={onShareAuthorDID}> + <Menu.ItemText>{_(msg`Copy author DID`)}</Menu.ItemText> + <Menu.ItemIcon icon={Share} position="right" /> + </Menu.Item> + </Menu.Group> + </> + ) : null} </> )} </Menu.Outer> |