forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {
2 type $Typed,
3 type ChatBskyConvoDefs,
4 type ComAtprotoModerationCreateReport,
5} from '@atproto/api'
6import {msg} from '@lingui/macro'
7import {useLingui} from '@lingui/react'
8import {useMutation} from '@tanstack/react-query'
9
10import {logger} from '#/logger'
11import {useAgent} from '#/state/session'
12import {NEW_TO_OLD_REASONS_MAP} from './const'
13import {type ReportState} from './state'
14import {type ParsedReportSubject} from './types'
15
16export function useSubmitReportMutation() {
17 const {_} = useLingui()
18 const agent = useAgent()
19
20 return useMutation({
21 async mutationFn({
22 subject,
23 state,
24 }: {
25 subject: ParsedReportSubject
26 state: ReportState
27 }) {
28 if (!state.selectedOption) {
29 throw new Error(_(msg`Please select a reason for this report`))
30 }
31 if (!state.selectedLabeler) {
32 throw new Error(_(msg`Please select a moderation service`))
33 }
34
35 const labeler = state.selectedLabeler
36 const labelerSupportedReasonTypes = labeler.reasonTypes || []
37
38 let reasonType = state.selectedOption.reason
39 const backwardsCompatibleReasonType = NEW_TO_OLD_REASONS_MAP[reasonType]
40 const supportsNewReasonType =
41 labelerSupportedReasonTypes.includes(reasonType)
42 const supportsOldReasonType = labelerSupportedReasonTypes.includes(
43 backwardsCompatibleReasonType,
44 )
45
46 /*
47 * Only fall back for backwards compatibility if the labeler
48 * does not support the new reason type. If the labeler does not declare
49 * supported reason types, send the new version.
50 */
51 if (supportsOldReasonType && !supportsNewReasonType) {
52 reasonType = backwardsCompatibleReasonType
53 }
54
55 let report:
56 | ComAtprotoModerationCreateReport.InputSchema
57 | (Omit<ComAtprotoModerationCreateReport.InputSchema, 'subject'> & {
58 subject: $Typed<ChatBskyConvoDefs.MessageRef>
59 })
60
61 switch (subject.type) {
62 case 'account': {
63 report = {
64 reasonType,
65 reason: state.details,
66 subject: {
67 $type: 'com.atproto.admin.defs#repoRef',
68 did: subject.did,
69 },
70 }
71 break
72 }
73 case 'post':
74 case 'list':
75 case 'feed':
76 case 'starterPack': {
77 report = {
78 reasonType,
79 reason: state.details,
80 subject: {
81 $type: 'com.atproto.repo.strongRef',
82 uri: subject.uri,
83 cid: subject.cid,
84 },
85 }
86 break
87 }
88 case 'convoMessage': {
89 report = {
90 reasonType,
91 reason: state.details,
92 subject: {
93 $type: 'chat.bsky.convo.defs#messageRef',
94 messageId: subject.message.id,
95 convoId: subject.convoId,
96 did: subject.message.sender.did,
97 },
98 }
99 break
100 }
101 }
102
103 if (__DEV__) {
104 logger.info('Submitting report', {
105 labeler: {
106 handle: labeler.creator.handle,
107 },
108 report,
109 })
110 } else {
111 await agent.createModerationReport(report, {
112 encoding: 'application/json',
113 headers: {
114 'atproto-proxy': `${labeler.creator.did}#atproto_labeler`,
115 },
116 })
117 }
118 },
119 })
120}