diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx
index 4a692748c..243d52977 100644
--- a/src/components/AccountList.tsx
+++ b/src/components/AccountList.tsx
@@ -17,7 +17,6 @@ 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 {PdsBadge} from '#/components/PdsBadge'
import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
import {useActorStatus} from '#/features/liveNow'
@@ -168,7 +167,6 @@ function AccountItem({
profile?.displayName || profile?.handle || account.handle,
)}
-
{profile && (
- if (!data) return null
- if (hideBskyPds && data.isBsky) return null
-
- return (
-
- )
-}
-
-function PdsBadgeLoading({
- size,
- isBsky = false,
-}: {
- size: 'lg' | 'md' | 'sm'
- isBsky?: boolean
-}) {
- const {gtPhone} = useBreakpoints()
- let dimensions = 12
- if (size === 'lg') {
- dimensions = gtPhone ? 20 : 18
- } else if (size === 'md') {
- dimensions = 14
- }
- return (
-
-
-
- )
-}
-
-function PdsBadgeInner({
- pdsUrl,
- faviconUrl,
- isBsky,
- isBridged,
- size,
- interactive,
-}: {
- pdsUrl: string
- faviconUrl: string | undefined
- isBsky: boolean
- isBridged: boolean
- size: 'lg' | 'md' | 'sm'
- interactive: boolean
-}) {
- const {_} = useLingui()
- const {gtPhone} = useBreakpoints()
- const dialogControl = Dialog.useDialogControl()
-
- let dimensions = 12
- if (size === 'lg') {
- dimensions = gtPhone ? 20 : 18
- } else if (size === 'md') {
- dimensions = 14
- }
-
- const icon = (
-
- )
-
- if (!interactive) {
- return (
-
- {icon}
-
- )
- }
-
- return (
- <>
-
-
-
- >
- )
-}
diff --git a/src/components/ProfileBadges.tsx b/src/components/ProfileBadges.tsx
index f7e46f586..95ac5406d 100644
--- a/src/components/ProfileBadges.tsx
+++ b/src/components/ProfileBadges.tsx
@@ -1,12 +1,23 @@
import {useWindowDimensions, View} from 'react-native'
+import {msg} from '@lingui/core/macro'
+import {useLingui} from '@lingui/react'
import {useProfileShadow} from '#/state/cache/profile-shadow'
+import {
+ usePdsLabelEnabled,
+ usePdsLabelHideBskyPds,
+} from '#/state/preferences/pds-label'
+import {usePdsFaviconQuery, usePdsLabelQuery} from '#/state/queries/pds-label'
import {atoms as a, useAlf, type ViewStyleProp} from '#/alf'
import {BotBadge, BotBadgeButton, isBotAccount} from '#/components/BotBadge'
+import {Button} from '#/components/Button'
+import * as Dialog from '#/components/Dialog'
+import {PdsBadgeIcon, PdsDialog} from '#/components/PdsDialog'
import {isPetAccount, PetBadge, PetBadgeButton} from '#/components/PetBadge'
import {useSimpleVerificationState} from '#/components/verification'
import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton'
+import {IS_WEB} from '#/env'
import type * as bsky from '#/types/bsky'
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
@@ -30,22 +41,44 @@ const botIconSizes: Record = {
export function ProfileBadges({
profile,
interactive = false,
+ pdsInteractive = true,
size,
style,
}: ViewStyleProp & {
profile: bsky.profile.AnyProfileView
interactive?: boolean
+ pdsInteractive?: boolean
size: Size
}) {
const shadowed = useProfileShadow(profile)
const verification = useSimpleVerificationState({profile})
+ const pdsLabelEnabled = usePdsLabelEnabled()
+ const hideBskyPds = usePdsLabelHideBskyPds()
+ const {data: pdsData, isLoading: isPdsLoading} = usePdsLabelQuery(
+ pdsLabelEnabled ? shadowed.did : undefined,
+ )
+ const {data: pdsFaviconUrl} = usePdsFaviconQuery(
+ pdsData && !pdsData.isBsky && !pdsData.isBridged
+ ? pdsData.pdsUrl
+ : undefined,
+ )
const {fontScale: nativeScaleMultiplier} = useWindowDimensions()
const {
fonts: {scaleMultiplier: alfScaleMultiplier},
} = useAlf()
+ const isBskyHandle =
+ !!shadowed.handle &&
+ (shadowed.handle.endsWith('.bsky.social') ||
+ shadowed.handle === 'bsky.social')
+
+ const showPdsBadge =
+ pdsLabelEnabled &&
+ (isPdsLoading || (!!pdsData && !(hideBskyPds && pdsData.isBsky)))
+
// if nothing to show, don't render the container at all
if (
+ !showPdsBadge &&
!verification.showBadge &&
!isBotAccount(shadowed) &&
!isPetAccount(shadowed)
@@ -67,6 +100,17 @@ export function ProfileBadges({
isOnTheSmallSide ? a.gap_2xs : a.gap_xs,
style,
]}>
+ {showPdsBadge && (
+
+ )}
{interactive ? (
<>
)
}
+
+function pdsIconDimensions(size: Size) {
+ switch (size) {
+ case 'md':
+ return 14
+ case 'lg':
+ return 20
+ case 'xl':
+ return 24
+ default:
+ return 12
+ }
+}
+
+function PdsInlineIcon({
+ size,
+ interactive,
+ isLoading,
+ isBsky,
+ isBridged,
+ pdsUrl,
+ faviconUrl,
+}: {
+ size: Size
+ interactive: boolean
+ isLoading: boolean
+ isBsky: boolean
+ isBridged: boolean
+ pdsUrl?: string
+ faviconUrl?: string
+}) {
+ const {_} = useLingui()
+ const dialogControl = Dialog.useDialogControl()
+ const dimensions = pdsIconDimensions(size)
+
+ const icon = (
+
+ )
+
+ if (isLoading || !pdsUrl || !interactive) {
+ return (
+
+ {icon}
+
+ )
+ }
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx
index e8b49d0b6..d10fc08a0 100644
--- a/src/components/ProfileCard.tsx
+++ b/src/components/ProfileCard.tsx
@@ -40,7 +40,6 @@ import {
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 {PdsBadge} from '#/components/PdsBadge'
import * as Pills from '#/components/Pills'
import {ProfileBadges} from '#/components/ProfileBadges'
import {RichText} from '#/components/RichText'
@@ -269,17 +268,8 @@ function InlineNameAndHandle({
a.self_center,
{marginTop: platform({default: 0, android: -1})},
]}>
-
+
-
{name}
-
-
-
)
diff --git a/src/components/ProfileHoverCard/index.web.tsx b/src/components/ProfileHoverCard/index.web.tsx
index 3182b617b..758764dd7 100644
--- a/src/components/ProfileHoverCard/index.web.tsx
+++ b/src/components/ProfileHoverCard/index.web.tsx
@@ -38,7 +38,6 @@ import {
} from '#/components/KnownFollowers'
import {InlineLinkText, Link} from '#/components/Link'
import {Loader} from '#/components/Loader'
-import {PdsBadge} from '#/components/PdsBadge'
import * as Pills from '#/components/Pills'
import {Portal} from '#/components/Portal'
import {ProfileBadges} from '#/components/ProfileBadges'
@@ -545,12 +544,10 @@ function Inner({
moderation.ui('displayName'),
)}
-
-
-
{displayName}
-
-
-
{!isDeletedAccount && (
diff --git a/src/screens/Messages/components/ChatListItem.tsx b/src/screens/Messages/components/ChatListItem.tsx
index a78d46cd3..9f8d97792 100644
--- a/src/screens/Messages/components/ChatListItem.tsx
+++ b/src/screens/Messages/components/ChatListItem.tsx
@@ -41,7 +41,6 @@ import {Trash_Stroke2_Corner0_Rounded} from '#/components/icons/Trash'
import {Link} from '#/components/Link'
import {useMenuControl} from '#/components/Menu'
import {PostAlerts} from '#/components/moderation/PostAlerts'
-import {PdsBadge} from '#/components/PdsBadge'
import {createPortalGroup} from '#/components/Portal'
import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
@@ -415,9 +414,6 @@ function ChatListItemReady({
{displayName}
-
-
-
-
-
-
+
diff --git a/src/screens/Profile/Header/ProfileHeaderStandard.tsx b/src/screens/Profile/Header/ProfileHeaderStandard.tsx
index 71d8904fb..838180e20 100644
--- a/src/screens/Profile/Header/ProfileHeaderStandard.tsx
+++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx
@@ -50,7 +50,6 @@ import {
shouldShowKnownFollowers,
} from '#/components/KnownFollowers'
import {Link} from '#/components/Link'
-import {PdsBadge} from '#/components/PdsBadge'
import {ProfileBadges} from '#/components/ProfileBadges'
import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText'
@@ -202,7 +201,6 @@ let ProfileHeaderStandard = ({
a.align_center,
{marginTop: platform({ios: 2})},
]}>
-
diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx
index 663064559..597a9a33a 100644
--- a/src/view/com/composer/ComposerReplyTo.tsx
+++ b/src/view/com/composer/ComposerReplyTo.tsx
@@ -16,7 +16,6 @@ import {sanitizePronouns} from '#/lib/strings/pronouns'
import {type ComposerOptsPostRef} from '#/state/shell/composer'
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme, web} from '#/alf'
-import {PdsBadge} from '#/components/PdsBadge'
import {QuoteEmbed} from '#/components/Post/Embed'
import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
@@ -108,9 +107,6 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
sanitizeHandle(replyTo.author.handle),
)}
-
-
-
{replyTo.author?.pronouns && (
{showFull && parsedQuoteEmbed && parsedQuoteEmbed.type === 'post' && (
-
+
)}
diff --git a/src/view/com/composer/text-input/mobile/Autocomplete.tsx b/src/view/com/composer/text-input/mobile/Autocomplete.tsx
index 677f25c17..9621ebd82 100644
--- a/src/view/com/composer/text-input/mobile/Autocomplete.tsx
+++ b/src/view/com/composer/text-input/mobile/Autocomplete.tsx
@@ -9,7 +9,6 @@ import {sanitizeHandle} from '#/lib/strings/handles'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, platform, useTheme} from '#/alf'
-import {PdsBadge} from '#/components/PdsBadge'
import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
@@ -114,9 +113,6 @@ function AutocompleteProfileCard({
numberOfLines={1}>
{displayName}
-
-
-
-
-
-
{
-
-
-
+ ]}
+ />
{profile?.displayName || account.handle}
-
{profile && }