jerrification badge (pls no spoil)
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle cx="12" cy="12" r="12" fill="#006AFF"/><path fill="#fff" d="M15.117 7.116a1.25 1.25 0 0 1 1.767 1.768L13.767 12l3.2 3.2a1.25 1.25 0 0 1-1.767 1.768l-3.2-3.2-3.116 3.116a1.25 1.25 0 1 1-1.767-1.768L10.232 12 7.2 8.967A1.25 1.25 0 1 1 8.967 7.2L12 10.232l3.118-3.116Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 355 B |
@@ -1043,4 +1043,6 @@ export type Events = {
|
|||||||
'profile:associated:germ:click-self-info': {}
|
'profile:associated:germ:click-self-info': {}
|
||||||
'profile:associated:germ:self-disconnect': {}
|
'profile:associated:germ:self-disconnect': {}
|
||||||
'profile:associated:germ:self-reconnect': {}
|
'profile:associated:germ:self-reconnect': {}
|
||||||
|
|
||||||
|
'jerry:no': {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import {useSimpleVerificationState} from '#/components/verification'
|
|||||||
import {VerificationCheck} from '#/components/verification/VerificationCheck'
|
import {VerificationCheck} from '#/components/verification/VerificationCheck'
|
||||||
import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton'
|
import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
|
import {
|
||||||
|
isJerrifiedAccount,
|
||||||
|
JerrifiedBadge,
|
||||||
|
} from './verification/aprilFools/JerrifiedBadge'
|
||||||
|
import {JerrifiedBadgeButton} from './verification/aprilFools/JerrifiedBadgeButton'
|
||||||
|
|
||||||
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
||||||
|
|
||||||
@@ -39,8 +44,11 @@ export function ProfileBadges({
|
|||||||
const shadowed = useProfileShadow(profile)
|
const shadowed = useProfileShadow(profile)
|
||||||
const verification = useSimpleVerificationState({profile})
|
const verification = useSimpleVerificationState({profile})
|
||||||
|
|
||||||
|
const isJerry = isJerrifiedAccount(profile)
|
||||||
|
|
||||||
// if nothing to show, don't render the container at all
|
// if nothing to show, don't render the container at all
|
||||||
if (!verification.showBadge && !isBotAccount(shadowed)) return null
|
if (!verification.showBadge && !isBotAccount(shadowed) && !isJerry)
|
||||||
|
return null
|
||||||
|
|
||||||
const isOnTheSmallSide = size === 'xs' || size === 'sm'
|
const isOnTheSmallSide = size === 'xs' || size === 'sm'
|
||||||
|
|
||||||
@@ -54,6 +62,12 @@ export function ProfileBadges({
|
|||||||
]}>
|
]}>
|
||||||
{interactive ? (
|
{interactive ? (
|
||||||
<>
|
<>
|
||||||
|
{isJerry && (
|
||||||
|
<JerrifiedBadgeButton
|
||||||
|
profile={profile}
|
||||||
|
width={verificationIconSizes[size]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<VerificationCheckButton
|
<VerificationCheckButton
|
||||||
profile={shadowed}
|
profile={shadowed}
|
||||||
width={verificationIconSizes[size]}
|
width={verificationIconSizes[size]}
|
||||||
@@ -62,6 +76,7 @@ export function ProfileBadges({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
{isJerry && <JerrifiedBadge width={verificationIconSizes[size]} />}
|
||||||
{verification.showBadge && (
|
{verification.showBadge && (
|
||||||
<VerificationCheck
|
<VerificationCheck
|
||||||
verifier={verification.role === 'verifier'}
|
verifier={verification.role === 'verifier'}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import {forwardRef} from 'react'
|
||||||
|
import Svg, {Circle, Path} from 'react-native-svg'
|
||||||
|
|
||||||
|
import {type Props, useCommonSVGProps} from '#/components/icons/common'
|
||||||
|
|
||||||
|
export const UnverifiedX = forwardRef<Svg, Props>(
|
||||||
|
function LogoImpl(props, ref) {
|
||||||
|
const {fill, size, style, ...rest} = useCommonSVGProps(props)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
fill="none"
|
||||||
|
{...rest}
|
||||||
|
ref={ref}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
style={[style]}>
|
||||||
|
<Circle cx="12" cy="12" r="11.5" fill={fill} />
|
||||||
|
<Path
|
||||||
|
fill="#fff"
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M15.117 7.116a1.25 1.25 0 0 1 1.767 1.768L13.767 12l3.2 3.2a1.25 1.25 0 0 1-1.767 1.768l-3.2-3.2-3.116 3.116a1.25 1.25 0 1 1-1.767-1.768L10.232 12 7.2 8.967A1.25 1.25 0 1 1 8.967 7.2L12 10.232l3.118-3.116Z"
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import {UnverifiedX} from '#/components/icons/UnverifiedX'
|
||||||
|
import type * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
|
const JERRY = 'did:plc:vc7f4oafdgxsihk4cry2xpze'
|
||||||
|
|
||||||
|
export function isJerrifiedAccount(profile: bsky.profile.AnyProfileView) {
|
||||||
|
return profile.did === JERRY
|
||||||
|
}
|
||||||
|
|
||||||
|
export function JerrifiedBadge({width}: {width: number}) {
|
||||||
|
return <UnverifiedX width={width} />
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import {View} from 'react-native'
|
||||||
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
|
import {atoms as a, web} from '#/alf'
|
||||||
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
|
import * as Dialog from '#/components/Dialog'
|
||||||
|
import {UnverifiedX} from '#/components/icons/UnverifiedX'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
import {useAnalytics} from '#/analytics'
|
||||||
|
import type * as bsky from '#/types/bsky'
|
||||||
|
import {JerrifiedBadge} from './JerrifiedBadge'
|
||||||
|
|
||||||
|
export function JerrifiedBadgeButton({
|
||||||
|
profile,
|
||||||
|
width,
|
||||||
|
}: {
|
||||||
|
profile: bsky.profile.AnyProfileView
|
||||||
|
width: number
|
||||||
|
}) {
|
||||||
|
const {t: l} = useLingui()
|
||||||
|
const ax = useAnalytics()
|
||||||
|
const control = Dialog.useDialogControl()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
label={l`Unverified account`}
|
||||||
|
hitSlop={20}
|
||||||
|
onPress={evt => {
|
||||||
|
evt.preventDefault()
|
||||||
|
control.open()
|
||||||
|
}}>
|
||||||
|
{({hovered}) => (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.justify_end,
|
||||||
|
a.align_end,
|
||||||
|
a.transition_transform,
|
||||||
|
{
|
||||||
|
width: width,
|
||||||
|
height: width,
|
||||||
|
transform: [{scale: hovered ? 1.1 : 1}],
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<UnverifiedX width={width} />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
||||||
|
<Dialog.Handle />
|
||||||
|
<Dialog.ScrollableInner
|
||||||
|
label={l`Unverified account`}
|
||||||
|
style={web({maxWidth: 350})}
|
||||||
|
contentContainerStyle={a.gap_sm}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.py_lg,
|
||||||
|
a.align_center,
|
||||||
|
a.flex_row,
|
||||||
|
a.justify_center,
|
||||||
|
]}>
|
||||||
|
<UserAvatar
|
||||||
|
avatar={profile.avatar}
|
||||||
|
type="user"
|
||||||
|
size={60}
|
||||||
|
noBorder
|
||||||
|
/>
|
||||||
|
<View style={[{opacity: 0.5}, a.absolute, a.z_10]}>
|
||||||
|
<JerrifiedBadge width={64} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={[a.text_2xl, a.font_bold, a.leading_snug]}>
|
||||||
|
<Trans>Jerry is unverified</Trans>
|
||||||
|
</Text>
|
||||||
|
<Text style={[a.text_md, a.leading_snug]}>
|
||||||
|
<Trans>Do not trust this user under any circumstances.</Trans>
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
color="primary"
|
||||||
|
onPress={() => {
|
||||||
|
ax.metric('jerry:no', {})
|
||||||
|
control.close()
|
||||||
|
}}
|
||||||
|
label={l`Jerry, no!`}
|
||||||
|
style={[a.mt_sm]}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Jerry, no!</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
onPress={() => control.close()}
|
||||||
|
label={l`Close`}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Close</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
<Dialog.Close />
|
||||||
|
</Dialog.ScrollableInner>
|
||||||
|
</Dialog.Outer>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user