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 {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
import {useLabelSubject} from '#/lib/moderation'
import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeHandle} from '#/lib/strings/handles'
import {logger} from '#/logger'
import {isAndroid} from '#/platform/detection'
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'
export interface LabelsOnMeDialogProps {
control: Dialog.DialogOuterProps['control']
labels: ComAtprotoLabelDefs.Label[]
type: 'account' | 'content'
}
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 {labels} = props
const isAccount = props.type === 'account'
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
const timeDiff = useGetTimeAgo({future: true})
return (
{strings.name}
{strings.description}
{!isSelfLabel && (
)}
{isSelfLabel ? (
This label was applied by you.
) : (
Source:{' '}
control.close()}>
{sourceName}
{label.exp && (
Expires in {timeDiff(Date.now(), label.exp)}
)}
)}
)
}
function AppealForm({
label,
control,
onPressBack,
}: {
label: ComAtprotoLabelDefs.Label
control: Dialog.DialogOuterProps['control']
onPressBack: () => void
}) {
const {_} = useLingui()
const {labeler, strings} = useLabelInfo(label)
const {gtMobile} = useBreakpoints()
const [details, setDetails] = React.useState('')
const {subject} = useLabelSubject({label})
const isAccountReport = 'did' in subject
const agent = useAgent()
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'
await agent.createModerationReport(
{
reasonType: ComAtprotoModerationDefs.REASONAPPEAL,
subject: {
$type,
...subject,
},
reason: details,
},
{
encoding: 'application/json',
headers: {
'atproto-proxy': `${label.src}#atproto_labeler`,
},
},
)
},
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({message: 'Appeal submitted', context: 'toast'})))
},
})
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}
.
{isAndroid && }
>
)
}