forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useCallback, useState} from 'react'
2import {View} from 'react-native'
3import {msg} from '@lingui/core/macro'
4import {useLingui} from '@lingui/react'
5import {Trans} from '@lingui/react/macro'
6
7import {logger} from '#/logger'
8import {useAgent, useSessionApi} from '#/state/session'
9import {pdsAgent} from '#/state/session/agent'
10import {atoms as a, useTheme} from '#/alf'
11import {Button, ButtonIcon, ButtonText} from '#/components/Button'
12import {type DialogOuterProps} from '#/components/Dialog'
13import {Divider} from '#/components/Divider'
14import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
15import {Loader} from '#/components/Loader'
16import * as Prompt from '#/components/Prompt'
17import {Text} from '#/components/Typography'
18
19export function DeactivateAccountDialog({
20 control,
21}: {
22 control: DialogOuterProps['control']
23}) {
24 return (
25 <Prompt.Outer control={control}>
26 <DeactivateAccountDialogInner control={control} />
27 </Prompt.Outer>
28 )
29}
30
31function DeactivateAccountDialogInner({
32 control,
33}: {
34 control: DialogOuterProps['control']
35}) {
36 const t = useTheme()
37 const {_} = useLingui()
38 const agent = useAgent()
39 const {logoutCurrentAccount} = useSessionApi()
40 const [pending, setPending] = useState(false)
41 const [error, setError] = useState<string | undefined>()
42
43 const handleDeactivate = useCallback(async () => {
44 try {
45 setPending(true)
46 await pdsAgent(agent).com.atproto.server.deactivateAccount({})
47 control.close(() => {
48 logoutCurrentAccount('Deactivated')
49 })
50 } catch (e: any) {
51 switch (e.message) {
52 case 'Bad token scope':
53 setError(
54 _(
55 msg`You're signed in with an App Password. Please sign in with your main password to continue deactivating your account.`,
56 ),
57 )
58 break
59 default:
60 setError(_(msg`Something went wrong, please try again`))
61 break
62 }
63
64 logger.error(e, {
65 message: 'Failed to deactivate account',
66 })
67 } finally {
68 setPending(false)
69 }
70 }, [agent, control, logoutCurrentAccount, _, setPending])
71
72 return (
73 <>
74 <Prompt.TitleText>{_(msg`Deactivate account`)}</Prompt.TitleText>
75 <Prompt.DescriptionText>
76 <Trans>
77 Your profile, posts, feeds, and lists will no longer be visible to
78 other Bluesky users. You can reactivate your account at any time by
79 logging in.
80 </Trans>
81 </Prompt.DescriptionText>
82
83 <View style={[a.pb_xl]}>
84 <Divider />
85 <View style={[a.gap_sm, a.pt_lg, a.pb_xl]}>
86 <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}>
87 <Trans>
88 There is no time limit for account deactivation, come back any
89 time.
90 </Trans>
91 </Text>
92 <Text style={[t.atoms.text_contrast_medium, a.leading_snug]}>
93 <Trans>
94 If you're trying to change your handle or email, do so before you
95 deactivate.
96 </Trans>
97 </Text>
98 </View>
99
100 <Divider />
101 </View>
102 <Prompt.Actions>
103 <Button
104 color="negative"
105 size="large"
106 label={_(msg`Yes, deactivate`)}
107 onPress={handleDeactivate}>
108 <ButtonText>{_(msg`Yes, deactivate`)}</ButtonText>
109 {pending && <ButtonIcon icon={Loader} position="right" />}
110 </Button>
111 <Prompt.Cancel />
112 </Prompt.Actions>
113
114 {error && (
115 <View
116 style={[
117 a.flex_row,
118 a.gap_sm,
119 a.mt_md,
120 a.p_md,
121 a.rounded_sm,
122 t.atoms.bg_contrast_25,
123 ]}>
124 <CircleInfo size="md" fill={t.palette.negative_400} />
125 <Text style={[a.flex_1, a.leading_snug]}>{error}</Text>
126 </View>
127 )}
128 </>
129 )
130}