Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Ensure profile labels can be appealed separately from account labels (#5154)

authored by

Eric Bailey and committed by
GitHub
76f493c2 4d97a2aa

+45 -22
+5 -6
src/components/moderation/LabelsOnMe.tsx
··· 14 14 } from '#/components/moderation/LabelsOnMeDialog' 15 15 16 16 export function LabelsOnMe({ 17 - details, 17 + type, 18 18 labels, 19 19 size, 20 20 style, 21 21 }: { 22 - details: {did: string} | {uri: string; cid: string} 22 + type: 'account' | 'content' 23 23 labels: ComAtprotoLabelDefs.Label[] | undefined 24 24 size?: ButtonSize 25 25 style?: StyleProp<ViewStyle> 26 26 }) { 27 27 const {_} = useLingui() 28 28 const {currentAccount} = useSession() 29 - const isAccount = 'did' in details 30 29 const control = useLabelsOnMeDialogControl() 31 30 32 31 if (!labels || !currentAccount) { ··· 39 38 40 39 return ( 41 40 <View style={[a.flex_row, style]}> 42 - <LabelsOnMeDialog control={control} subject={details} labels={labels} /> 41 + <LabelsOnMeDialog control={control} labels={labels} type={type} /> 43 42 44 43 <Button 45 44 variant="solid" ··· 51 50 }}> 52 51 <ButtonIcon position="left" icon={CircleInfo} /> 53 52 <ButtonText style={[a.leading_snug]}> 54 - {isAccount ? ( 53 + {type === 'account' ? ( 55 54 <Plural 56 55 value={labels.length} 57 56 one="# label has been placed on this account" ··· 82 81 return null 83 82 } 84 83 return ( 85 - <LabelsOnMe details={post} labels={post.labels} size="tiny" style={style} /> 84 + <LabelsOnMe type="content" labels={post.labels} size="tiny" style={style} /> 86 85 ) 87 86 }
+6 -15
src/components/moderation/LabelsOnMeDialog.tsx
··· 5 5 import {useLingui} from '@lingui/react' 6 6 import {useMutation} from '@tanstack/react-query' 7 7 8 + import {useLabelSubject} from '#/lib/moderation' 8 9 import {useLabelInfo} from '#/lib/moderation/useLabelInfo' 9 10 import {makeProfileLink} from '#/lib/routes/links' 10 11 import {sanitizeHandle} from '#/lib/strings/handles' ··· 18 19 import {Text} from '#/components/Typography' 19 20 import {Divider} from '../Divider' 20 21 import {Loader} from '../Loader' 21 - export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog' 22 22 23 - type Subject = 24 - | { 25 - uri: string 26 - cid: string 27 - } 28 - | { 29 - did: string 30 - } 23 + export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog' 31 24 32 25 export interface LabelsOnMeDialogProps { 33 26 control: Dialog.DialogOuterProps['control'] 34 - subject: Subject 35 27 labels: ComAtprotoLabelDefs.Label[] 28 + type: 'account' | 'content' 36 29 } 37 30 38 31 export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) { ··· 51 44 const [appealingLabel, setAppealingLabel] = React.useState< 52 45 ComAtprotoLabelDefs.Label | undefined 53 46 >(undefined) 54 - const {subject, labels} = props 55 - const isAccount = 'did' in subject 47 + const {labels} = props 48 + const isAccount = props.type === 'account' 56 49 const containsSelfLabel = React.useMemo( 57 50 () => labels.some(l => l.src === currentAccount?.did), 58 51 [currentAccount?.did, labels], ··· 68 61 {appealingLabel ? ( 69 62 <AppealForm 70 63 label={appealingLabel} 71 - subject={subject} 72 64 control={props.control} 73 65 onPressBack={() => setAppealingLabel(undefined)} 74 66 /> ··· 188 180 189 181 function AppealForm({ 190 182 label, 191 - subject, 192 183 control, 193 184 onPressBack, 194 185 }: { 195 186 label: ComAtprotoLabelDefs.Label 196 - subject: Subject 197 187 control: Dialog.DialogOuterProps['control'] 198 188 onPressBack: () => void 199 189 }) { ··· 201 191 const {labeler, strings} = useLabelInfo(label) 202 192 const {gtMobile} = useBreakpoints() 203 193 const [details, setDetails] = React.useState('') 194 + const {subject} = useLabelSubject({label}) 204 195 const isAccountReport = 'did' in subject 205 196 const agent = useAgent() 206 197 const sourceName = labeler
+33
src/lib/moderation.ts
··· 1 + import React from 'react' 1 2 import { 2 3 AppBskyLabelerDefs, 3 4 BskyAgent, 5 + ComAtprotoLabelDefs, 4 6 InterpretedLabelValueDefinition, 5 7 LABELS, 6 8 ModerationCause, ··· 82 84 } 83 85 return modOpts.prefs.labelers.find(l => l.did === labeler) 84 86 } 87 + 88 + export type Subject = 89 + | { 90 + uri: string 91 + cid: string 92 + } 93 + | { 94 + did: string 95 + } 96 + 97 + export function useLabelSubject({label}: {label: ComAtprotoLabelDefs.Label}): { 98 + subject: Subject 99 + } { 100 + return React.useMemo(() => { 101 + const {cid, uri} = label 102 + if (cid) { 103 + return { 104 + subject: { 105 + uri, 106 + cid, 107 + }, 108 + } 109 + } else { 110 + return { 111 + subject: { 112 + did: uri, 113 + }, 114 + } 115 + } 116 + }, [label]) 117 + }
+1 -1
src/screens/Profile/Header/Shell.tsx
··· 86 86 style={[a.px_lg, a.py_xs]} 87 87 pointerEvents={isIOS ? 'auto' : 'box-none'}> 88 88 {isMe ? ( 89 - <LabelsOnMe details={{did: profile.did}} labels={profile.labels} /> 89 + <LabelsOnMe type="account" labels={profile.labels} /> 90 90 ) : ( 91 91 <ProfileHeaderAlerts moderation={moderation} /> 92 92 )}