From 0ac15920a477a5c8090fd2b929b36ac0b6e02c34 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 18 Apr 2025 21:15:32 -0500 Subject: [PATCH] Verification (#8226) * WIP * Alignment with icon * Add create/remove prompts * Fill out check dialog a bit * Reorg * Handle was verified state * Add warning to edit profile * Add warning to handle dialog * Decent alignment in posts on all platforms * Refactor alignment for posts, chatlist, hover card * Disable on profile * Convo header * Compute simple verification state * Add other icon, rename, integrate * Swap in simple state for profile edits * Clean up utility hooks * Add verifications UI to dialog * Add edu nux * Revert change * Fix wrapping of check on profile * Rename * Fix gap under PostMeta * Update check dialogs * Handle takendown verifiers in check dialog * alf composer reply to * Refactor verification state * Add create/remove mutations, non-functional for now * Fix up post-rebase * Add check to first author noty * Do cache updates after mutations * DRY up hook, add to profile updates too * Add to drawer * Update account list * Adapt to new types * Hook up mutations * Use profile shadow in feeds * Add to settings * Shadow currentAccountProfile * Add invalid state to verifications * Fix alignment and overflow in Settings and Drawer * Re-integrate post rebase * Remove debug code * Update copy * Add unverified notification support * Remove link * Make sure dialog closes * Update URL * Add settings screen * Integrate new setting into verification states * Add metrics, bump package, fix bad import * NUX fixes * Update copy * Fixes * Update types * fix search autocomplete * fix lint * add display name warning to new dialog * update default prefs * Add parsing support for notifications * Bump pkg * Tweak noty styles * Adjust check alignment * Tweak check alignment * Fix badge for verifier * Modify copy --------- Co-authored-by: Samuel Newman Co-authored-by: Paul Frazee --- .eslintrc.js | 1 + .../circleCheck_stroke2_corner0_rounded.svg | 1 + .../icons/sparkle_stroke2_corner0_rounded.svg | 1 + assets/icons/verifiedCheck.svg | 1 + assets/icons/verifierCheck.svg | 1 + .../initial_verification_announcement_1.png | Bin 0 -> 51326 bytes .../initial_verification_announcement_2.png | Bin 0 -> 85854 bytes bskyweb/cmd/bskyweb/server.go | 1 + package.json | 2 +- src/Navigation.tsx | 9 + src/components/AccountList.tsx | 67 +++-- src/components/Link.tsx | 6 +- src/components/ProfileCard.tsx | 25 +- src/components/ProfileHoverCard/index.web.tsx | 40 ++- src/components/Prompt.tsx | 26 +- src/components/Typography.tsx | 4 +- .../nuxs/InitialVerificationAnnouncement.tsx | 194 +++++++++++++ src/components/dialogs/nuxs/index.tsx | 17 +- src/components/dms/MessagesListHeader.tsx | 49 ++-- src/components/icons/CircleCheck.tsx | 5 + src/components/icons/Sparkle.tsx | 5 + src/components/icons/VerifiedCheck.tsx | 30 ++ src/components/icons/VerifierCheck.tsx | 35 +++ .../verification/VerificationCheck.tsx | 12 + .../verification/VerificationCheckButton.tsx | 155 +++++++++++ .../verification/VerificationCreatePrompt.tsx | 70 +++++ .../verification/VerificationRemovePrompt.tsx | 50 ++++ .../verification/VerificationsDialog.tsx | 257 ++++++++++++++++++ .../verification/VerifierDialog.tsx | 153 +++++++++++ src/components/verification/index.ts | 113 ++++++++ src/lib/constants.ts | 8 + src/lib/getUserDisplayName.ts | 10 + src/lib/routes/types.ts | 1 + src/logger/metrics.ts | 13 + src/routes.ts | 1 + .../Messages/components/ChatListItem.tsx | 49 ++-- .../Moderation/VerificationSettings.tsx | 96 +++++++ src/screens/Moderation/index.tsx | 27 +- .../Profile/Header/EditProfileDialog.tsx | 27 +- .../Profile/Header/ProfileHeaderStandard.tsx | 34 ++- .../Search/components/AutocompleteResults.tsx | 2 +- .../Search/components/SearchHistory.tsx | 136 ++++++--- src/screens/Settings/Settings.tsx | 49 +++- .../components/ChangeHandleDialog.tsx | 23 +- src/state/cache/profile-shadow.ts | 4 + src/state/queries/notifications/util.ts | 26 +- src/state/queries/nuxs/definitions.ts | 6 + src/state/queries/preferences/const.ts | 7 +- src/state/queries/preferences/index.ts | 30 +- src/state/queries/profile.ts | 31 ++- .../queries/useCurrentAccountProfile.tsx | 9 + .../useUpdateProfileVerificationCache.ts | 35 +++ .../useVerificationCreateMutation.tsx | 53 ++++ .../useVerificationsRemoveMutation.tsx | 63 +++++ src/types/bsky/profile.ts | 2 +- src/view/com/composer/ComposerReplyTo.tsx | 110 ++++---- src/view/com/modals/EditProfile.tsx | 32 ++- .../notifications/NotificationFeedItem.tsx | 204 ++++++++++---- src/view/com/post-thread/PostThreadItem.tsx | 44 ++- src/view/com/profile/ProfileMenu.tsx | 52 +++- src/view/com/util/PostMeta.tsx | 175 +++++++----- src/view/shell/Drawer.tsx | 30 +- yarn.lock | 8 +- 63 files changed, 2332 insertions(+), 395 deletions(-) create mode 100644 assets/icons/circleCheck_stroke2_corner0_rounded.svg create mode 100644 assets/icons/sparkle_stroke2_corner0_rounded.svg create mode 100644 assets/icons/verifiedCheck.svg create mode 100644 assets/icons/verifierCheck.svg create mode 100644 assets/images/initial_verification_announcement_1.png create mode 100644 assets/images/initial_verification_announcement_2.png create mode 100644 src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx create mode 100644 src/components/icons/CircleCheck.tsx create mode 100644 src/components/icons/Sparkle.tsx create mode 100644 src/components/icons/VerifiedCheck.tsx create mode 100644 src/components/icons/VerifierCheck.tsx create mode 100644 src/components/verification/VerificationCheck.tsx create mode 100644 src/components/verification/VerificationCheckButton.tsx create mode 100644 src/components/verification/VerificationCreatePrompt.tsx create mode 100644 src/components/verification/VerificationRemovePrompt.tsx create mode 100644 src/components/verification/VerificationsDialog.tsx create mode 100644 src/components/verification/VerifierDialog.tsx create mode 100644 src/components/verification/index.ts create mode 100644 src/lib/getUserDisplayName.ts create mode 100644 src/screens/Moderation/VerificationSettings.tsx create mode 100644 src/state/queries/useCurrentAccountProfile.tsx create mode 100644 src/state/queries/verification/useUpdateProfileVerificationCache.ts create mode 100644 src/state/queries/verification/useVerificationCreateMutation.tsx create mode 100644 src/state/queries/verification/useVerificationsRemoveMutation.tsx diff --git a/.eslintrc.js b/.eslintrc.js index 44f3edfd1..726cc5607 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ module.exports = { 'P', 'Admonition', 'Admonition.Admonition', + 'Span', ], impliedTextProps: [], suggestedTextWrappers: { diff --git a/assets/icons/circleCheck_stroke2_corner0_rounded.svg b/assets/icons/circleCheck_stroke2_corner0_rounded.svg new file mode 100644 index 000000000..d6b0b6bbf --- /dev/null +++ b/assets/icons/circleCheck_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/sparkle_stroke2_corner0_rounded.svg b/assets/icons/sparkle_stroke2_corner0_rounded.svg new file mode 100644 index 000000000..84478380e --- /dev/null +++ b/assets/icons/sparkle_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/verifiedCheck.svg b/assets/icons/verifiedCheck.svg new file mode 100644 index 000000000..f76955ac8 --- /dev/null +++ b/assets/icons/verifiedCheck.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/verifierCheck.svg b/assets/icons/verifierCheck.svg new file mode 100644 index 000000000..71158eb13 --- /dev/null +++ b/assets/icons/verifierCheck.svg @@ -0,0 +1 @@ + diff --git a/assets/images/initial_verification_announcement_1.png b/assets/images/initial_verification_announcement_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c7f38153b33d6e4a9de9182b27b8cf3866d8488c GIT binary patch literal 51326 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 literal 0 HcmV?d00001 diff --git a/assets/images/initial_verification_announcement_2.png b/assets/images/initial_verification_announcement_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d78f1b58301ddc3878e50968eb3c3285861e3059 GIT binary patch literal 85854 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≦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 literal 0 HcmV?d00001 diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index b74df5ff1..f419212cc 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -263,6 +263,7 @@ func serve(cctx *cli.Context) error { e.GET("/moderation/modlists", server.WebGeneric) e.GET("/moderation/muted-accounts", server.WebGeneric) e.GET("/moderation/blocked-accounts", server.WebGeneric) + e.GET("/moderation/verification-settings", server.WebGeneric) e.GET("/settings", server.WebGeneric) e.GET("/settings/language", server.WebGeneric) e.GET("/settings/app-passwords", server.WebGeneric) diff --git a/package.json b/package.json index 974eef74c..235b1a91b 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "icons:optimize": "svgo -f ./assets/icons" }, "dependencies": { - "@atproto/api": "^0.14.21", + "@atproto/api": "^0.15.3", "@bitdrift/react-native": "^0.6.8", "@braintree/sanitize-url": "^6.0.2", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 277ffb07e..d4fdc4797 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -70,6 +70,7 @@ import {MessagesConversationScreen} from '#/screens/Messages/Conversation' import {MessagesInboxScreen} from '#/screens/Messages/Inbox' import {MessagesSettingsScreen} from '#/screens/Messages/Settings' import {ModerationScreen} from '#/screens/Moderation' +import {Screen as ModerationVerificationSettings} from '#/screens/Moderation/VerificationSettings' import {Screen as ModerationInteractionSettings} from '#/screens/ModerationInteractionSettings' import {PostLikedByScreen} from '#/screens/Post/PostLikedBy' import {PostQuotesScreen} from '#/screens/Post/PostQuotes' @@ -167,6 +168,14 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) { requireAuth: true, }} /> + ModerationVerificationSettings} + options={{ + title: title(msg`Verification Settings`), + requireAuth: true, + }} + /> SettingsScreen} diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx index 52d149eb5..f2e781ccf 100644 --- a/src/components/AccountList.tsx +++ b/src/components/AccountList.tsx @@ -1,6 +1,6 @@ import React, {useCallback} from 'react' import {View} from 'react-native' -import {AppBskyActorDefs} from '@atproto/api' +import {type AppBskyActorDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -12,6 +12,8 @@ import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme} from '#/alf' import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' import {ChevronRight_Stroke2_Corner0_Rounded as Chevron} from '#/components/icons/Chevron' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' import {Button} from './Button' import {Text} from './Typography' @@ -74,11 +76,13 @@ export function AccountList({ ]}> {otherLabel ?? Other account} @@ -105,6 +109,7 @@ function AccountItem({ }) { const t = useTheme() const {_} = useLingui() + const verification = useSimpleVerificationState({profile}) const onPress = useCallback(() => { onSelect(account) @@ -114,7 +119,7 @@ function AccountItem({ + )} + + + + + + + ) +} diff --git a/src/components/dialogs/nuxs/index.tsx b/src/components/dialogs/nuxs/index.tsx index 10cae887b..c8c539b85 100644 --- a/src/components/dialogs/nuxs/index.tsx +++ b/src/components/dialogs/nuxs/index.tsx @@ -1,16 +1,17 @@ import React from 'react' -import {AppBskyActorDefs} from '@atproto/api' +import {type AppBskyActorDefs} from '@atproto/api' import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs' import { usePreferencesQuery, - UsePreferencesQueryResponse, + type UsePreferencesQueryResponse, } from '#/state/queries/preferences' import {useProfileQuery} from '#/state/queries/profile' -import {SessionAccount, useSession} from '#/state/session' +import {type SessionAccount, useSession} from '#/state/session' import {useOnboardingState} from '#/state/shell' +import {InitialVerificationAnnouncement} from '#/components/dialogs/nuxs/InitialVerificationAnnouncement' /* * NUXs */ @@ -29,7 +30,12 @@ const queuedNuxs: { currentProfile: AppBskyActorDefs.ProfileViewDetailed preferences: UsePreferencesQueryResponse }) => boolean -}[] = [] +}[] = [ + { + id: Nux.InitialVerificationAnnouncement, + enabled: () => true, + }, +] const Context = React.createContext({ activeNux: undefined, @@ -163,6 +169,9 @@ function Inner({ return ( {/*For example, activeNux === Nux.NeueTypography && */} + {activeNux === Nux.InitialVerificationAnnouncement && ( + + )} ) } diff --git a/src/components/dms/MessagesListHeader.tsx b/src/components/dms/MessagesListHeader.tsx index 8da8c015f..c8ed98f88 100644 --- a/src/components/dms/MessagesListHeader.tsx +++ b/src/components/dms/MessagesListHeader.tsx @@ -1,9 +1,9 @@ import React, {useCallback} from 'react' import {TouchableOpacity, View} from 'react-native' import { - AppBskyActorDefs, - ModerationCause, - ModerationDecision, + type AppBskyActorDefs, + type ModerationCause, + type ModerationDecision, } from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg} from '@lingui/macro' @@ -12,12 +12,12 @@ import {useNavigation} from '@react-navigation/native' import {BACK_HITSLOP} from '#/lib/constants' import {makeProfileLink} from '#/lib/routes/links' -import {NavigationProp} from '#/lib/routes/types' +import {type NavigationProp} from '#/lib/routes/types' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {isWeb} from '#/platform/detection' -import {Shadow} from '#/state/cache/profile-shadow' +import {type Shadow} from '#/state/cache/profile-shadow' import {isConvoActive, useConvo} from '#/state/messages/convo' -import {ConvoItem} from '#/state/messages/convo/types' +import {type ConvoItem} from '#/state/messages/convo/types' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {ConvoMenu} from '#/components/dms/ConvoMenu' @@ -25,6 +25,8 @@ import {Bell2Off_Filled_Corner0_Rounded as BellStroke} from '#/components/icons/ import {Link} from '#/components/Link' import {PostAlerts} from '#/components/moderation/PostAlerts' import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' const PFP_SIZE = isWeb ? 40 : 34 @@ -149,6 +151,9 @@ function HeaderReady({ const {_} = useLingui() const t = useTheme() const convoState = useConvo() + const verification = useSimpleVerificationState({ + profile, + }) const isDeletedAccount = profile?.handle === 'missing.invalid' const displayName = isDeletedAccount @@ -185,17 +190,27 @@ function HeaderReady({ /> - - {displayName} - + + + {displayName} + + {verification.showBadge && ( + + + + )} + {!isDeletedAccount && ( (function LogoImpl( + props, + ref, +) { + const {fill, size, style, ...rest} = useCommonSVGProps(props) + + return ( + + + + + ) +}) diff --git a/src/components/icons/VerifierCheck.tsx b/src/components/icons/VerifierCheck.tsx new file mode 100644 index 000000000..7c3a0149d --- /dev/null +++ b/src/components/icons/VerifierCheck.tsx @@ -0,0 +1,35 @@ +import React from 'react' +import Svg, {Path} from 'react-native-svg' + +import {type Props, useCommonSVGProps} from '#/components/icons/common' + +export const VerifierCheck = React.forwardRef(function LogoImpl( + props, + ref, +) { + const {fill, size, style, ...rest} = useCommonSVGProps(props) + + return ( + + + + + ) +}) diff --git a/src/components/verification/VerificationCheck.tsx b/src/components/verification/VerificationCheck.tsx new file mode 100644 index 000000000..4f41c6682 --- /dev/null +++ b/src/components/verification/VerificationCheck.tsx @@ -0,0 +1,12 @@ +import {type Props} from '#/components/icons/common' +import {VerifiedCheck} from '#/components/icons/VerifiedCheck' +import {VerifierCheck} from '#/components/icons/VerifierCheck' + +export function VerificationCheck({ + verifier, + ...rest +}: Props & { + verifier?: boolean +}) { + return verifier ? : +} diff --git a/src/components/verification/VerificationCheckButton.tsx b/src/components/verification/VerificationCheckButton.tsx new file mode 100644 index 000000000..1b66cd90e --- /dev/null +++ b/src/components/verification/VerificationCheckButton.tsx @@ -0,0 +1,155 @@ +import {View} from 'react-native' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {logger} from '#/logger' +import {type Shadow} from '#/state/cache/types' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {Button} from '#/components/Button' +import {useDialogControl} from '#/components/Dialog' +import {useFullVerificationState} from '#/components/verification' +import {type FullVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' +import {VerificationsDialog} from '#/components/verification/VerificationsDialog' +import {VerifierDialog} from '#/components/verification/VerifierDialog' +import type * as bsky from '#/types/bsky' + +export function shouldShowVerificationCheckButton( + state: FullVerificationState, +) { + let ok = false + + if (state.profile.role === 'default') { + if (state.profile.isVerified) { + ok = true + } else if (state.profile.isViewer && state.profile.wasVerified) { + ok = true + } else if ( + state.viewer.role === 'verifier' && + state.viewer.hasIssuedVerification + ) { + ok = true + } + } else if (state.profile.role === 'verifier') { + if (state.profile.isViewer) { + ok = true + } else if (state.profile.isVerified) { + ok = true + } + } + + if ( + !state.profile.showBadge && + !state.profile.isViewer && + !(state.viewer.role === 'verifier' && state.viewer.hasIssuedVerification) + ) { + ok = false + } + + return ok +} + +export function VerificationCheckButton({ + profile, + size, +}: { + profile: Shadow + size: 'lg' | 'md' | 'sm' +}) { + const state = useFullVerificationState({ + profile, + }) + + if (shouldShowVerificationCheckButton(state)) { + return + } + + return null +} + +export function Badge({ + profile, + verificationState: state, + size, +}: { + profile: Shadow + verificationState: FullVerificationState + size: 'lg' | 'md' | 'sm' +}) { + const t = useTheme() + const {_} = useLingui() + const verificationsDialogControl = useDialogControl() + const verifierDialogControl = useDialogControl() + const {gtPhone} = useBreakpoints() + let dimensions = 12 + if (size === 'lg') { + dimensions = gtPhone ? 20 : 18 + } else if (size === 'md') { + dimensions = 16 + } + + const verifiedByHidden = !state.profile.showBadge && state.profile.isViewer + + return ( + <> + + + + + + + ) +} diff --git a/src/components/verification/VerificationCreatePrompt.tsx b/src/components/verification/VerificationCreatePrompt.tsx new file mode 100644 index 000000000..39ac6dbf6 --- /dev/null +++ b/src/components/verification/VerificationCreatePrompt.tsx @@ -0,0 +1,70 @@ +import {useCallback} from 'react' +import {View} from 'react-native' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {logger} from '#/logger' +import {useModerationOpts} from '#/state/preferences/moderation-opts' +import {useVerificationCreateMutation} from '#/state/queries/verification/useVerificationCreateMutation' +import * as Toast from '#/view/com/util/Toast' +import {atoms as a} from '#/alf' +import {type DialogControlProps} from '#/components/Dialog' +import {VerifiedCheck} from '#/components/icons/VerifiedCheck' +import * as ProfileCard from '#/components/ProfileCard' +import * as Prompt from '#/components/Prompt' +import type * as bsky from '#/types/bsky' + +export function VerificationCreatePrompt({ + control, + profile, +}: { + control: DialogControlProps + profile: bsky.profile.AnyProfileView +}) { + const {_} = useLingui() + const moderationOpts = useModerationOpts() + const {mutateAsync: create} = useVerificationCreateMutation() + const onConfirm = useCallback(async () => { + try { + await create({profile}) + Toast.show(_(msg`Successfully verified`)) + } catch (e) { + Toast.show(_(msg`Failed to create a verification`), 'xmark') + logger.error('Failed to create a verification', { + safeMessage: e, + }) + } + }, [_, profile, create]) + + return ( + + + + + {_(msg`Verify this account?`)} + + + + {_(msg`This action can be undone at any time.`)} + + + {moderationOpts ? ( + + + + + ) : null} + + + + + + + ) +} diff --git a/src/components/verification/VerificationRemovePrompt.tsx b/src/components/verification/VerificationRemovePrompt.tsx new file mode 100644 index 000000000..470b61c19 --- /dev/null +++ b/src/components/verification/VerificationRemovePrompt.tsx @@ -0,0 +1,50 @@ +import {useCallback} from 'react' +import {type AppBskyActorDefs} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {logger} from '#/logger' +import {useVerificationsRemoveMutation} from '#/state/queries/verification/useVerificationsRemoveMutation' +import * as Toast from '#/view/com/util/Toast' +import {type DialogControlProps} from '#/components/Dialog' +import * as Prompt from '#/components/Prompt' +import type * as bsky from '#/types/bsky' + +export {useDialogControl as usePromptControl} from '#/components/Dialog' + +export function VerificationRemovePrompt({ + control, + profile, + verifications, + onConfirm: onConfirmInner, +}: { + control: DialogControlProps + profile: bsky.profile.AnyProfileView + verifications: AppBskyActorDefs.VerificationView[] + onConfirm?: () => void +}) { + const {_} = useLingui() + const {mutateAsync: remove} = useVerificationsRemoveMutation() + const onConfirm = useCallback(async () => { + onConfirmInner?.() + try { + await remove({profile, verifications}) + Toast.show(_(msg`Removed verification`)) + } catch (e) { + Toast.show(_(msg`Failed to remove verification`), 'xmark') + logger.error('Failed to remove verification', { + safeMessage: e, + }) + } + }, [_, profile, verifications, remove, onConfirmInner]) + + return ( + + ) +} diff --git a/src/components/verification/VerificationsDialog.tsx b/src/components/verification/VerificationsDialog.tsx new file mode 100644 index 000000000..d61823968 --- /dev/null +++ b/src/components/verification/VerificationsDialog.tsx @@ -0,0 +1,257 @@ +import {View} from 'react-native' +import {type AppBskyActorDefs} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {urls} from '#/lib/constants' +import {getUserDisplayName} from '#/lib/getUserDisplayName' +import {logger} from '#/logger' +import {useModerationOpts} from '#/state/preferences/moderation-opts' +import {useProfileQuery} from '#/state/queries/profile' +import {useSession} from '#/state/session' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {Admonition} from '#/components/Admonition' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {useDialogControl} from '#/components/Dialog' +import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Trash' +import {Link} from '#/components/Link' +import * as ProfileCard from '#/components/ProfileCard' +import {Text} from '#/components/Typography' +import {type FullVerificationState} from '#/components/verification' +import {VerificationRemovePrompt} from '#/components/verification/VerificationRemovePrompt' +import type * as bsky from '#/types/bsky' + +export {useDialogControl} from '#/components/Dialog' + +export function VerificationsDialog({ + control, + profile, + verificationState, +}: { + control: Dialog.DialogControlProps + profile: bsky.profile.AnyProfileView + verificationState: FullVerificationState +}) { + return ( + + + + + ) +} + +function Inner({ + profile, + control, + verificationState: state, +}: { + control: Dialog.DialogControlProps + profile: bsky.profile.AnyProfileView + verificationState: FullVerificationState +}) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + + const userName = getUserDisplayName(profile) + const label = state.profile.isViewer + ? state.profile.isVerified + ? _(msg`You are verified`) + : _(msg`Your verifications`) + : state.profile.isVerified + ? _(msg`${userName} is verified`) + : _( + msg({ + message: `${userName}'s verifications`, + comment: `Possessive, meaning "the verifications of {userName}"`, + }), + ) + + return ( + + + + + + {label} + + + {state.profile.isVerified ? ( + + This account has a checkmark because it's been verified by trusted + sources. + + ) : ( + + This account has one or more verifications, but it is not + currently verified. + + )} + + + + {profile.verification ? ( + + + Verified by: + + + + {profile.verification.verifications.map(v => ( + + ))} + + + {profile.verification.verifications.some(v => !v.isValid) && + state.profile.isViewer && ( + + Some of your verifications are invalid. + + )} + + ) : null} + + + + { + logger.metric('verification:learn-more', { + location: 'verificationsDialog', + }) + }}> + + Learn more + + + + + + + ) +} + +function VerifierCard({ + verification, + subject, + outerDialogControl, +}: { + verification: AppBskyActorDefs.VerificationView + subject: bsky.profile.AnyProfileView + outerDialogControl: Dialog.DialogControlProps +}) { + const t = useTheme() + const {_} = useLingui() + const {currentAccount} = useSession() + const moderationOpts = useModerationOpts() + const {data: profile, error} = useProfileQuery({did: verification.issuer}) + const verificationRemovePromptControl = useDialogControl() + const canAdminister = verification.issuer === currentAccount?.did + + return ( + + + + {error ? ( + <> + + + + Unknown verifier + + + {verification.issuer} + + + + ) : profile && moderationOpts ? ( + <> + + + {canAdminister && ( + + + + )} + + ) : ( + <> + + + + )} + + + + outerDialogControl.close()} + /> + + ) +} diff --git a/src/components/verification/VerifierDialog.tsx b/src/components/verification/VerifierDialog.tsx new file mode 100644 index 000000000..bfe49ec19 --- /dev/null +++ b/src/components/verification/VerifierDialog.tsx @@ -0,0 +1,153 @@ +import {Text as RNText, View} from 'react-native' +import {Image} from 'expo-image' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {urls} from '#/lib/constants' +import {getUserDisplayName} from '#/lib/getUserDisplayName' +import {NON_BREAKING_SPACE} from '#/lib/strings/constants' +import {logger} from '#/logger' +import {useSession} from '#/state/session' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {VerifierCheck} from '#/components/icons/VerifierCheck' +import {Link} from '#/components/Link' +import {Text} from '#/components/Typography' +import {type FullVerificationState} from '#/components/verification' +import type * as bsky from '#/types/bsky' + +export {useDialogControl} from '#/components/Dialog' + +export function VerifierDialog({ + control, + profile, + verificationState, +}: { + control: Dialog.DialogControlProps + profile: bsky.profile.AnyProfileView + verificationState: FullVerificationState +}) { + return ( + + + + + ) +} + +function Inner({ + profile, + control, +}: { + control: Dialog.DialogControlProps + profile: bsky.profile.AnyProfileView + verificationState: FullVerificationState +}) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + const {currentAccount} = useSession() + + const isSelf = profile.did === currentAccount?.did + const userName = getUserDisplayName(profile) + const label = isSelf + ? _(msg`You are a trusted verifier`) + : _(msg`${userName} is a trusted verifier`) + + return ( + + + + + + {_( + + + + + {label} + + + + Accounts with a scalloped blue check mark + + {NON_BREAKING_SPACE} + + {NON_BREAKING_SPACE} + + can verify others. These trusted verifiers are selected by + Bluesky. + + + + + + { + logger.metric('verification:learn-more', { + location: 'verifierDialog', + }) + }}> + + Learn more + + + + + + + + + ) +} diff --git a/src/components/verification/index.ts b/src/components/verification/index.ts new file mode 100644 index 000000000..7a83a160a --- /dev/null +++ b/src/components/verification/index.ts @@ -0,0 +1,113 @@ +import {useMemo} from 'react' + +import {usePreferencesQuery} from '#/state/queries/preferences' +import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile' +import {useSession} from '#/state/session' +import type * as bsky from '#/types/bsky' + +export type FullVerificationState = { + profile: { + role: 'default' | 'verifier' + isVerified: boolean + wasVerified: boolean + isViewer: boolean + showBadge: boolean + } + viewer: + | { + role: 'default' + isVerified: boolean + } + | { + role: 'verifier' + isVerified: boolean + hasIssuedVerification: boolean + } +} + +export function useFullVerificationState({ + profile, +}: { + profile: bsky.profile.AnyProfileView +}): FullVerificationState { + const {currentAccount} = useSession() + const currentAccountProfile = useCurrentAccountProfile() + const profileState = useSimpleVerificationState({profile}) + const viewerState = useSimpleVerificationState({ + profile: currentAccountProfile, + }) + + return useMemo(() => { + const verifications = profile.verification?.verifications || [] + const wasVerified = + profileState.role === 'default' && + !profileState.isVerified && + verifications.length > 0 + const hasIssuedVerification = Boolean( + viewerState && + viewerState.role === 'verifier' && + profileState.role === 'default' && + verifications.find(v => v.issuer === currentAccount?.did), + ) + + return { + profile: { + ...profileState, + wasVerified, + isViewer: profile.did === currentAccount?.did, + showBadge: profileState.showBadge, + }, + viewer: + viewerState.role === 'verifier' + ? { + role: 'verifier', + isVerified: viewerState.isVerified, + hasIssuedVerification, + } + : { + role: 'default', + isVerified: viewerState.isVerified, + }, + } + }, [profile, currentAccount, profileState, viewerState]) +} + +export type SimpleVerificationState = { + role: 'default' | 'verifier' + isVerified: boolean + showBadge: boolean +} + +export function useSimpleVerificationState({ + profile, +}: { + profile?: bsky.profile.AnyProfileView +}): SimpleVerificationState { + const preferences = usePreferencesQuery() + const prefs = useMemo( + () => preferences.data?.verificationPrefs || {hideBadges: false}, + [preferences.data?.verificationPrefs], + ) + return useMemo(() => { + if (!profile || !profile.verification) { + return { + role: 'default', + isVerified: false, + showBadge: false, + } + } + + const {verifiedStatus, trustedVerifierStatus} = profile.verification + const isVerifiedUser = ['valid', 'invalid'].includes(verifiedStatus) + const isVerifierUser = ['valid', 'invalid'].includes(trustedVerifierStatus) + const isVerified = + (isVerifiedUser && verifiedStatus === 'valid') || + (isVerifierUser && trustedVerifierStatus === 'valid') + + return { + role: isVerifierUser ? 'verifier' : 'default', + isVerified, + showBadge: prefs.hideBadges ? false : isVerified, + } + }, [profile, prefs]) +} diff --git a/src/lib/constants.ts b/src/lib/constants.ts index fe84f41b2..bb98f9fc8 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -192,3 +192,11 @@ export const SUPPORTED_MIME_TYPES = [ export type SupportedMimeTypes = (typeof SUPPORTED_MIME_TYPES)[number] export const EMOJI_REACTION_LIMIT = 5 + +export const urls = { + website: { + blog: { + initialVerificationAnnouncement: `https://bsky.social/about/blog/04-21-2025-verification`, + }, + }, +} diff --git a/src/lib/getUserDisplayName.ts b/src/lib/getUserDisplayName.ts new file mode 100644 index 000000000..790bb31e5 --- /dev/null +++ b/src/lib/getUserDisplayName.ts @@ -0,0 +1,10 @@ +import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {sanitizeHandle} from '#/lib/strings/handles' + +export function getUserDisplayName< + T extends {displayName?: string; handle: string; [key: string]: any}, +>(props: T): string { + return sanitizeDisplayName( + props.displayName || sanitizeHandle(props.handle, '@'), + ) +} diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index 658b68db8..0bc85b630 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -13,6 +13,7 @@ export type CommonNavigatorParams = { ModerationMutedAccounts: undefined ModerationBlockedAccounts: undefined ModerationInteractionSettings: undefined + ModerationVerificationSettings: undefined Settings: undefined Profile: {name: string; hideBackButton?: boolean} ProfileFollowers: {name: string} diff --git a/src/logger/metrics.ts b/src/logger/metrics.ts index 2b696c1e4..42b0d6ef3 100644 --- a/src/logger/metrics.ts +++ b/src/logger/metrics.ts @@ -370,4 +370,17 @@ export type MetricEvents = { targetLanguage: string textLength: number } + + 'verification:create': {} + 'verification:revoke': {} + 'verification:badge:click': {} + 'verification:learn-more': { + location: + | 'initialAnnouncementeNux' + | 'verificationsDialog' + | 'verifierDialog' + | 'verificationSettings' + } + 'verification:settings:hideBadges': {} + 'verification:settings:unHideBadges': {} } diff --git a/src/routes.ts b/src/routes.ts index 68c39e7fc..60bb65dd5 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -14,6 +14,7 @@ export const router = new Router({ ModerationMutedAccounts: '/moderation/muted-accounts', ModerationBlockedAccounts: '/moderation/blocked-accounts', ModerationInteractionSettings: '/moderation/interaction-settings', + ModerationVerificationSettings: '/moderation/verification-settings', // profiles, threads, lists Profile: ['/profile/:name', '/profile/:name/rss'], ProfileFollowers: '/profile/:name/followers', diff --git a/src/screens/Messages/components/ChatListItem.tsx b/src/screens/Messages/components/ChatListItem.tsx index 8a760e2c9..09cf2dccd 100644 --- a/src/screens/Messages/components/ChatListItem.tsx +++ b/src/screens/Messages/components/ChatListItem.tsx @@ -43,6 +43,8 @@ import {Link} from '#/components/Link' import {useMenuControl} from '#/components/Menu' import {PostAlerts} from '#/components/moderation/PostAlerts' import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' import type * as bsky from '#/types/bsky' export let ChatListItem = ({ @@ -106,6 +108,9 @@ function ChatListItemReady({ const playHaptic = useHaptics() const queryClient = useQueryClient() const isUnread = convo.unreadCount > 0 + const verification = useSimpleVerificationState({ + profile, + }) const blockInfo = useMemo(() => { const modui = moderation.ui('profileView') @@ -385,11 +390,10 @@ function ChatListItemReady({ - + {displayName} - + + {verification.showBadge && ( + + + + )} {lastMessageSentAt && ( - - {({timeElapsed}) => ( - - {' '} - · {timeElapsed} - - )} - + + + {({timeElapsed}) => ( + + · {timeElapsed} + + )} + + )} {(convo.muted || moderation.blocked) && ( + + + + + Verification Settings + + + + + + + + + + Verifications on Bluesky work differently than on other + platforms.{' '} + { + logger.metric('verification:learn-more', { + location: 'verificationSettings', + }) + }}> + Learn more here. + + + + + {preferences ? ( + + ) : ( + + + + )} + + + + ) +} + +function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { + const {_} = useLingui() + const {hideBadges} = preferences.verificationPrefs + const {mutate: setVerificationPrefs, isPending} = + useSetVerificationPrefsMutation() + + return ( + { + setVerificationPrefs({hideBadges: value}) + }}> + + + + Hide verification badges + + + + + ) +} diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index 55cc67f8c..78b0a6ae9 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -6,19 +6,22 @@ import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' import {getLabelingServiceTitle} from '#/lib/moderation' -import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types' +import { + type CommonNavigatorParams, + type NativeStackScreenProps, +} from '#/lib/routes/types' import {logger} from '#/logger' import {isIOS} from '#/platform/detection' import { useMyLabelersQuery, usePreferencesQuery, - UsePreferencesQueryResponse, + type UsePreferencesQueryResponse, usePreferencesSetAdultContentMutation, } from '#/state/queries/preferences' import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities' import {useSetMinimalShellMode} from '#/state/shell' import {ViewHeader} from '#/view/com/util/ViewHeader' -import {atoms as a, useBreakpoints, useTheme, ViewStyleProp} from '#/alf' +import {atoms as a, useBreakpoints, useTheme, type ViewStyleProp} from '#/alf' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings' @@ -27,7 +30,8 @@ import {Divider} from '#/components/Divider' import * as Toggle from '#/components/forms/Toggle' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' -import {Props as SVGIconProps} from '#/components/icons/common' +import {CircleCheck_Stroke2_Corner0_Rounded as CircleCheck} from '#/components/icons/CircleCheck' +import {type Props as SVGIconProps} from '#/components/icons/common' import {EditBig_Stroke2_Corner0_Rounded as EditBig} from '#/components/icons/EditBig' import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter' import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' @@ -274,6 +278,21 @@ export function ModerationScreenInner({ /> )} + + + {state => ( + + )} + + {verification.isVerified && + verification.role === 'default' && + displayName !== initialDisplayName && ( + + + You are verified. You will lose your verification status if you + change your display name.{' '} + + Learn more. + + + + )} + Description diff --git a/src/screens/Profile/Header/ProfileHeaderStandard.tsx b/src/screens/Profile/Header/ProfileHeaderStandard.tsx index 773c296c9..1c4c4d9f3 100644 --- a/src/screens/Profile/Header/ProfileHeaderStandard.tsx +++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx @@ -10,6 +10,7 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {sanitizeHandle} from '#/lib/strings/handles' import {logger} from '#/logger' import {isIOS, isWeb} from '#/platform/detection' import {useProfileShadow} from '#/state/cache/profile-shadow' @@ -22,7 +23,7 @@ import { import {useRequireAuth, useSession} from '#/state/session' import {ProfileMenu} from '#/view/com/profile/ProfileMenu' import * as Toast from '#/view/com/util/Toast' -import {atoms as a} from '#/alf' +import {atoms as a, platform, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {useDialogControl} from '#/components/Dialog' import {MessageProfileButton} from '#/components/dms/MessageProfileButton' @@ -33,7 +34,8 @@ import { } from '#/components/KnownFollowers' import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' -import {ProfileHeaderDisplayName} from './DisplayName' +import {Text} from '#/components/Typography' +import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton' import {EditProfileDialog} from './EditProfileDialog' import {ProfileHeaderHandle} from './Handle' import {ProfileHeaderMetrics} from './Metrics' @@ -54,6 +56,8 @@ let ProfileHeaderStandard = ({ hideBackButton = false, isPlaceholderProfile, }: Props): React.ReactNode => { + const t = useTheme() + const {gtMobile} = useBreakpoints() const profile: Shadow = useProfileShadow(profileUnshadowed) const {currentAccount, hasSession} = useSession() @@ -238,7 +242,31 @@ let ProfileHeaderStandard = ({ - + + + {sanitizeDisplayName( + profile.displayName || sanitizeHandle(profile.handle), + moderation.ui('displayName'), + )} + + + + + {!isPlaceholderProfile && !isBlockedUser && ( diff --git a/src/screens/Search/components/AutocompleteResults.tsx b/src/screens/Search/components/AutocompleteResults.tsx index b3bccd1d4..2824ccc1b 100644 --- a/src/screens/Search/components/AutocompleteResults.tsx +++ b/src/screens/Search/components/AutocompleteResults.tsx @@ -49,7 +49,7 @@ let AutocompleteResults = ({ ? undefined : `/search?q=${encodeURIComponent(searchText)}` } - style={{borderBottomWidth: 1}} + style={a.border_b} /> {autocompleteData?.map(item => ( void }) { const {gtMobile} = useBreakpoints() - const t = useTheme() const {_} = useLingui() + const moderationOpts = useModerationOpts() return ( - {selectedProfiles.slice(0, 5).map((profile, index) => ( - - onProfileClick(profile)} - style={[a.align_center, a.w_full]}> - ( + onProfileClick(profile)} + onRemove={() => onRemoveProfileClick(profile)} /> - - {sanitizeDisplayName( - profile.displayName || profile.handle, - )} - - - onRemoveProfileClick(profile)} - hitSlop={createHitslop(6)} - style={styles.profileRemoveBtn}> - - - - ))} + ))} @@ -134,6 +111,81 @@ export function SearchHistory({ ) } +function RecentProfileItem({ + profile, + moderationOpts, + onPress, + onRemove, +}: { + profile: bsky.profile.AnyProfileView + moderationOpts: ModerationOpts + onPress: () => void + onRemove: () => void +}) { + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + const t = useTheme() + + const moderation = moderateProfile(profile, moderationOpts) + const name = sanitizeDisplayName( + profile.displayName || sanitizeHandle(profile.handle), + moderation.ui('displayName'), + ) + const verification = useSimpleVerificationState({profile}) + + return ( + + + + + + + {name} + + {verification.showBadge && ( + + + + )} + + + + + + + + ) +} + const styles = StyleSheet.create({ selectedProfilesContainer: { marginTop: 10, diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index 956413a55..a723aaa37 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -29,7 +29,7 @@ import {useCloseAllActiveElements} from '#/state/util' import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import * as SettingsList from '#/screens/Settings/components/SettingsList' -import {atoms as a, tokens, useBreakpoints, useTheme} from '#/alf' +import {atoms as a, platform, tokens, useBreakpoints, useTheme} from '#/alf' import {AvatarStackWithFetch} from '#/components/AvatarStack' import {useDialogControl} from '#/components/Dialog' import {SwitchAccountDialog} from '#/components/dialogs/SwitchAccount' @@ -55,6 +55,11 @@ import {Loader} from '#/components/Loader' import * as Menu from '#/components/Menu' import * as Prompt from '#/components/Prompt' import {Text} from '#/components/Typography' +import {useFullVerificationState} from '#/components/verification' +import { + shouldShowVerificationCheckButton, + VerificationCheckButton, +} from '#/components/verification/VerificationCheckButton' type Props = NativeStackScreenProps export function SettingsScreen({}: Props) { @@ -278,6 +283,9 @@ function ProfilePreview({ const {gtMobile} = useBreakpoints() const shadow = useProfileShadow(profile) const moderationOpts = useModerationOpts() + const verificationState = useFullVerificationState({ + profile: shadow, + }) if (!moderationOpts) return null @@ -292,20 +300,33 @@ function ProfilePreview({ type={shadow.associated?.labeler ? 'labeler' : 'user'} /> - - {sanitizeDisplayName( - profile.displayName || sanitizeHandle(profile.handle), - moderation.ui('displayName'), + + + {sanitizeDisplayName( + profile.displayName || sanitizeHandle(profile.handle), + moderation.ui('displayName'), + )} + + {shouldShowVerificationCheckButton(verificationState) && ( + + + )} - + {sanitizeHandle(profile.handle, '@')} diff --git a/src/screens/Settings/components/ChangeHandleDialog.tsx b/src/screens/Settings/components/ChangeHandleDialog.tsx index b69713a10..a39d958ab 100644 --- a/src/screens/Settings/components/ChangeHandleDialog.tsx +++ b/src/screens/Settings/components/ChangeHandleDialog.tsx @@ -10,18 +10,19 @@ import Animated, { SlideOutLeft, SlideOutRight, } from 'react-native-reanimated' -import {ComAtprotoServerDescribeServer} from '@atproto/api' +import {type ComAtprotoServerDescribeServer} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useMutation, useQueryClient} from '@tanstack/react-query' -import {HITSLOP_10} from '#/lib/constants' +import {HITSLOP_10, urls} from '#/lib/constants' import {cleanError} from '#/lib/strings/errors' import {createFullHandle, validateServiceHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles' import {useFetchDid, useUpdateHandleMutation} from '#/state/queries/handle' import {RQKEY as RQKEY_PROFILE} from '#/state/queries/profile' import {useServiceQuery} from '#/state/queries/service' +import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile' import {useAgent, useSession} from '#/state/session' import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' import {atoms as a, native, useBreakpoints, useTheme} from '#/alf' @@ -40,6 +41,7 @@ import {SquareBehindSquare4_Stroke2_Corner0_Rounded as CopyIcon} from '#/compone import {InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' import {CopyButton} from './CopyButton' export function ChangeHandleDialog({ @@ -152,6 +154,10 @@ function ProvidedHandlePage({ const control = Dialog.useDialogContext() const {currentAccount} = useSession() const queryClient = useQueryClient() + const profile = useCurrentAccountProfile() + const verification = useSimpleVerificationState({ + profile, + }) const { mutate: changeHandle, @@ -197,6 +203,19 @@ function ProvidedHandlePage({ + {verification.isVerified && verification.role === 'default' && ( + + + You are verified. You will lose your verification status if you + change your handle.{' '} + + Learn more. + + + + )} New handle diff --git a/src/state/cache/profile-shadow.ts b/src/state/cache/profile-shadow.ts index 82ee44388..9c23e4550 100644 --- a/src/state/cache/profile-shadow.ts +++ b/src/state/cache/profile-shadow.ts @@ -1,4 +1,5 @@ import {useEffect, useMemo, useState} from 'react' +import {type AppBskyActorDefs} from '@atproto/api' import {type QueryClient} from '@tanstack/react-query' import EventEmitter from 'eventemitter3' @@ -29,6 +30,7 @@ export interface ProfileShadow { followingUri: string | undefined muted: boolean | undefined blockingUri: string | undefined + verification: AppBskyActorDefs.VerificationState } const shadows: WeakMap< @@ -134,6 +136,8 @@ function mergeShadow( blocking: 'blockingUri' in shadow ? shadow.blockingUri : profile.viewer?.blocking, }, + verification: + 'verification' in shadow ? shadow.verification : profile.verification, }) } diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts index f6f53f58f..6bbf9b250 100644 --- a/src/state/queries/notifications/util.ts +++ b/src/state/queries/notifications/util.ts @@ -1,22 +1,26 @@ import { - AppBskyFeedDefs, + type AppBskyFeedDefs, AppBskyFeedLike, AppBskyFeedPost, AppBskyFeedRepost, - AppBskyGraphDefs, + type AppBskyGraphDefs, AppBskyGraphStarterpack, - AppBskyNotificationListNotifications, - BskyAgent, + type AppBskyNotificationListNotifications, + type BskyAgent, moderateNotification, - ModerationOpts, + type ModerationOpts, } from '@atproto/api' -import {QueryClient} from '@tanstack/react-query' +import {type QueryClient} from '@tanstack/react-query' import chunk from 'lodash.chunk' import {labelIsHideableOffense} from '#/lib/moderation' import * as bsky from '#/types/bsky' import {precacheProfile} from '../profile' -import {FeedNotification, FeedPage, NotificationType} from './types' +import { + type FeedNotification, + type FeedPage, + type NotificationType, +} from './types' const GROUPABLE_REASONS = ['like', 'repost', 'follow'] const MS_1HR = 1e3 * 60 * 60 @@ -155,14 +159,14 @@ export function groupNotifications( const type = toKnownType(notif) if (type !== 'starterpack-joined') { groupedNotifs.push({ - _reactKey: `notif-${notif.uri}`, + _reactKey: `notif-${notif.uri}-${notif.reason}`, type, notification: notif, subjectUri: getSubjectUri(type, notif), }) } else { groupedNotifs.push({ - _reactKey: `notif-${notif.uri}`, + _reactKey: `notif-${notif.uri}-${notif.reason}`, type: 'starterpack-joined', notification: notif, subjectUri: notif.uri, @@ -238,7 +242,9 @@ function toKnownType( notif.reason === 'reply' || notif.reason === 'quote' || notif.reason === 'follow' || - notif.reason === 'starterpack-joined' + notif.reason === 'starterpack-joined' || + notif.reason === 'verified' || + notif.reason === 'unverified' ) { return notif.reason as NotificationType } diff --git a/src/state/queries/nuxs/definitions.ts b/src/state/queries/nuxs/definitions.ts index 8eb53a0a4..a44ffa4c5 100644 --- a/src/state/queries/nuxs/definitions.ts +++ b/src/state/queries/nuxs/definitions.ts @@ -5,6 +5,7 @@ import {type BaseNux} from '#/state/queries/nuxs/types' export enum Nux { NeueTypography = 'NeueTypography', ExploreInterestsCard = 'ExploreInterestsCard', + InitialVerificationAnnouncement = 'InitialVerificationAnnouncement', } export const nuxNames = new Set(Object.values(Nux)) @@ -18,9 +19,14 @@ export type AppNux = BaseNux< id: Nux.ExploreInterestsCard data: undefined } + | { + id: Nux.InitialVerificationAnnouncement + data: undefined + } > export const NuxSchemas: Record | undefined> = { [Nux.NeueTypography]: undefined, [Nux.ExploreInterestsCard]: undefined, + [Nux.InitialVerificationAnnouncement]: undefined, } diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts index 3c1fead5e..84b208a9f 100644 --- a/src/state/queries/preferences/const.ts +++ b/src/state/queries/preferences/const.ts @@ -1,7 +1,7 @@ import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation' import { - ThreadViewPreferences, - UsePreferencesQueryResponse, + type ThreadViewPreferences, + type UsePreferencesQueryResponse, } from '#/state/queries/preferences/types' export const DEFAULT_HOME_FEED_PREFS: UsePreferencesQueryResponse['feedViewPrefs'] = @@ -43,4 +43,7 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = { threadgateAllowRules: undefined, postgateEmbeddingRules: [], }, + verificationPrefs: { + hideBadges: false, + }, } diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index 81b3dd086..daab5eca3 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -1,7 +1,7 @@ import { - AppBskyActorDefs, - BskyFeedViewPreference, - LabelPreference, + type AppBskyActorDefs, + type BskyFeedViewPreference, + type LabelPreference, } from '@atproto/api' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' @@ -16,8 +16,8 @@ import { DEFAULT_THREAD_VIEW_PREFS, } from '#/state/queries/preferences/const' import { - ThreadViewPreferences, - UsePreferencesQueryResponse, + type ThreadViewPreferences, + type UsePreferencesQueryResponse, } from '#/state/queries/preferences/types' import {useAgent} from '#/state/session' import {saveLabelers} from '#/state/session/agent-config' @@ -407,3 +407,23 @@ export function useSetActiveProgressGuideMutation() { }, }) } + +export function useSetVerificationPrefsMutation() { + const queryClient = useQueryClient() + const agent = useAgent() + + return useMutation({ + mutationFn: async prefs => { + await agent.setVerificationPrefs(prefs) + if (prefs.hideBadges) { + logger.metric('verification:settings:hideBadges', {}) + } else { + logger.metric('verification:settings:unHideBadges', {}) + } + // triggers a refetch + await queryClient.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts index 2cf144d3a..609a62e25 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -1,18 +1,18 @@ import {useCallback} from 'react' -import {Image as RNImage} from 'react-native-image-crop-picker' +import {type Image as RNImage} from 'react-native-image-crop-picker' import { - AppBskyActorDefs, - AppBskyActorGetProfile, - AppBskyActorGetProfiles, - AppBskyActorProfile, + type AppBskyActorDefs, + type AppBskyActorGetProfile, + type AppBskyActorGetProfiles, + type AppBskyActorProfile, AtUri, - BskyAgent, - ComAtprotoRepoUploadBlob, - Un$Typed, + type BskyAgent, + type ComAtprotoRepoUploadBlob, + type Un$Typed, } from '@atproto/api' import { keepPreviousData, - QueryClient, + type QueryClient, useMutation, useQuery, useQueryClient, @@ -21,16 +21,17 @@ import { import {uploadBlob} from '#/lib/api' import {until} from '#/lib/async/until' import {useToggleMutationQueue} from '#/lib/hooks/useToggleMutationQueue' -import {logEvent, LogEvents, toClout} from '#/lib/statsig/statsig' -import {Shadow} from '#/state/cache/types' +import {logEvent, type LogEvents, toClout} from '#/lib/statsig/statsig' +import {type Shadow} from '#/state/cache/types' import {STALE} from '#/state/queries' import {resetProfilePostsQueries} from '#/state/queries/post-feed' import { unstableCacheProfileView, useUnstableProfileViewCache, } from '#/state/queries/unstable-profile-cache' +import {useUpdateProfileVerificationCache} from '#/state/queries/verification/useUpdateProfileVerificationCache' import * as userActionHistory from '#/state/userActionHistory' -import * as bsky from '#/types/bsky' +import type * as bsky from '#/types/bsky' import {updateProfileShadow} from '../cache/profile-shadow' import {useAgent, useSession} from '../session' import { @@ -50,7 +51,7 @@ export const precacheProfile = unstableCacheProfileView const RQKEY_ROOT = 'profile' export const RQKEY = (did: string) => [RQKEY_ROOT, did] -const profilesQueryKeyRoot = 'profiles' +export const profilesQueryKeyRoot = 'profiles' export const profilesQueryKey = (handles: string[]) => [ profilesQueryKeyRoot, handles, @@ -137,6 +138,7 @@ interface ProfileUpdateParams { export function useProfileUpdateMutation() { const queryClient = useQueryClient() const agent = useAgent() + const updateProfileVerificationCache = useUpdateProfileVerificationCache() return useMutation({ mutationFn: async ({ profile, @@ -223,7 +225,7 @@ export function useProfileUpdateMutation() { }), ) }, - onSuccess(data, variables) { + async onSuccess(_, variables) { // invalidate cache queryClient.invalidateQueries({ queryKey: RQKEY(variables.profile.did), @@ -231,6 +233,7 @@ export function useProfileUpdateMutation() { queryClient.invalidateQueries({ queryKey: [profilesQueryKeyRoot, [variables.profile.did]], }) + await updateProfileVerificationCache({profile: variables.profile}) }, }) } diff --git a/src/state/queries/useCurrentAccountProfile.tsx b/src/state/queries/useCurrentAccountProfile.tsx new file mode 100644 index 000000000..d1f562efc --- /dev/null +++ b/src/state/queries/useCurrentAccountProfile.tsx @@ -0,0 +1,9 @@ +import {useMaybeProfileShadow} from '#/state/cache/profile-shadow' +import {useProfileQuery} from '#/state/queries/profile' +import {useSession} from '#/state/session' + +export function useCurrentAccountProfile() { + const {currentAccount} = useSession() + const {data: profile} = useProfileQuery({did: currentAccount?.did}) + return useMaybeProfileShadow(profile) +} diff --git a/src/state/queries/verification/useUpdateProfileVerificationCache.ts b/src/state/queries/verification/useUpdateProfileVerificationCache.ts new file mode 100644 index 000000000..f5ccf1458 --- /dev/null +++ b/src/state/queries/verification/useUpdateProfileVerificationCache.ts @@ -0,0 +1,35 @@ +import {useCallback} from 'react' +import {useQueryClient} from '@tanstack/react-query' + +import {logger} from '#/logger' +import {updateProfileShadow} from '#/state/cache/profile-shadow' +import {useAgent} from '#/state/session' +import type * as bsky from '#/types/bsky' + +/** + * Fetches a fresh verification state from the app view and updates our profile + * cache. This state is computed using a variety of factors on the server, so + * we need to get this data from the server. + */ +export function useUpdateProfileVerificationCache() { + const qc = useQueryClient() + const agent = useAgent() + + return useCallback( + async ({profile}: {profile: bsky.profile.AnyProfileView}) => { + try { + const {data: updated} = await agent.getProfile({ + actor: profile.did ?? '', + }) + updateProfileShadow(qc, profile.did, { + verification: updated.verification, + }) + } catch (e) { + logger.error(`useUpdateProfileVerificationCache failed`, { + safeMessage: e, + }) + } + }, + [agent, qc], + ) +} diff --git a/src/state/queries/verification/useVerificationCreateMutation.tsx b/src/state/queries/verification/useVerificationCreateMutation.tsx new file mode 100644 index 000000000..1048eb9d2 --- /dev/null +++ b/src/state/queries/verification/useVerificationCreateMutation.tsx @@ -0,0 +1,53 @@ +import {type AppBskyActorGetProfile} from '@atproto/api' +import {useMutation} from '@tanstack/react-query' + +import {until} from '#/lib/async/until' +import {logger} from '#/logger' +import {useUpdateProfileVerificationCache} from '#/state/queries/verification/useUpdateProfileVerificationCache' +import {useAgent, useSession} from '#/state/session' +import type * as bsky from '#/types/bsky' + +export function useVerificationCreateMutation() { + const agent = useAgent() + const {currentAccount} = useSession() + const updateProfileVerificationCache = useUpdateProfileVerificationCache() + + return useMutation({ + async mutationFn({profile}: {profile: bsky.profile.AnyProfileView}) { + if (!currentAccount) { + throw new Error('User not logged in') + } + + const {uri} = await agent.app.bsky.graph.verification.create( + {repo: currentAccount.did}, + { + subject: profile.did, + createdAt: new Date().toISOString(), + handle: profile.handle, + displayName: profile.displayName || '', + }, + ) + + await until( + 5, + 1e3, + ({data: profile}: AppBskyActorGetProfile.Response) => { + if ( + profile.verification && + profile.verification.verifications.find(v => v.uri === uri) + ) { + return true + } + return false + }, + () => { + return agent.getProfile({actor: profile.did ?? ''}) + }, + ) + }, + async onSuccess(_, {profile}) { + logger.metric('verification:create', {}) + await updateProfileVerificationCache({profile}) + }, + }) +} diff --git a/src/state/queries/verification/useVerificationsRemoveMutation.tsx b/src/state/queries/verification/useVerificationsRemoveMutation.tsx new file mode 100644 index 000000000..936c786c9 --- /dev/null +++ b/src/state/queries/verification/useVerificationsRemoveMutation.tsx @@ -0,0 +1,63 @@ +import { + type AppBskyActorDefs, + type AppBskyActorGetProfile, + AtUri, +} from '@atproto/api' +import {useMutation} from '@tanstack/react-query' + +import {until} from '#/lib/async/until' +import {logger} from '#/logger' +import {useUpdateProfileVerificationCache} from '#/state/queries/verification/useUpdateProfileVerificationCache' +import {useAgent, useSession} from '#/state/session' +import type * as bsky from '#/types/bsky' + +export function useVerificationsRemoveMutation() { + const agent = useAgent() + const {currentAccount} = useSession() + const updateProfileVerificationCache = useUpdateProfileVerificationCache() + + return useMutation({ + async mutationFn({ + profile, + verifications, + }: { + profile: bsky.profile.AnyProfileView + verifications: AppBskyActorDefs.VerificationView[] + }) { + if (!currentAccount) { + throw new Error('User not logged in') + } + + const uris = verifications.map(v => v.uri) + + await Promise.all( + uris.map(uri => { + return agent.app.bsky.graph.verification.delete({ + repo: currentAccount.did, + rkey: new AtUri(uri).rkey, + }) + }), + ) + + await until( + 5, + 1e3, + ({data: profile}: AppBskyActorGetProfile.Response) => { + if ( + !profile.verification?.verifications.some(v => uris.includes(v.uri)) + ) { + return true + } + return false + }, + () => { + return agent.getProfile({actor: profile.did ?? ''}) + }, + ) + }, + async onSuccess(_, {profile}) { + logger.metric('verification:revoke', {}) + await updateProfileVerificationCache({profile}) + }, + }) +} diff --git a/src/types/bsky/profile.ts b/src/types/bsky/profile.ts index 7449f117e..12c8146ae 100644 --- a/src/types/bsky/profile.ts +++ b/src/types/bsky/profile.ts @@ -1,4 +1,4 @@ -import {AppBskyActorDefs, ChatBskyActorDefs} from '@atproto/api' +import {type AppBskyActorDefs, type ChatBskyActorDefs} from '@atproto/api' /** * Matches any profile view exported by our SDK diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 2766fe625..5da530768 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -1,5 +1,5 @@ -import React from 'react' -import {LayoutAnimation, Pressable, StyleSheet, View} from 'react-native' +import {useCallback, useMemo, useState} from 'react' +import {LayoutAnimation, Pressable, View} from 'react-native' import {Image} from 'expo-image' import { AppBskyEmbedImages, @@ -12,20 +12,22 @@ import {useLingui} from '@lingui/react' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' -import {ComposerOptsPostRef} from '#/state/shell/composer' +import {type ComposerOptsPostRef} from '#/state/shell/composer' import {MaybeQuoteEmbed} from '#/view/com/util/post-embeds/QuoteEmbed' -import {Text} from '#/view/com/util/text/Text' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { const t = useTheme() const {_} = useLingui() const {embed} = replyTo - const [showFull, setShowFull] = React.useState(false) + const [showFull, setShowFull] = useState(false) - const onPress = React.useCallback(() => { + const onPress = useCallback(() => { setShowFull(prev => !prev) LayoutAnimation.configureNext({ duration: 350, @@ -33,7 +35,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { }) }, []) - const quoteEmbed = React.useMemo(() => { + const quoteEmbed = useMemo(() => { if ( AppBskyEmbedRecord.isView(embed) && AppBskyEmbedRecord.isViewRecord(embed.record) && @@ -50,7 +52,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { return null }, [embed]) - const images = React.useMemo(() => { + const images = useMemo(() => { if (AppBskyEmbedImages.isView(embed)) { return embed.images } else if ( @@ -61,17 +63,26 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { } }, [embed]) + const verification = useSimpleVerificationState({profile: replyTo.author}) + return ( + accessibilityHint=""> - - - {sanitizeDisplayName( - replyTo.author.displayName || sanitizeHandle(replyTo.author.handle), + + + + {sanitizeDisplayName( + replyTo.author.displayName || + sanitizeHandle(replyTo.author.handle), + )} + + {verification.showBadge && ( + + + )} - - - + + + {replyTo.text} @@ -112,7 +136,17 @@ function ComposerReplyToImages({ showFull: boolean }) { return ( - + {(images.length === 1 && ( ) } - -const styles = StyleSheet.create({ - replyToLayout: { - flexDirection: 'row', - alignItems: 'flex-start', - borderBottomWidth: StyleSheet.hairlineWidth, - paddingTop: 4, - paddingBottom: 16, - marginBottom: 12, - marginHorizontal: 16, - }, - replyToPost: { - flex: 1, - paddingLeft: 13, - paddingRight: 8, - }, - replyToBody: { - flexDirection: 'row', - gap: 10, - }, - replyToText: { - flex: 1, - flexGrow: 1, - }, - imagesContainer: { - borderRadius: 6, - overflow: 'hidden', - marginTop: 2, - height: 64, - width: 64, - }, -}) diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index 2b9969b54..8cc2d31ec 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -8,14 +8,14 @@ import { TouchableOpacity, View, } from 'react-native' -import {Image as RNImage} from 'react-native-image-crop-picker' +import {type Image as RNImage} from 'react-native-image-crop-picker' import Animated, {FadeOut} from 'react-native-reanimated' import {LinearGradient} from 'expo-linear-gradient' -import {AppBskyActorDefs} from '@atproto/api' +import {type AppBskyActorDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {MAX_DESCRIPTION, MAX_DISPLAY_NAME} from '#/lib/constants' +import {MAX_DESCRIPTION, MAX_DISPLAY_NAME, urls} from '#/lib/constants' import {usePalette} from '#/lib/hooks/usePalette' import {compressIfNeeded} from '#/lib/media/manip' import {cleanError} from '#/lib/strings/errors' @@ -30,6 +30,9 @@ import {Text} from '#/view/com/util/text/Text' import * as Toast from '#/view/com/util/Toast' import {EditableUserAvatar} from '#/view/com/util/UserAvatar' import {UserBanner} from '#/view/com/util/UserBanner' +import {Admonition} from '#/components/Admonition' +import {InlineLinkText} from '#/components/Link' +import {useSimpleVerificationState} from '#/components/verification' import {ErrorMessage} from '../util/error/ErrorMessage' const AnimatedTouchableOpacity = @@ -139,6 +142,10 @@ export function Component({ setImageError, _, ]) + const verification = useSimpleVerificationState({ + profile, + }) + const [touchedDisplayName, setTouchedDisplayName] = useState(false) return ( @@ -186,7 +193,26 @@ export function Component({ accessible={true} accessibilityLabel={_(msg`Display name`)} accessibilityHint={_(msg`Edit your display name`)} + onFocus={() => setTouchedDisplayName(true)} /> + + {verification.isVerified && + verification.role === 'default' && + touchedDisplayName && ( + + + + You are verified. You will lose your verification status + if you change your display name.{' '} + + Learn more. + + + + + )} diff --git a/src/view/com/notifications/NotificationFeedItem.tsx b/src/view/com/notifications/NotificationFeedItem.tsx index 8875ec02e..1de0b67b3 100644 --- a/src/view/com/notifications/NotificationFeedItem.tsx +++ b/src/view/com/notifications/NotificationFeedItem.tsx @@ -49,7 +49,7 @@ import {Post} from '#/view/com/post/Post' import {formatCount} from '#/view/com/util/numeric/format' import {TimeElapsed} from '#/view/com/util/TimeElapsed' import {PreviewableUserAvatar, UserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a, useTheme} from '#/alf' +import {atoms as a, platform, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import { ChevronBottom_Stroke2_Corner0_Rounded as ChevronDownIcon, @@ -59,12 +59,15 @@ import {Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled} from '#/compon import {PersonPlus_Filled_Stroke2_Corner0_Rounded as PersonPlusIcon} from '#/components/icons/Person' import {Repost_Stroke2_Corner2_Rounded as RepostIcon} from '#/components/icons/Repost' import {StarterPack} from '#/components/icons/StarterPack' +import {VerifiedCheck} from '#/components/icons/VerifiedCheck' import {InlineLinkText, Link} from '#/components/Link' import * as MediaPreview from '#/components/MediaPreview' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {Notification as StarterPackCard} from '#/components/StarterPack/StarterPackCard' import {SubtleWebHover} from '#/components/SubtleWebHover' import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' import * as bsky from '#/types/bsky' const MAX_AUTHORS = 5 @@ -145,6 +148,9 @@ let NotificationFeedItem = ({ const niceTimestamp = niceDate(i18n, item.notification.indexedAt) const firstAuthor = authors[0] + const firstAuthorVerification = useSimpleVerificationState({ + profile: firstAuthor.profile, + }) const firstAuthorName = sanitizeDisplayName( firstAuthor.profile.displayName || firstAuthor.profile.handle, ) @@ -186,6 +192,24 @@ let NotificationFeedItem = ({ emoji label={_(msg`Go to ${firstAuthorName}'s profile`)}> {forceLTR(firstAuthorName)} + {firstAuthorVerification.showBadge && ( + + + + )} ) const additionalAuthorsCount = authors.length - 1 @@ -366,6 +390,60 @@ let NotificationFeedItem = ({ ) + // @ts-ignore TODO + } else if (item.type === 'verified') { + a11yLabel = hasMultipleAuthors + ? _( + msg`${firstAuthorName} and ${plural(additionalAuthorsCount, { + one: `${formattedAuthorsCount} other`, + other: `${formattedAuthorsCount} others`, + })} verified you`, + ) + : _(msg`${firstAuthorName} verified you`) + notificationContent = hasMultipleAuthors ? ( + + {firstAuthorLink} and{' '} + + + {' '} + verified you + + ) : ( + {firstAuthorLink} verified you + ) + icon = + // @ts-ignore TODO + } else if (item.type === 'unverified') { + a11yLabel = hasMultipleAuthors + ? _( + msg`${firstAuthorName} and ${plural(additionalAuthorsCount, { + one: `${formattedAuthorsCount} other`, + other: `${formattedAuthorsCount} others`, + })} removed their verifications from your account`, + ) + : _(msg`${firstAuthorName} removed their verification from your account`) + notificationContent = hasMultipleAuthors ? ( + + {firstAuthorLink} and{' '} + + + {' '} + removed their verifications from your account + + ) : ( + + {firstAuthorLink} removed their verification from your account + + ) + icon = } else { return null } @@ -447,7 +525,6 @@ let NotificationFeedItem = ({ style={[ a.flex_row, a.flex_wrap, - a.pb_2xs, {paddingTop: 6}, a.self_start, a.text_md, @@ -475,7 +552,9 @@ let NotificationFeedItem = ({ {item.type === 'post-like' || item.type === 'repost' ? ( - + + + ) : null} {item.type === 'feedgen-like' && item.subjectUri ? ( {visible && authors.map(author => ( - - - - - - - - - - {sanitizeDisplayName( - author.profile.displayName || author.profile.handle, - )} - - - {sanitizeHandle(author.profile.handle, '@')} - - - - + ))} ) } +function ExpandedAuthorCard({author}: {author: Author}) { + const t = useTheme() + const {_} = useLingui() + const verification = useSimpleVerificationState({ + profile: author.profile, + }) + return ( + + + + + + + + + + {sanitizeDisplayName( + author.profile.displayName || author.profile.handle, + )} + + {verification.showBadge && ( + + + + )} + + {sanitizeHandle(author.profile.handle, '@')} + + + + + ) +} + function AdditionalPostText({post}: {post?: AppBskyFeedDefs.PostView}) { const t = useTheme() if ( @@ -761,7 +857,7 @@ function AdditionalPostText({post}: {post?: AppBskyFeedDefs.PostView}) { {text?.length > 0 && ( + style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> {text} )} diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 3c8fa31ed..dfd641f66 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -32,6 +32,7 @@ import { type Shadow, usePostShadow, } from '#/state/cache/post-shadow' +import {useProfileShadow} from '#/state/cache/profile-shadow' import {useLanguagePrefs} from '#/state/preferences' import {type ThreadPost} from '#/state/queries/post-thread' import {useSession} from '#/state/session' @@ -62,6 +63,7 @@ import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' import {SubtleWebHover} from '#/components/SubtleWebHover' import {Text} from '#/components/Typography' +import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton' import {WhoCanReply} from '#/components/WhoCanReply' import * as bsky from '#/types/bsky' @@ -207,6 +209,7 @@ let PostThreadItemLoaded = ({ () => countLines(richText?.text) >= MAX_POST_LINES, ) const {currentAccount} = useSession() + const shadowedPostAuthor = useProfileShadow(post.author) const rootUri = record.reply?.root?.uri || post.uri const postHref = React.useMemo(() => { const urip = new AtUri(post.uri) @@ -329,18 +332,35 @@ let PostThreadItemLoaded = ({ type={post.author.associated?.labeler ? 'labeler' : 'user'} /> - - - {sanitizeDisplayName( - post.author.displayName || - sanitizeHandle(post.author.handle), - moderation.ui('displayName'), - )} - - + + + + {sanitizeDisplayName( + post.author.displayName || + sanitizeHandle(post.author.handle), + moderation.ui('displayName'), + )} + + + + + + + { + return v.issuer === currentAccount?.did + }) ?? [] + return ( @@ -277,6 +290,29 @@ let ProfileMenu = ({ + {verification.viewer.role === 'verifier' && + !verification.profile.isViewer && + (verification.viewer.hasIssuedVerification ? ( + verificationRemovePromptControl.open()}> + + Remove verification + + + + ) : ( + verificationCreatePromptControl.open()}> + + Verify account + + + + ))} {!isSelf && ( <> {!profile.viewer?.blocking && @@ -410,6 +446,16 @@ let ProfileMenu = ({ onConfirm={onPressShare} confirmButtonCta={_(msg`Share anyway`)} /> + + + ) } diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index 30180b889..d5af32236 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -1,9 +1,10 @@ -import React, {memo, useCallback} from 'react' -import {StyleProp, View, ViewStyle} from 'react-native' -import {AppBskyActorDefs, ModerationDecision} from '@atproto/api' +import {memo, useCallback} from 'react' +import {type StyleProp, View, type ViewStyle} from 'react-native' +import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' +import type React from 'react' import {makeProfileLink} from '#/lib/routes/links' import {forceLTR} from '#/lib/strings/bidi' @@ -12,11 +13,14 @@ import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import {niceDate} from '#/lib/strings/time' import {isAndroid} from '#/platform/detection' +import {useProfileShadow} from '#/state/cache/profile-shadow' import {precacheProfile} from '#/state/queries/profile' -import {atoms as a, useTheme, web} from '#/alf' +import {atoms as a, platform, useTheme, web} from '#/alf' import {WebOnlyInlineLinkText} from '#/components/Link' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' import {TimeElapsed} from './TimeElapsed' import {PreviewableUserAvatar} from './UserAvatar' @@ -35,20 +39,22 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => { const t = useTheme() const {i18n, _} = useLingui() - const displayName = opts.author.displayName || opts.author.handle - const handle = opts.author.handle - const profileLink = makeProfileLink(opts.author) + const author = useProfileShadow(opts.author) + const displayName = author.displayName || author.handle + const handle = author.handle + const profileLink = makeProfileLink(author) const queryClient = useQueryClient() const onOpenAuthor = opts.onOpenAuthor const onBeforePressAuthor = useCallback(() => { - precacheProfile(queryClient, opts.author) + precacheProfile(queryClient, author) onOpenAuthor?.() - }, [queryClient, opts.author, onOpenAuthor]) + }, [queryClient, author, onOpenAuthor]) const onBeforePressPost = useCallback(() => { - precacheProfile(queryClient, opts.author) - }, [queryClient, opts.author]) + precacheProfile(queryClient, author) + }, [queryClient, author]) const timestampLabel = niceDate(i18n, opts.timestamp) + const verification = useSimpleVerificationState({profile: author}) return ( { a.flex_1, a.flex_row, a.align_center, - a.pb_2xs, + a.pb_xs, a.gap_xs, - a.z_10, + a.z_20, opts.style, ]}> {opts.showAvatar && ( )} - - - - + + + + {forceLTR( sanitizeDisplayName( displayName, opts.moderation?.ui('displayName'), ), )} - - - - + + {verification.showBadge && ( + + + + )} + {NON_BREAKING_SPACE + sanitizeHandle(handle, '@')} - - - - + + + - {!isAndroid && ( - - · - - )} - - - {({timeElapsed}) => ( - - {timeElapsed} - - )} - + + {({timeElapsed}) => ( + + {!isAndroid && ( + + ·{' '} + + )} + {timeElapsed} + + )} + + ) } diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index e38cb217c..d51db3960 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -51,6 +51,8 @@ import { } from '#/components/icons/UserCircle' import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' +import {useSimpleVerificationState} from '#/components/verification' +import {VerificationCheck} from '#/components/verification/VerificationCheck' const iconWidth = 26 @@ -64,6 +66,7 @@ let DrawerProfileCard = ({ const {_, i18n} = useLingui() const t = useTheme() const {data: profile} = useProfileQuery({did: account.did}) + const verification = useSimpleVerificationState({profile}) return ( + style={[a.gap_sm, a.pr_lg]}> - - {profile?.displayName || account.handle} - + + + {profile?.displayName || account.handle} + + {verification.showBadge && ( + + + + )} +