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

zio/stable
Eric Bailey 2024-09-04 18:34:19 -05:00 committed by GitHub
parent 4d97a2aa16
commit 76f493c279
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 22 deletions

View File

@ -14,19 +14,18 @@ import {
} from '#/components/moderation/LabelsOnMeDialog' } from '#/components/moderation/LabelsOnMeDialog'
export function LabelsOnMe({ export function LabelsOnMe({
details, type,
labels, labels,
size, size,
style, style,
}: { }: {
details: {did: string} | {uri: string; cid: string} type: 'account' | 'content'
labels: ComAtprotoLabelDefs.Label[] | undefined labels: ComAtprotoLabelDefs.Label[] | undefined
size?: ButtonSize size?: ButtonSize
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const isAccount = 'did' in details
const control = useLabelsOnMeDialogControl() const control = useLabelsOnMeDialogControl()
if (!labels || !currentAccount) { if (!labels || !currentAccount) {
@ -39,7 +38,7 @@ export function LabelsOnMe({
return ( return (
<View style={[a.flex_row, style]}> <View style={[a.flex_row, style]}>
<LabelsOnMeDialog control={control} subject={details} labels={labels} /> <LabelsOnMeDialog control={control} labels={labels} type={type} />
<Button <Button
variant="solid" variant="solid"
@ -51,7 +50,7 @@ export function LabelsOnMe({
}}> }}>
<ButtonIcon position="left" icon={CircleInfo} /> <ButtonIcon position="left" icon={CircleInfo} />
<ButtonText style={[a.leading_snug]}> <ButtonText style={[a.leading_snug]}>
{isAccount ? ( {type === 'account' ? (
<Plural <Plural
value={labels.length} value={labels.length}
one="# label has been placed on this account" one="# label has been placed on this account"
@ -82,6 +81,6 @@ export function LabelsOnMyPost({
return null return null
} }
return ( return (
<LabelsOnMe details={post} labels={post.labels} size="tiny" style={style} /> <LabelsOnMe type="content" labels={post.labels} size="tiny" style={style} />
) )
} }

View File

@ -5,6 +5,7 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useMutation} from '@tanstack/react-query' import {useMutation} from '@tanstack/react-query'
import {useLabelSubject} from '#/lib/moderation'
import {useLabelInfo} from '#/lib/moderation/useLabelInfo' import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
@ -18,21 +19,13 @@ import {InlineLinkText} from '#/components/Link'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {Divider} from '../Divider' import {Divider} from '../Divider'
import {Loader} from '../Loader' import {Loader} from '../Loader'
export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog'
type Subject = export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog'
| {
uri: string
cid: string
}
| {
did: string
}
export interface LabelsOnMeDialogProps { export interface LabelsOnMeDialogProps {
control: Dialog.DialogOuterProps['control'] control: Dialog.DialogOuterProps['control']
subject: Subject
labels: ComAtprotoLabelDefs.Label[] labels: ComAtprotoLabelDefs.Label[]
type: 'account' | 'content'
} }
export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) { export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) {
@ -51,8 +44,8 @@ function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) {
const [appealingLabel, setAppealingLabel] = React.useState< const [appealingLabel, setAppealingLabel] = React.useState<
ComAtprotoLabelDefs.Label | undefined ComAtprotoLabelDefs.Label | undefined
>(undefined) >(undefined)
const {subject, labels} = props const {labels} = props
const isAccount = 'did' in subject const isAccount = props.type === 'account'
const containsSelfLabel = React.useMemo( const containsSelfLabel = React.useMemo(
() => labels.some(l => l.src === currentAccount?.did), () => labels.some(l => l.src === currentAccount?.did),
[currentAccount?.did, labels], [currentAccount?.did, labels],
@ -68,7 +61,6 @@ function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) {
{appealingLabel ? ( {appealingLabel ? (
<AppealForm <AppealForm
label={appealingLabel} label={appealingLabel}
subject={subject}
control={props.control} control={props.control}
onPressBack={() => setAppealingLabel(undefined)} onPressBack={() => setAppealingLabel(undefined)}
/> />
@ -188,12 +180,10 @@ function Label({
function AppealForm({ function AppealForm({
label, label,
subject,
control, control,
onPressBack, onPressBack,
}: { }: {
label: ComAtprotoLabelDefs.Label label: ComAtprotoLabelDefs.Label
subject: Subject
control: Dialog.DialogOuterProps['control'] control: Dialog.DialogOuterProps['control']
onPressBack: () => void onPressBack: () => void
}) { }) {
@ -201,6 +191,7 @@ function AppealForm({
const {labeler, strings} = useLabelInfo(label) const {labeler, strings} = useLabelInfo(label)
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const [details, setDetails] = React.useState('') const [details, setDetails] = React.useState('')
const {subject} = useLabelSubject({label})
const isAccountReport = 'did' in subject const isAccountReport = 'did' in subject
const agent = useAgent() const agent = useAgent()
const sourceName = labeler const sourceName = labeler

View File

@ -1,6 +1,8 @@
import React from 'react'
import { import {
AppBskyLabelerDefs, AppBskyLabelerDefs,
BskyAgent, BskyAgent,
ComAtprotoLabelDefs,
InterpretedLabelValueDefinition, InterpretedLabelValueDefinition,
LABELS, LABELS,
ModerationCause, ModerationCause,
@ -82,3 +84,34 @@ export function isLabelerSubscribed(
} }
return modOpts.prefs.labelers.find(l => l.did === labeler) return modOpts.prefs.labelers.find(l => l.did === labeler)
} }
export type Subject =
| {
uri: string
cid: string
}
| {
did: string
}
export function useLabelSubject({label}: {label: ComAtprotoLabelDefs.Label}): {
subject: Subject
} {
return React.useMemo(() => {
const {cid, uri} = label
if (cid) {
return {
subject: {
uri,
cid,
},
}
} else {
return {
subject: {
did: uri,
},
}
}
}, [label])
}

View File

@ -86,7 +86,7 @@ let ProfileHeaderShell = ({
style={[a.px_lg, a.py_xs]} style={[a.px_lg, a.py_xs]}
pointerEvents={isIOS ? 'auto' : 'box-none'}> pointerEvents={isIOS ? 'auto' : 'box-none'}>
{isMe ? ( {isMe ? (
<LabelsOnMe details={{did: profile.did}} labels={profile.labels} /> <LabelsOnMe type="account" labels={profile.labels} />
) : ( ) : (
<ProfileHeaderAlerts moderation={moderation} /> <ProfileHeaderAlerts moderation={moderation} />
)} )}