Make generic convo report dialog (#4085)
parent
1cdcb3e6c3
commit
8b3bfb3cf7
|
@ -25,12 +25,10 @@ import {SquareArrowTopRight_Stroke2_Corner0_Rounded as SquareArrowTopRight} from
|
|||
import {Text} from '#/components/Typography'
|
||||
import {ReportDialogProps} from './types'
|
||||
|
||||
type ParamsWithMessages = ReportDialogProps['params'] | {type: 'message'}
|
||||
|
||||
export function SelectReportOptionView({
|
||||
...props
|
||||
}: {
|
||||
params: ParamsWithMessages
|
||||
params: ReportDialogProps['params']
|
||||
labelers: AppBskyLabelerDefs.LabelerViewDetailed[]
|
||||
onSelectReportOption: (reportOption: ReportOption) => void
|
||||
goBack: () => void
|
||||
|
@ -57,9 +55,12 @@ export function SelectReportOptionView({
|
|||
} else if (props.params.type === 'feedgen') {
|
||||
title = _(msg`Report this feed`)
|
||||
description = _(msg`Why should this feed be reviewed?`)
|
||||
} else if (props.params.type === 'message') {
|
||||
} else if (props.params.type === 'convoMessage') {
|
||||
title = _(msg`Report this message`)
|
||||
description = _(msg`Why should this message be reviewed?`)
|
||||
} else if (props.params.type === 'convoAccount') {
|
||||
title = _(msg`Report this account`)
|
||||
description = _(msg`Why should this account be reviewed?`)
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -12,4 +12,6 @@ export type ReportDialogProps = {
|
|||
type: 'account'
|
||||
did: string
|
||||
}
|
||||
| {type: 'convoMessage'}
|
||||
| {type: 'convoAccount'}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import * as Toast from '#/view/com/util/Toast'
|
|||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {BlockedByListDialog} from '#/components/dms/BlockedByListDialog'
|
||||
import {LeaveConvoPrompt} from '#/components/dms/LeaveConvoPrompt'
|
||||
import {ReportConversationPrompt} from '#/components/dms/ReportConversationPrompt'
|
||||
import {ReportDialog} from '#/components/dms/ReportDialog'
|
||||
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as ArrowBoxLeft} from '#/components/icons/ArrowBoxLeft'
|
||||
import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
||||
import {Flag_Stroke2_Corner0_Rounded as Flag} from '#/components/icons/Flag'
|
||||
|
@ -205,7 +205,10 @@ let ConvoMenu = ({
|
|||
convoId={convo.id}
|
||||
currentScreen={currentScreen}
|
||||
/>
|
||||
<ReportConversationPrompt control={reportControl} />
|
||||
<ReportDialog
|
||||
control={reportControl}
|
||||
params={{type: 'convoAccount', did: profile.did, convoId: convo.id}}
|
||||
/>
|
||||
<BlockedByListDialog
|
||||
control={blockedByListControl}
|
||||
listBlocks={listBlocks}
|
||||
|
|
|
@ -11,6 +11,7 @@ import {useConvoActive} from 'state/messages/convo'
|
|||
import {useSession} from 'state/session'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {ReportDialog} from '#/components/dms/ReportDialog'
|
||||
import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
||||
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
|
||||
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
||||
|
@ -18,7 +19,6 @@ import * as Menu from '#/components/Menu'
|
|||
import * as Prompt from '#/components/Prompt'
|
||||
import {usePromptControl} from '#/components/Prompt'
|
||||
import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '../icons/Clipboard'
|
||||
import {MessageReportDialog} from './MessageReportDialog'
|
||||
|
||||
export let MessageMenu = ({
|
||||
message,
|
||||
|
@ -112,7 +112,10 @@ export let MessageMenu = ({
|
|||
</Menu.Outer>
|
||||
</Menu.Root>
|
||||
|
||||
<MessageReportDialog message={message} control={reportControl} />
|
||||
<ReportDialog
|
||||
params={{type: 'convoMessage', convoId: convo.convo.id, message}}
|
||||
control={reportControl}
|
||||
/>
|
||||
|
||||
<Prompt.Basic
|
||||
control={deleteControl}
|
||||
|
|
|
@ -12,7 +12,7 @@ import {useDialogControl} from '#/components/Dialog'
|
|||
import {Divider} from '#/components/Divider'
|
||||
import {BlockedByListDialog} from '#/components/dms/BlockedByListDialog'
|
||||
import {LeaveConvoPrompt} from '#/components/dms/LeaveConvoPrompt'
|
||||
import {ReportConversationPrompt} from '#/components/dms/ReportConversationPrompt'
|
||||
import {ReportDialog} from '#/components/dms/ReportDialog'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
export function MessagesListBlockedFooter({
|
||||
|
@ -120,7 +120,10 @@ export function MessagesListBlockedFooter({
|
|||
convoId={convoId}
|
||||
/>
|
||||
|
||||
<ReportConversationPrompt control={reportControl} />
|
||||
<ReportDialog
|
||||
control={reportControl}
|
||||
params={{type: 'convoAccount', did: recipient.did, convoId}}
|
||||
/>
|
||||
|
||||
<BlockedByListDialog
|
||||
control={blockedByListControl}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import React from 'react'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {DialogControlProps} from '#/components/Dialog'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
|
||||
export function ReportConversationPrompt({
|
||||
control,
|
||||
}: {
|
||||
control: DialogControlProps
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
|
||||
return (
|
||||
<Prompt.Basic
|
||||
control={control}
|
||||
title={_(msg`Report conversation`)}
|
||||
description={_(
|
||||
msg`To report a conversation, please report one of its messages via the conversation screen. This lets our moderators understand the context of your issue.`,
|
||||
)}
|
||||
confirmButtonCta={_(msg`I understand`)}
|
||||
onConfirm={() => {}}
|
||||
showCancel={false}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -25,12 +25,24 @@ import {RichText} from '../RichText'
|
|||
import {Text} from '../Typography'
|
||||
import {MessageItemMetadata} from './MessageItem'
|
||||
|
||||
let MessageReportDialog = ({
|
||||
type ReportDialogParams =
|
||||
| {
|
||||
type: 'convoAccount'
|
||||
did: string
|
||||
convoId: string
|
||||
}
|
||||
| {
|
||||
type: 'convoMessage'
|
||||
convoId: string
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
}
|
||||
|
||||
let ReportDialog = ({
|
||||
control,
|
||||
message,
|
||||
params,
|
||||
}: {
|
||||
control: Dialog.DialogControlProps
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
params: ReportDialogParams
|
||||
}): React.ReactNode => {
|
||||
const {_} = useLingui()
|
||||
return (
|
||||
|
@ -39,33 +51,35 @@ let MessageReportDialog = ({
|
|||
nativeOptions={isAndroid ? {sheet: {snapPoints: ['100%']}} : {}}>
|
||||
<Dialog.Handle />
|
||||
<Dialog.ScrollableInner label={_(msg`Report this message`)}>
|
||||
<DialogInner message={message} />
|
||||
<DialogInner params={params} />
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
</Dialog.Outer>
|
||||
)
|
||||
}
|
||||
MessageReportDialog = memo(MessageReportDialog)
|
||||
export {MessageReportDialog}
|
||||
ReportDialog = memo(ReportDialog)
|
||||
export {ReportDialog}
|
||||
|
||||
function DialogInner({message}: {message: ChatBskyConvoDefs.MessageView}) {
|
||||
function DialogInner({params}: {params: ReportDialogParams}) {
|
||||
const [reportOption, setReportOption] = useState<ReportOption | null>(null)
|
||||
|
||||
return reportOption ? (
|
||||
<SubmitStep
|
||||
message={message}
|
||||
params={params}
|
||||
reportOption={reportOption}
|
||||
goBack={() => setReportOption(null)}
|
||||
/>
|
||||
) : (
|
||||
<ReasonStep setReportOption={setReportOption} />
|
||||
<ReasonStep params={params} setReportOption={setReportOption} />
|
||||
)
|
||||
}
|
||||
|
||||
function ReasonStep({
|
||||
setReportOption,
|
||||
params,
|
||||
}: {
|
||||
setReportOption: (reportOption: ReportOption) => void
|
||||
params: ReportDialogParams
|
||||
}) {
|
||||
const control = Dialog.useDialogContext()
|
||||
|
||||
|
@ -73,18 +87,26 @@ function ReasonStep({
|
|||
<SelectReportOptionView
|
||||
labelers={[]}
|
||||
goBack={control.close}
|
||||
params={{type: 'message'}}
|
||||
params={
|
||||
params.type === 'convoMessage'
|
||||
? {
|
||||
type: 'convoMessage',
|
||||
}
|
||||
: {
|
||||
type: 'convoAccount',
|
||||
}
|
||||
}
|
||||
onSelectReportOption={setReportOption}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function SubmitStep({
|
||||
message,
|
||||
params,
|
||||
reportOption,
|
||||
goBack,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
params: ReportDialogParams
|
||||
reportOption: ReportOption
|
||||
goBack: () => void
|
||||
}) {
|
||||
|
@ -101,17 +123,33 @@ function SubmitStep({
|
|||
isPending: submitting,
|
||||
} = useMutation({
|
||||
mutationFn: async () => {
|
||||
const report = {
|
||||
reasonType: reportOption.reason,
|
||||
subject: {
|
||||
$type: 'chat.bsky.convo.defs#messageRef',
|
||||
messageId: message.id,
|
||||
did: message.sender!.did,
|
||||
} satisfies ChatBskyConvoDefs.MessageRef,
|
||||
reason: details,
|
||||
} satisfies ComAtprotoModerationCreateReport.InputSchema
|
||||
if (params.type === 'convoMessage') {
|
||||
const {convoId, message} = params
|
||||
|
||||
await getAgent().createModerationReport(report)
|
||||
const report = {
|
||||
reasonType: reportOption.reason,
|
||||
subject: {
|
||||
$type: 'chat.bsky.convo.defs#messageRef',
|
||||
messageId: message.id,
|
||||
convoId,
|
||||
did: message.sender.did,
|
||||
} satisfies ChatBskyConvoDefs.MessageRef,
|
||||
reason: details,
|
||||
} satisfies ComAtprotoModerationCreateReport.InputSchema
|
||||
|
||||
await getAgent().createModerationReport(report)
|
||||
} else if (params.type === 'convoAccount') {
|
||||
const {convoId, did} = params
|
||||
|
||||
await getAgent().createModerationReport({
|
||||
reasonType: reportOption.reason,
|
||||
subject: {
|
||||
$type: 'com.atproto.admin.defs#repoRef',
|
||||
did,
|
||||
},
|
||||
reason: details + ` — from:dms:${convoId}`,
|
||||
})
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
control.close(() => {
|
||||
|
@ -120,6 +158,17 @@ function SubmitStep({
|
|||
},
|
||||
})
|
||||
|
||||
const copy = useMemo(() => {
|
||||
return {
|
||||
convoMessage: {
|
||||
title: _(msg`Report this message`),
|
||||
},
|
||||
convoAccount: {
|
||||
title: _(msg`Report this account`),
|
||||
},
|
||||
}[params.type]
|
||||
}, [_, params])
|
||||
|
||||
return (
|
||||
<View style={a.gap_lg}>
|
||||
<Button
|
||||
|
@ -133,9 +182,7 @@ function SubmitStep({
|
|||
</Button>
|
||||
|
||||
<View style={[a.justify_center, gtMobile ? a.gap_sm : a.gap_xs]}>
|
||||
<Text style={[a.text_2xl, a.font_bold]}>
|
||||
<Trans>Report this message</Trans>
|
||||
</Text>
|
||||
<Text style={[a.text_2xl, a.font_bold]}>{copy.title}</Text>
|
||||
<Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||
<Trans>
|
||||
Your report will be sent to the Bluesky Moderation Service
|
||||
|
@ -143,10 +190,15 @@ function SubmitStep({
|
|||
</Text>
|
||||
</View>
|
||||
|
||||
<PreviewMessage message={message} />
|
||||
{params.type === 'convoMessage' && (
|
||||
<PreviewMessage message={params.message} />
|
||||
)}
|
||||
|
||||
<Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||
<Trans>Reason: {reportOption.title}</Trans>
|
||||
<Text style={[a.font_bold, a.text_md, t.atoms.text_contrast_medium]}>
|
||||
<Trans>Reason:</Trans>
|
||||
</Text>{' '}
|
||||
<Text style={[a.font_bold, a.text_md]}>{reportOption.title}</Text>
|
||||
</Text>
|
||||
|
||||
<Divider />
|
|
@ -15,7 +15,8 @@ interface ReportOptions {
|
|||
list: ReportOption[]
|
||||
feedgen: ReportOption[]
|
||||
other: ReportOption[]
|
||||
message: ReportOption[]
|
||||
convoMessage: ReportOption[]
|
||||
convoAccount: ReportOption[]
|
||||
}
|
||||
|
||||
export function useReportOptions(): ReportOptions {
|
||||
|
@ -73,7 +74,20 @@ export function useReportOptions(): ReportOptions {
|
|||
},
|
||||
...common,
|
||||
],
|
||||
message: [
|
||||
convoMessage: [
|
||||
{
|
||||
reason: ComAtprotoModerationDefs.REASONSPAM,
|
||||
title: _(msg`Spam`),
|
||||
description: _(msg`Excessive or unwanted messages`),
|
||||
},
|
||||
{
|
||||
reason: ComAtprotoModerationDefs.REASONSEXUAL,
|
||||
title: _(msg`Unwanted Sexual Content`),
|
||||
description: _(msg`Inappropriate messages or explicit links`),
|
||||
},
|
||||
...common,
|
||||
],
|
||||
convoAccount: [
|
||||
{
|
||||
reason: ComAtprotoModerationDefs.REASONSPAM,
|
||||
title: _(msg`Spam`),
|
||||
|
|
Loading…
Reference in New Issue