Bluesky app fork with some witchin' additions 馃挮
at main 156 lines 4.2 kB view raw
1import {View} from 'react-native' 2import {msg} from '@lingui/macro' 3import {useLingui} from '@lingui/react' 4 5import {type Shadow} from '#/state/cache/types' 6import {atoms as a, useBreakpoints, useTheme} from '#/alf' 7import {Button} from '#/components/Button' 8import {useDialogControl} from '#/components/Dialog' 9import {useFullVerificationState} from '#/components/verification' 10import {type FullVerificationState} from '#/components/verification' 11import {VerificationCheck} from '#/components/verification/VerificationCheck' 12import {VerificationsDialog} from '#/components/verification/VerificationsDialog' 13import {VerifierDialog} from '#/components/verification/VerifierDialog' 14import {useAnalytics} from '#/analytics' 15import type * as bsky from '#/types/bsky' 16 17export function shouldShowVerificationCheckButton( 18 state: FullVerificationState, 19) { 20 let ok = false 21 22 if (state.profile.role === 'default') { 23 if (state.profile.isVerified) { 24 ok = true 25 } else if (state.profile.isViewer && state.profile.wasVerified) { 26 ok = true 27 } else if ( 28 state.viewer.role === 'verifier' && 29 state.viewer.hasIssuedVerification 30 ) { 31 ok = true 32 } 33 } else if (state.profile.role === 'verifier') { 34 if (state.profile.isViewer) { 35 ok = true 36 } else if (state.profile.isVerified) { 37 ok = true 38 } 39 } 40 41 if ( 42 !state.profile.showBadge && 43 !state.profile.isViewer && 44 !(state.viewer.role === 'verifier' && state.viewer.hasIssuedVerification) 45 ) { 46 ok = false 47 } 48 49 return ok 50} 51 52export function VerificationCheckButton({ 53 profile, 54 size, 55}: { 56 profile: Shadow<bsky.profile.AnyProfileView> 57 size: 'lg' | 'md' | 'sm' 58}) { 59 const state = useFullVerificationState({ 60 profile, 61 }) 62 63 if (shouldShowVerificationCheckButton(state)) { 64 return <Badge profile={profile} verificationState={state} size={size} /> 65 } 66 67 return null 68} 69 70export function Badge({ 71 profile, 72 verificationState: state, 73 size, 74}: { 75 profile: Shadow<bsky.profile.AnyProfileView> 76 verificationState: FullVerificationState 77 size: 'lg' | 'md' | 'sm' 78}) { 79 const t = useTheme() 80 const ax = useAnalytics() 81 const {_} = useLingui() 82 const verificationsDialogControl = useDialogControl() 83 const verifierDialogControl = useDialogControl() 84 const {gtPhone} = useBreakpoints() 85 let dimensions = 12 86 if (size === 'lg') { 87 dimensions = gtPhone ? 20 : 18 88 } else if (size === 'md') { 89 dimensions = 14 90 } 91 92 const verifiedByHidden = !state.profile.showBadge && state.profile.isViewer 93 94 return ( 95 <> 96 <Button 97 label={ 98 state.profile.isViewer 99 ? _(msg`View your verifications`) 100 : _(msg`View this user's verifications`) 101 } 102 hitSlop={20} 103 onPress={evt => { 104 evt.preventDefault() 105 ax.metric('verification:badge:click', {}) 106 if (state.profile.role === 'verifier') { 107 verifierDialogControl.open() 108 } else { 109 verificationsDialogControl.open() 110 } 111 }}> 112 {({hovered}) => ( 113 <View 114 style={[ 115 a.justify_end, 116 a.align_end, 117 a.transition_transform, 118 { 119 width: dimensions, 120 height: dimensions, 121 transform: [ 122 { 123 scale: hovered ? 1.1 : 1, 124 }, 125 ], 126 }, 127 ]}> 128 <VerificationCheck 129 width={dimensions} 130 fill={ 131 verifiedByHidden 132 ? t.atoms.bg_contrast_100.backgroundColor 133 : state.profile.isVerified 134 ? t.palette.primary_500 135 : t.atoms.bg_contrast_100.backgroundColor 136 } 137 verifier={state.profile.role === 'verifier'} 138 /> 139 </View> 140 )} 141 </Button> 142 143 <VerificationsDialog 144 control={verificationsDialogControl} 145 profile={profile} 146 verificationState={state} 147 /> 148 149 <VerifierDialog 150 control={verifierDialogControl} 151 profile={profile} 152 verificationState={state} 153 /> 154 </> 155 ) 156}