Skip to content

Commit

Permalink
Add dev mode for easy copying of at:// URIs and DIDs (#7723)
Browse files Browse the repository at this point in the history
* Add dev mode for easy copying at:// URIs and DIDs

* Use storage API

* Share text instead of URL

* Cleanup persisted schema

* Change translation msg
  • Loading branch information
tom-sherman authored Feb 13, 2025
1 parent db25f95 commit d56efe2
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 2 deletions.
16 changes: 16 additions & 0 deletions src/lib/sharing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
}
}
11 changes: 11 additions & 0 deletions src/screens/Settings/AboutSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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>
Expand Down Expand Up @@ -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}`,
Expand Down
9 changes: 9 additions & 0 deletions src/state/preferences/dev-mode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {device, useStorage} from '#/storage'

export function useDevModeEnabled() {
const [devModeEnabled = false, setDevModeEnabled] = useStorage(device, [
'devMode',
])

return [devModeEnabled, setDevModeEnabled] as const
}
1 change: 1 addition & 0 deletions src/storage/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type Device = {
countryCode: string | undefined
}
trendingBetaEnabled: boolean
devMode: boolean
}

export type Account = {
Expand Down
37 changes: 36 additions & 1 deletion src/view/com/profile/ProfileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>

Expand Down
34 changes: 33 additions & 1 deletion src/view/com/util/forms/PostDropdownBtnMenuItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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,
Expand Down Expand Up @@ -122,6 +123,7 @@ let PostDropdownMenuItems = ({
const hideReplyConfirmControl = useDialogControl()
const {mutateAsync: toggleReplyVisibility} =
useToggleReplyVisibilityMutation()
const [devModeEnabled] = useDevModeEnabled()

const postUri = post.uri
const postCid = post.cid
Expand Down Expand Up @@ -366,6 +368,14 @@ let PostDropdownMenuItems = ({
}
}, [_, queueBlock])

const onShareATURI = useCallback(() => {
shareText(postUri)
}, [postUri])

const onShareAuthorDID = useCallback(() => {
shareText(postAuthor.did)
}, [postAuthor.did])

return (
<>
<Menu.Outer>
Expand Down Expand Up @@ -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>
Expand Down

0 comments on commit d56efe2

Please sign in to comment.