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