about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/ReportDialog/SelectReportOptionView.tsx9
-rw-r--r--src/components/ReportDialog/types.ts2
-rw-r--r--src/components/dms/ConvoMenu.tsx7
-rw-r--r--src/components/dms/MessageMenu.tsx7
-rw-r--r--src/components/dms/MessagesListBlockedFooter.tsx7
-rw-r--r--src/components/dms/ReportConversationPrompt.tsx27
-rw-r--r--src/components/dms/ReportDialog.tsx (renamed from src/components/dms/MessageReportDialog.tsx)106
-rw-r--r--src/lib/moderation/useReportOptions.ts18
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`),