diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx
index 2e5e39aaa4..682fceee5a 100644
--- a/src/components/AccountList.tsx
+++ b/src/components/AccountList.tsx
@@ -12,14 +12,12 @@ import {useProfilesQuery} from '#/state/queries/profile'
import {type SessionAccount, useSession} from '#/state/session'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {Button} from '#/components/Button'
import {CheckThick_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronIcon} from '#/components/icons/Chevron'
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
-import {useSimpleVerificationState} from '#/components/verification'
-import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {useActorStatus} from '#/features/liveNow'
export function AccountList({
@@ -53,18 +51,26 @@ export function AccountList({
a.border,
t.atoms.border_contrast_low,
]}>
- {accounts.map(account => (
-
- p.did === account.did)}
- account={account}
- onSelect={onSelectAccount}
- isCurrentAccount={account.did === currentAccount?.did}
- isPendingAccount={account.did === pendingDid}
- />
-
-
- ))}
+ {accounts
+ .map(account => ({
+ account,
+ profile: profiles?.profiles.find(p => p.did === account.did),
+ }))
+ .filter(item => {
+ return !!item.profile
+ })
+ .map(({account, profile}) => (
+
+
+
+
+ ))}
-
+
>
)
}
diff --git a/src/components/PostControls/ShareMenu/RecentChats.tsx b/src/components/PostControls/ShareMenu/RecentChats.tsx
index 07943d073c..8bc2aad058 100644
--- a/src/components/PostControls/ShareMenu/RecentChats.tsx
+++ b/src/components/PostControls/ShareMenu/RecentChats.tsx
@@ -15,12 +15,10 @@ import {useListConvosQuery} from '#/state/queries/messages/list-conversations'
import {useSession} from '#/state/session'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, tokens, useTheme} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {Button} from '#/components/Button'
import {useDialogContext} from '#/components/Dialog'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
-import {useSimpleVerificationState} from '#/components/verification'
-import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {useAnalytics} from '#/analytics'
import type * as bsky from '#/types/bsky'
@@ -112,7 +110,6 @@ function RecentChatItem({
profile.displayName || sanitizeHandle(profile.handle),
moderation.ui('displayName'),
)
- const verification = useSimpleVerificationState({profile})
if (isBlockedOrBlocking(profile) || isMuted(profile)) {
return null
@@ -142,15 +139,7 @@ function RecentChatItem({
numberOfLines={1}>
{name}
- {verification.showBadge && (
-
-
-
- )}
-
+
)
diff --git a/src/components/ProfileBadges.tsx b/src/components/ProfileBadges.tsx
new file mode 100644
index 0000000000..e7441962ea
--- /dev/null
+++ b/src/components/ProfileBadges.tsx
@@ -0,0 +1,48 @@
+import {View} from 'react-native'
+
+import {isBotAccount} from '#/lib/bots'
+import {useProfileShadow} from '#/state/cache/profile-shadow'
+import {atoms as a, type ViewStyleProp} from '#/alf'
+import {BotBadge, BotBadgeButton} from '#/components/BotBadge'
+import {useSimpleVerificationState} from '#/components/verification'
+import {VerificationCheck} from '#/components/verification/VerificationCheck'
+import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton'
+import type * as bsky from '#/types/bsky'
+
+export function ProfileBadges({
+ profile,
+ interactive = false,
+ size,
+ style,
+}: ViewStyleProp & {
+ profile: bsky.profile.AnyProfileView
+ interactive?: boolean
+ size: 'lg' | 'md' | 'sm'
+}) {
+ const shadowed = useProfileShadow(profile)
+ const verification = useSimpleVerificationState({profile})
+
+ // if nothing to show, don't render the container at all
+ if (!verification.showBadge && !isBotAccount(shadowed)) return null
+
+ return (
+
+ {interactive ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+ {verification.showBadge && (
+
+ )}
+
+ >
+ )}
+
+ )
+}
diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx
index a3bc25f473..4382b9cd36 100644
--- a/src/components/ProfileCard.tsx
+++ b/src/components/ProfileCard.tsx
@@ -31,7 +31,6 @@ import {
useTheme,
type ViewStyleProp,
} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {
Button,
ButtonIcon,
@@ -42,10 +41,9 @@ import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {Link as InternalLink, type LinkProps} from '#/components/Link'
import * as Pills from '#/components/Pills'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
-import {useSimpleVerificationState} from '#/components/verification'
-import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {type Metrics} from '#/analytics'
import {useActorStatus} from '#/features/liveNow'
import type * as bsky from '#/types/bsky'
@@ -243,7 +241,6 @@ function InlineNameAndHandle({
moderationOpts: ModerationOpts
}) {
const t = useTheme()
- const verification = useSimpleVerificationState({profile})
const moderation = moderateProfile(profile, moderationOpts)
const name = sanitizeDisplayName(
profile.displayName || sanitizeHandle(profile.handle),
@@ -263,27 +260,15 @@ function InlineNameAndHandle({
numberOfLines={1}>
{forceLTR(name)}
- {verification.showBadge && (
-
-
-
- )}
-
-
-
+ ]}
+ />
{name}
- {verification.showBadge && (
-
-
-
- )}
-
-
-
+
)
}
diff --git a/src/components/ProfileHoverCard/index.web.tsx b/src/components/ProfileHoverCard/index.web.tsx
index 938bdf330c..c0996fe4da 100644
--- a/src/components/ProfileHoverCard/index.web.tsx
+++ b/src/components/ProfileHoverCard/index.web.tsx
@@ -23,7 +23,6 @@ import {formatCount} from '#/view/com/util/numeric/format'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {ProfileHeaderHandle} from '#/screens/Profile/Header/Handle'
import {atoms as a, useTheme} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {useFollowMethods} from '#/components/hooks/useFollowMethods'
import {useRichText} from '#/components/hooks/useRichText'
@@ -37,10 +36,9 @@ import {InlineLinkText, Link} from '#/components/Link'
import {Loader} from '#/components/Loader'
import * as Pills from '#/components/Pills'
import {Portal} from '#/components/Portal'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
-import {useSimpleVerificationState} from '#/components/verification'
-import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {IS_WEB_TOUCH_DEVICE} from '#/env'
import {useActorStatus} from '#/features/liveNow'
import {LiveStatus} from '#/features/liveNow/components/LiveStatusDialog'
@@ -460,7 +458,6 @@ function Inner({
[currentAccount, profile],
)
const isLabeler = profile.associated?.labeler
- const verification = useSimpleVerificationState({profile})
return (
@@ -528,21 +525,16 @@ function Inner({
moderation.ui('displayName'),
)}
- {verification.showBadge && (
-
-
-
- )}
-
+
diff --git a/src/components/dms/MessagesListHeader.tsx b/src/components/dms/MessagesListHeader.tsx
index 1f87c77371..9b1a695e18 100644
--- a/src/components/dms/MessagesListHeader.tsx
+++ b/src/components/dms/MessagesListHeader.tsx
@@ -15,15 +15,13 @@ import {isConvoActive, useConvo} from '#/state/messages/convo'
import {type ConvoItem} from '#/state/messages/convo/types'
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme, web} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {ConvoMenu} from '#/components/dms/ConvoMenu'
import {Bell2Off_Filled_Corner0_Rounded as BellStroke} from '#/components/icons/Bell2'
import * as Layout from '#/components/Layout'
import {Link} from '#/components/Link'
import {PostAlerts} from '#/components/moderation/PostAlerts'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
-import {useSimpleVerificationState} from '#/components/verification'
-import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {IS_WEB} from '#/env'
const PFP_SIZE = IS_WEB ? 40 : Layout.HEADER_SLOT_SIZE
@@ -113,9 +111,6 @@ function HeaderReady({
const {_} = useLingui()
const t = useTheme()
const convoState = useConvo()
- const verification = useSimpleVerificationState({
- profile,
- })
const isDeletedAccount = profile?.handle === 'missing.invalid'
const displayName = isDeletedAccount
@@ -162,15 +157,7 @@ function HeaderReady({
numberOfLines={1}>
{displayName}
- {verification.showBadge && (
-
-
-
- )}
-
+
{!isDeletedAccount && (
0
- const verification = useSimpleVerificationState({
- profile,
- })
const blockInfo = useMemo(() => {
const modui = moderation.ui('profileView')
@@ -415,15 +410,11 @@ function ChatListItemReady({
{displayName}
- {verification.showBadge && (
-
-
-
- )}
-
+
{lastMessageSentAt && (
diff --git a/src/screens/PostThread/components/ThreadItemAnchor.tsx b/src/screens/PostThread/components/ThreadItemAnchor.tsx
index 80ebec2b8c..8a98f11d7c 100644
--- a/src/screens/PostThread/components/ThreadItemAnchor.tsx
+++ b/src/screens/PostThread/components/ThreadItemAnchor.tsx
@@ -34,7 +34,6 @@ import {
REPLY_LINE_WIDTH,
} from '#/screens/PostThread/const'
import {atoms as a, useTheme} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {Button} from '#/components/Button'
import {DebugFieldDisplay} from '#/components/DebugFieldDisplay'
import {CalendarClock_Stroke2_Corner0_Rounded as CalendarClockIcon} from '#/components/icons/CalendarClock'
@@ -48,12 +47,12 @@ import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
import {TranslatedPost} from '#/components/Post/Translated'
import {PostControls, PostControlsSkeleton} from '#/components/PostControls'
import {useFormatPostStatCount} from '#/components/PostControls/util'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText'
import * as Skele from '#/components/Skeleton'
import {Text} from '#/components/Typography'
-import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton'
import {WhoCanReply} from '#/components/WhoCanReply'
import {useAnalytics} from '#/analytics'
import {useActorStatus} from '#/features/liveNow'
@@ -363,9 +362,12 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
-
+
-
-
-
-
-
+
diff --git a/src/screens/Search/components/SearchHistory.tsx b/src/screens/Search/components/SearchHistory.tsx
index 6cae572c93..b27834a605 100644
--- a/src/screens/Search/components/SearchHistory.tsx
+++ b/src/screens/Search/components/SearchHistory.tsx
@@ -10,14 +10,12 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture'
import {atoms as a} from '#/alf'
-import {BotBadge} from '#/components/BotBadge'
import {Button, ButtonIcon} from '#/components/Button'
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
import * as Layout from '#/components/Layout'
import {Link} from '#/components/Link'
+import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
-import {useSimpleVerificationState} from '#/components/verification'
-import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {useAnalytics} from '#/analytics'
import type * as bsky from '#/types/bsky'
@@ -140,7 +138,6 @@ function RecentProfileItem({
profile.displayName || sanitizeHandle(profile.handle),
moderation.ui('displayName'),
)
- const verification = useSimpleVerificationState({profile})
return (
@@ -166,15 +163,7 @@ function RecentProfileItem({
{name}
- {verification.showBadge && (
-
-
-
- )}
-
+