forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useCallback, useState} from 'react'
2import {View} from 'react-native'
3import {type AppBskyActorDefs, ToolsOzoneReportDefs} from '@atproto/api'
4import {msg} from '@lingui/core/macro'
5import {useLingui} from '@lingui/react'
6import {Trans} from '@lingui/react/macro'
7import {useMutation} from '@tanstack/react-query'
8
9import {BLUESKY_MOD_SERVICE_HEADERS} from '#/lib/constants'
10import {logger} from '#/logger'
11import {useAgent} from '#/state/session'
12import {atoms as a, web} from '#/alf'
13import {Button, ButtonIcon, ButtonText} from '#/components/Button'
14import * as Dialog from '#/components/Dialog'
15import {Loader} from '#/components/Loader'
16import * as Toast from '#/components/Toast'
17import {Text} from '#/components/Typography'
18
19export function GoLiveDisabledDialog({
20 control,
21 status,
22}: {
23 control: Dialog.DialogControlProps
24 status: AppBskyActorDefs.StatusView
25}) {
26 return (
27 <Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
28 <Dialog.Handle />
29 <DialogInner control={control} status={status} />
30 </Dialog.Outer>
31 )
32}
33
34export function DialogInner({
35 control,
36 status,
37}: {
38 control: Dialog.DialogControlProps
39 status: AppBskyActorDefs.StatusView
40}) {
41 const {_} = useLingui()
42 const agent = useAgent()
43 const [details, setDetails] = useState('')
44
45 const {mutate, isPending} = useMutation({
46 mutationFn: async () => {
47 if (!agent.session?.did) {
48 throw new Error('Not logged in')
49 }
50 if (!status.uri || !status.cid) {
51 throw new Error('Status is missing uri or cid')
52 }
53
54 if (__DEV__) {
55 logger.info('Submitting go live appeal', {
56 details,
57 })
58 } else {
59 await agent.createModerationReport(
60 {
61 reasonType: ToolsOzoneReportDefs.REASONAPPEAL,
62 subject: {
63 $type: 'com.atproto.repo.strongRef',
64 uri: status.uri,
65 cid: status.cid,
66 },
67 reason: details,
68 },
69 {
70 encoding: 'application/json',
71 headers: BLUESKY_MOD_SERVICE_HEADERS,
72 },
73 )
74 }
75 },
76 onError: () => {
77 Toast.show(_(msg`Failed to submit appeal, please try again.`), {
78 type: 'error',
79 })
80 },
81 onSuccess: () => {
82 control.close()
83 Toast.show(_(msg({message: 'Appeal submitted', context: 'toast'})), {
84 type: 'success',
85 })
86 },
87 })
88
89 const onSubmit = useCallback(() => mutate(), [mutate])
90
91 return (
92 <Dialog.ScrollableInner
93 label={_(msg`Appeal livestream suspension`)}
94 style={[web({maxWidth: 400})]}>
95 <View style={[a.gap_lg]}>
96 <View style={[a.gap_md]}>
97 <Text
98 style={[
99 a.flex_1,
100 a.text_2xl,
101 a.font_semi_bold,
102 a.leading_snug,
103 a.pr_4xl,
104 ]}>
105 <Trans>Going live is currently disabled for your account</Trans>
106 </Text>
107 <Text style={[a.text_md, a.leading_snug]}>
108 <Trans>
109 You are currently blocked from using the Go Live feature. To
110 appeal this moderation decision, please submit the form below.
111 </Trans>
112 </Text>
113 <Text style={[a.text_md, a.leading_snug]}>
114 <Trans>
115 This appeal will be sent to Bluesky's moderation service.
116 </Trans>
117 </Text>
118 </View>
119
120 <View style={[a.gap_md]}>
121 <Dialog.Input
122 label={_(msg`Text input field`)}
123 placeholder={_(
124 msg`Please explain why you think your Go Live access was incorrectly disabled.`,
125 )}
126 value={details}
127 onChangeText={setDetails}
128 autoFocus={true}
129 numberOfLines={3}
130 multiline
131 maxLength={300}
132 />
133 <Button
134 testID="submitBtn"
135 variant="solid"
136 color="primary"
137 size="large"
138 onPress={onSubmit}
139 label={_(msg`Submit`)}>
140 <ButtonText>{_(msg`Submit`)}</ButtonText>
141 {isPending && <ButtonIcon icon={Loader} />}
142 </Button>
143 </View>
144 </View>
145 <Dialog.Close />
146 </Dialog.ScrollableInner>
147 )
148}