diff options
-rw-r--r-- | src/components/ReportDialog/SelectReportOptionView.tsx | 9 | ||||
-rw-r--r-- | src/components/ReportDialog/types.ts | 2 | ||||
-rw-r--r-- | src/components/dms/ConvoMenu.tsx | 7 | ||||
-rw-r--r-- | src/components/dms/MessageMenu.tsx | 7 | ||||
-rw-r--r-- | src/components/dms/MessagesListBlockedFooter.tsx | 7 | ||||
-rw-r--r-- | src/components/dms/ReportConversationPrompt.tsx | 27 | ||||
-rw-r--r-- | src/components/dms/ReportDialog.tsx (renamed from src/components/dms/MessageReportDialog.tsx) | 106 | ||||
-rw-r--r-- | src/lib/moderation/useReportOptions.ts | 18 |
8 files changed, 117 insertions, 66 deletions
diff --git a/src/components/ReportDialog/SelectReportOptionView.tsx b/src/components/ReportDialog/SelectReportOptionView.tsx index da3c43440..405384476 100644 --- a/src/components/ReportDialog/SelectReportOptionView.tsx +++ b/src/components/ReportDialog/SelectReportOptionView.tsx @@ -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 { diff --git a/src/components/ReportDialog/types.ts b/src/components/ReportDialog/types.ts index 0c8a1e077..5a1385652 100644 --- a/src/components/ReportDialog/types.ts +++ b/src/components/ReportDialog/types.ts @@ -12,4 +12,6 @@ export type ReportDialogProps = { type: 'account' did: string } + | {type: 'convoMessage'} + | {type: 'convoAccount'} } diff --git a/src/components/dms/ConvoMenu.tsx b/src/components/dms/ConvoMenu.tsx index 0e5cd12bf..50a528084 100644 --- a/src/components/dms/ConvoMenu.tsx +++ b/src/components/dms/ConvoMenu.tsx @@ -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} diff --git a/src/components/dms/MessageMenu.tsx b/src/components/dms/MessageMenu.tsx index 1a2ad01dc..21812d268 100644 --- a/src/components/dms/MessageMenu.tsx +++ b/src/components/dms/MessageMenu.tsx @@ -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} diff --git a/src/components/dms/MessagesListBlockedFooter.tsx b/src/components/dms/MessagesListBlockedFooter.tsx index a018b8623..7cf6f5852 100644 --- a/src/components/dms/MessagesListBlockedFooter.tsx +++ b/src/components/dms/MessagesListBlockedFooter.tsx @@ -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} diff --git a/src/components/dms/ReportConversationPrompt.tsx b/src/components/dms/ReportConversationPrompt.tsx deleted file mode 100644 index 610cfbcf9..000000000 --- a/src/components/dms/ReportConversationPrompt.tsx +++ /dev/null @@ -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} - /> - ) -} diff --git a/src/components/dms/MessageReportDialog.tsx b/src/components/dms/ReportDialog.tsx index cc25732af..e8ac0ed2f 100644 --- a/src/components/dms/MessageReportDialog.tsx +++ b/src/components/dms/ReportDialog.tsx @@ -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 + + 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(report) + 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 /> diff --git a/src/lib/moderation/useReportOptions.ts b/src/lib/moderation/useReportOptions.ts index ff12534c2..6533004c4 100644 --- a/src/lib/moderation/useReportOptions.ts +++ b/src/lib/moderation/useReportOptions.ts @@ -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`), |