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