From 8d7a7369aa868babb112edcbb2ec6530f47d3462 Mon Sep 17 00:00:00 2001 From: DS Boyce <260543580+ds-boyce@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:06:08 -0700 Subject: [PATCH] Display beta badge when isBetaUser is true (#11160) --- src/components/BetaBadge.tsx | 104 ++++++++++++++++++ src/components/BotBadge.tsx | 6 +- src/components/ProfileBadges.tsx | 72 ++++++++++-- .../verification/VerificationCheckButton.tsx | 28 +++-- 4 files changed, 187 insertions(+), 23 deletions(-) create mode 100644 src/components/BetaBadge.tsx diff --git a/src/components/BetaBadge.tsx b/src/components/BetaBadge.tsx new file mode 100644 index 0000000000..115f8d0046 --- /dev/null +++ b/src/components/BetaBadge.tsx @@ -0,0 +1,104 @@ +import {useState} from 'react' +import {type Insets, Pressable, View} from 'react-native' +import {Trans, useLingui} from '@lingui/react/macro' + +import {usePreferencesQuery} from '#/state/queries/preferences' +import {useSession} from '#/state/session' +import {atoms as a, useTheme} from '#/alf' +import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker' +import * as Tooltip from '#/components/Tooltip' +import type * as bsky from '#/types/bsky' + +/** + * Whether to show the beta badge for a given profile. Only shown on the + * viewer's own profile, and only when the viewer has opted in to beta features. + */ +export function useIsBetaBadgeVisible( + profile: bsky.profile.AnyProfileView, +): boolean { + const {currentAccount} = useSession() + const {data: preferences} = usePreferencesQuery() + const isBetaUser = preferences?.bskyAppState?.isBetaUser ?? false + const isSelf = currentAccount?.did === profile.did + + return isSelf && isBetaUser +} + +export function BetaBadge({ + profile, + width, + padding, +}: { + profile: bsky.profile.AnyProfileView + width: number + padding: number +}) { + const t = useTheme() + const isVisible = useIsBetaBadgeVisible(profile) + + if (!isVisible) return null + + return ( + + + + ) +} + +export function BetaBadgeButton({ + profile, + width, + padding, + hitSlop, +}: { + profile: bsky.profile.AnyProfileView + width: number + padding: number + hitSlop: Insets +}) { + const t = useTheme() + const {t: l} = useLingui() + const isVisible = useIsBetaBadgeVisible(profile) + + const [tooltipVisible, setTooltipVisible] = useState(false) + + if (!isVisible) return null + + return ( + + + [ + a.rounded_full, + a.transition_transform, + { + backgroundColor: t.palette.primary_50, + padding, + transform: [ + { + scale: hovered ? 1.1 : 1, + }, + ], + }, + ]} + onPress={() => setTooltipVisible(v => !v)}> + + + + + Beta features enabled + + + ) +} diff --git a/src/components/BotBadge.tsx b/src/components/BotBadge.tsx index 83da49bc4e..b5e6f867b6 100644 --- a/src/components/BotBadge.tsx +++ b/src/components/BotBadge.tsx @@ -1,4 +1,4 @@ -import {View} from 'react-native' +import {type Insets, View} from 'react-native' import {type ComAtprotoLabelDefs} from '@atproto/api' import {useLingui} from '@lingui/react/macro' @@ -44,9 +44,11 @@ export function BotBadge({ export function BotBadgeButton({ profile, width, + hitSlop, }: { profile: bsky.profile.AnyProfileView width: number + hitSlop: Insets }) { const t = useTheme() const ax = useAnalytics() @@ -61,7 +63,7 @@ export function BotBadgeButton({ <> - -