import React from 'react' import {View} from 'react-native' import {ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useMutation} from '@tanstack/react-query' import {useLabelInfo} from '#/lib/moderation/useLabelInfo' import {makeProfileLink} from '#/lib/routes/links' import {useGate} from '#/lib/statsig/statsig' import {sanitizeHandle} from '#/lib/strings/handles' import {logger} from '#/logger' import {useAgent, useSession} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' import {Divider} from '../Divider' import {Loader} from '../Loader' export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog' type Subject = | { uri: string cid: string } | { did: string } export interface LabelsOnMeDialogProps { control: Dialog.DialogOuterProps['control'] subject: Subject labels: ComAtprotoLabelDefs.Label[] } export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) { return ( ) } function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) { const {_} = useLingui() const {currentAccount} = useSession() const [appealingLabel, setAppealingLabel] = React.useState< ComAtprotoLabelDefs.Label | undefined >(undefined) const {subject, labels} = props const isAccount = 'did' in subject const containsSelfLabel = React.useMemo( () => labels.some(l => l.src === currentAccount?.did), [currentAccount?.did, labels], ) return ( {appealingLabel ? ( setAppealingLabel(undefined)} /> ) : ( <> {isAccount ? ( Labels on your account ) : ( Labels on your content )} {containsSelfLabel ? ( You may appeal non-self labels if you feel they were placed in error. ) : ( You may appeal these labels if you feel they were placed in error. )} {labels.map(label => ( )} ) } function Label({ label, isSelfLabel, control, onPressAppeal, }: { label: ComAtprotoLabelDefs.Label isSelfLabel: boolean control: Dialog.DialogOuterProps['control'] onPressAppeal: (label: ComAtprotoLabelDefs.Label) => void }) { const t = useTheme() const {_} = useLingui() const {labeler, strings} = useLabelInfo(label) const sourceName = labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src return ( {strings.name} {strings.description} {!isSelfLabel && ( )} {isSelfLabel ? ( This label was applied by you. ) : ( Source:{' '} control.close()}> {sourceName} )} ) } function AppealForm({ label, subject, control, onPressBack, }: { label: ComAtprotoLabelDefs.Label subject: Subject control: Dialog.DialogOuterProps['control'] onPressBack: () => void }) { const {_} = useLingui() const {labeler, strings} = useLabelInfo(label) const {gtMobile} = useBreakpoints() const [details, setDetails] = React.useState('') const isAccountReport = 'did' in subject const agent = useAgent() const gate = useGate() const sourceName = labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src const {mutate, isPending} = useMutation({ mutationFn: async () => { const $type = !isAccountReport ? 'com.atproto.repo.strongRef' : 'com.atproto.admin.defs#repoRef' if (gate('session_withproxy_fix')) { await agent.createModerationReport( { reasonType: ComAtprotoModerationDefs.REASONAPPEAL, subject: { $type, ...subject, }, reason: details, }, { encoding: 'application/json', headers: { 'atproto-proxy': `${label.src}#atproto_labeler`, }, }, ) } else { await agent .withProxy('atproto_labeler', label.src) .createModerationReport({ reasonType: ComAtprotoModerationDefs.REASONAPPEAL, subject: { $type, ...subject, }, reason: details, }) } }, onError: err => { logger.error('Failed to submit label appeal', {message: err}) Toast.show(_(msg`Failed to submit appeal, please try again.`), 'xmark') }, onSuccess: () => { control.close() Toast.show(_(msg`Appeal submitted`)) }, }) const onSubmit = React.useCallback(() => mutate(), [mutate]) return ( <> Appeal "{strings.name}" label This appeal will be sent to{' '} control.close()} style={[a.text_md, a.leading_snug]}> {sourceName} . ) }