mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {View} from 'react-native'
3import {useSafeAreaInsets} from 'react-native-safe-area-context'
4import {msg, Trans} from '@lingui/macro'
5import {useLingui} from '@lingui/react'
6import {useFocusEffect} from '@react-navigation/native'
7import {useQueryClient} from '@tanstack/react-query'
8
9import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
10import {logger} from '#/logger'
11import {isWeb} from '#/platform/detection'
12import {
13 type SessionAccount,
14 useAgent,
15 useSession,
16 useSessionApi,
17} from '#/state/session'
18import {useSetMinimalShellMode} from '#/state/shell'
19import {useLoggedOutViewControls} from '#/state/shell/logged-out'
20import {Logo} from '#/view/icons/Logo'
21import {atoms as a, useTheme} from '#/alf'
22import {AccountList} from '#/components/AccountList'
23import {Button, ButtonIcon, ButtonText} from '#/components/Button'
24import {Divider} from '#/components/Divider'
25import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
26import * as Layout from '#/components/Layout'
27import {Loader} from '#/components/Loader'
28import {Text} from '#/components/Typography'
29
30const COL_WIDTH = 400
31
32export function Deactivated() {
33 const {_} = useLingui()
34 const t = useTheme()
35 const insets = useSafeAreaInsets()
36 const {currentAccount, accounts} = useSession()
37 const {onPressSwitchAccount, pendingDid} = useAccountSwitcher()
38 const {setShowLoggedOut} = useLoggedOutViewControls()
39 const hasOtherAccounts = accounts.length > 1
40 const setMinimalShellMode = useSetMinimalShellMode()
41 const {logoutCurrentAccount} = useSessionApi()
42 const agent = useAgent()
43 const [pending, setPending] = React.useState(false)
44 const [error, setError] = React.useState<string | undefined>()
45 const queryClient = useQueryClient()
46
47 useFocusEffect(
48 React.useCallback(() => {
49 setMinimalShellMode(true)
50 }, [setMinimalShellMode]),
51 )
52
53 const onSelectAccount = React.useCallback(
54 (account: SessionAccount) => {
55 if (account.did !== currentAccount?.did) {
56 onPressSwitchAccount(account, 'SwitchAccount')
57 }
58 },
59 [currentAccount, onPressSwitchAccount],
60 )
61
62 const onPressAddAccount = React.useCallback(() => {
63 setShowLoggedOut(true)
64 }, [setShowLoggedOut])
65
66 const onPressLogout = React.useCallback(() => {
67 if (isWeb) {
68 // We're switching accounts, which remounts the entire app.
69 // On mobile, this gets us Home, but on the web we also need reset the URL.
70 // We can't change the URL via a navigate() call because the navigator
71 // itself is about to unmount, and it calls pushState() too late.
72 // So we change the URL ourselves. The navigator will pick it up on remount.
73 history.pushState(null, '', '/')
74 }
75 logoutCurrentAccount('Deactivated')
76 }, [logoutCurrentAccount])
77
78 const handleActivate = React.useCallback(async () => {
79 try {
80 setPending(true)
81 await agent.com.atproto.server.activateAccount()
82 await queryClient.resetQueries()
83 await agent.resumeSession(agent.session!)
84 } catch (e: any) {
85 switch (e.message) {
86 case 'Bad token scope':
87 setError(
88 _(
89 msg`You're signed in with an App Password. Please sign in with your main password to continue deactivating your account.`,
90 ),
91 )
92 break
93 default:
94 setError(_(msg`Something went wrong, please try again`))
95 break
96 }
97
98 logger.error(e, {
99 message: 'Failed to activate account',
100 })
101 } finally {
102 setPending(false)
103 }
104 }, [_, agent, setPending, setError, queryClient])
105
106 return (
107 <View style={[a.util_screen_outer, a.flex_1]}>
108 <Layout.Content
109 ignoreTabletLayoutOffset
110 contentContainerStyle={[
111 a.px_2xl,
112 {
113 paddingTop: isWeb ? 64 : insets.top + 16,
114 paddingBottom: isWeb ? 64 : insets.bottom,
115 },
116 ]}>
117 <View
118 style={[a.w_full, {marginHorizontal: 'auto', maxWidth: COL_WIDTH}]}>
119 <View style={[a.w_full, a.justify_center, a.align_center, a.pb_5xl]}>
120 <Logo width={40} />
121 </View>
122
123 <View style={[a.gap_xs, a.pb_3xl]}>
124 <Text style={[a.text_xl, a.font_bold, a.leading_snug]}>
125 <Trans>Welcome back!</Trans>
126 </Text>
127 <Text style={[a.text_sm, a.leading_snug]}>
128 <Trans>
129 You previously deactivated @{currentAccount?.handle}.
130 </Trans>
131 </Text>
132 <Text style={[a.text_sm, a.leading_snug, a.pb_md]}>
133 <Trans>
134 You can reactivate your account to continue logging in. Your
135 profile and posts will be visible to other users.
136 </Trans>
137 </Text>
138
139 <View style={[a.gap_sm]}>
140 <Button
141 label={_(msg`Reactivate your account`)}
142 size="large"
143 variant="solid"
144 color="primary"
145 onPress={handleActivate}>
146 <ButtonText>
147 <Trans>Yes, reactivate my account</Trans>
148 </ButtonText>
149 {pending && <ButtonIcon icon={Loader} position="right" />}
150 </Button>
151 <Button
152 label={_(msg`Cancel reactivation and sign out`)}
153 size="large"
154 variant="solid"
155 color="secondary"
156 onPress={onPressLogout}>
157 <ButtonText>
158 <Trans>Cancel</Trans>
159 </ButtonText>
160 </Button>
161 </View>
162
163 {error && (
164 <View
165 style={[
166 a.flex_row,
167 a.gap_sm,
168 a.mt_md,
169 a.p_md,
170 a.rounded_sm,
171 t.atoms.bg_contrast_25,
172 ]}>
173 <CircleInfo size="md" fill={t.palette.negative_400} />
174 <Text style={[a.flex_1, a.leading_snug]}>{error}</Text>
175 </View>
176 )}
177 </View>
178
179 <View style={[a.pb_3xl]}>
180 <Divider />
181 </View>
182
183 {hasOtherAccounts ? (
184 <>
185 <Text
186 style={[t.atoms.text_contrast_medium, a.pb_md, a.leading_snug]}>
187 <Trans>Or, sign in to one of your other accounts.</Trans>
188 </Text>
189 <AccountList
190 onSelectAccount={onSelectAccount}
191 onSelectOther={onPressAddAccount}
192 otherLabel={_(msg`Add account`)}
193 pendingDid={pendingDid}
194 />
195 </>
196 ) : (
197 <>
198 <Text
199 style={[t.atoms.text_contrast_medium, a.pb_md, a.leading_snug]}>
200 <Trans>Or, continue with another account.</Trans>
201 </Text>
202 <Button
203 label={_(msg`Sign in or create an account`)}
204 size="large"
205 variant="solid"
206 color="secondary"
207 onPress={() => setShowLoggedOut(true)}>
208 <ButtonText>
209 <Trans>Sign in or create an account</Trans>
210 </ButtonText>
211 </Button>
212 </>
213 )}
214 </View>
215 </Layout.Content>
216 </View>
217 )
218}