diff options
author | Eric Bailey <git@esb.lol> | 2024-06-03 20:10:43 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-04 02:10:43 +0100 |
commit | 3e1f0768916774642516d88254a6cf7a6a82331f (patch) | |
tree | 03204ed91e457eef7082c8cf8e1213bb622e5bdb /src/screens/Deactivated.tsx | |
parent | de93e8de746f3c8a7b1755aaa034043951371ae0 (diff) | |
download | voidsky-3e1f0768916774642516d88254a6cf7a6a82331f.tar.zst |
[🙅] Disambiguation of the deactivation (#4267)
* Disambiguation of the deactivation * Snapshot crackle pop * Change log context * [🙅] Add status to session state (#4269) * Add status to session state * [🙅] Add new deactivated screen (#4270) * Add new deactivated screen * Update copy, handle logout * Remove icons, adjust padding * [🙅] Add deactivate account dialog (#4290) * Deactivate dialog (cherry picked from commit 33940e2dfe0d710c0665a7f68b198b46f54db4a2) * Factor out dialog, add to delete modal too (cherry picked from commit 47d70f6b74e7d2ea7330fd172499fe91ba41062d) * Update copy, icon (cherry picked from commit e6efabbe78c3f3d9f0f8fb0a06a6a1c4fbfb70a9) * Update copy (cherry picked from commit abb0ce26f6747ab0548f6f12df0dee3c64464852) * Sizing tweaks (cherry picked from commit fc716d5716873f0fddef56496fc48af0614b2e55) * Add a11y label
Diffstat (limited to 'src/screens/Deactivated.tsx')
-rw-r--r-- | src/screens/Deactivated.tsx | 307 |
1 files changed, 131 insertions, 176 deletions
diff --git a/src/screens/Deactivated.tsx b/src/screens/Deactivated.tsx index c9e9f9525..faee517cb 100644 --- a/src/screens/Deactivated.tsx +++ b/src/screens/Deactivated.tsx @@ -1,19 +1,22 @@ import React from 'react' import {View} from 'react-native' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {msg, plural, Trans} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useFocusEffect} from '@react-navigation/native' -import {logger} from '#/logger' +import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher' import {isWeb} from '#/platform/detection' -import {isSessionDeactivated, useAgent, useSessionApi} from '#/state/session' -import {useOnboardingDispatch} from '#/state/shell' +import {type SessionAccount, useSession, useSessionApi} from '#/state/session' +import {useSetMinimalShellMode} from '#/state/shell' +import {useLoggedOutViewControls} from '#/state/shell/logged-out' import {ScrollView} from '#/view/com/util/Views' import {Logo} from '#/view/icons/Logo' -import {atoms as a, useBreakpoints, useTheme} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {Loader} from '#/components/Loader' -import {P, Text} from '#/components/Typography' +import {atoms as a, useTheme} from '#/alf' +import {AccountList} from '#/components/AccountList' +import {Button, ButtonText} from '#/components/Button' +import {Divider} from '#/components/Divider' +import {Text} from '#/components/Typography' const COL_WIDTH = 400 @@ -21,199 +24,151 @@ export function Deactivated() { const {_} = useLingui() const t = useTheme() const insets = useSafeAreaInsets() - const {gtMobile} = useBreakpoints() - const onboardingDispatch = useOnboardingDispatch() + const {currentAccount, accounts} = useSession() + const {onPressSwitchAccount, pendingDid} = useAccountSwitcher() + const {setShowLoggedOut} = useLoggedOutViewControls() + const hasOtherAccounts = accounts.length > 1 + const setMinimalShellMode = useSetMinimalShellMode() const {logout} = useSessionApi() - const agent = useAgent() - const [isProcessing, setProcessing] = React.useState(false) - const [estimatedTime, setEstimatedTime] = React.useState<string | undefined>( - undefined, - ) - const [placeInQueue, setPlaceInQueue] = React.useState<number | undefined>( - undefined, + useFocusEffect( + React.useCallback(() => { + setMinimalShellMode(true) + }, [setMinimalShellMode]), ) - const checkStatus = React.useCallback(async () => { - setProcessing(true) - try { - const res = await agent.com.atproto.temp.checkSignupQueue() - if (res.data.activated) { - // ready to go, exchange the access token for a usable one and kick off onboarding - await agent.refreshSession() - if (!isSessionDeactivated(agent.session?.accessJwt)) { - onboardingDispatch({type: 'start'}) - } - } else { - // not ready, update UI - setEstimatedTime(msToString(res.data.estimatedTimeMs)) - if (typeof res.data.placeInQueue !== 'undefined') { - setPlaceInQueue(Math.max(res.data.placeInQueue, 1)) - } + const onSelectAccount = React.useCallback( + (account: SessionAccount) => { + if (account.did !== currentAccount?.did) { + onPressSwitchAccount(account, 'SwitchAccount') } - } catch (e: any) { - logger.error('Failed to check signup queue', {err: e.toString()}) - } finally { - setProcessing(false) - } - }, [ - setProcessing, - setEstimatedTime, - setPlaceInQueue, - onboardingDispatch, - agent, - ]) + }, + [currentAccount, onPressSwitchAccount], + ) - React.useEffect(() => { - checkStatus() - const interval = setInterval(checkStatus, 60e3) - return () => clearInterval(interval) - }, [checkStatus]) + const onPressAddAccount = React.useCallback(() => { + setShowLoggedOut(true) + }, [setShowLoggedOut]) - const checkBtn = ( - <Button - variant="solid" - color="primary" - size="large" - label={_(msg`Check my status`)} - onPress={checkStatus} - disabled={isProcessing}> - <ButtonText> - <Trans>Check my status</Trans> - </ButtonText> - {isProcessing && <ButtonIcon icon={Loader} />} - </Button> - ) + const onPressLogout = React.useCallback(() => { + if (isWeb) { + // We're switching accounts, which remounts the entire app. + // On mobile, this gets us Home, but on the web we also need reset the URL. + // We can't change the URL via a navigate() call because the navigator + // itself is about to unmount, and it calls pushState() too late. + // So we change the URL ourselves. The navigator will pick it up on remount. + history.pushState(null, '', '/') + } + logout('Deactivated') + }, [logout]) return ( - <View - aria-modal - role="dialog" - aria-role="dialog" - aria-label={_(msg`You're in line`)} - accessibilityLabel={_(msg`You're in line`)} - accessibilityHint="" - style={[a.absolute, a.inset_0, a.flex_1, t.atoms.bg]}> + <View style={[a.h_full_vh, a.flex_1, t.atoms.bg]}> <ScrollView style={[a.h_full, a.w_full]} contentContainerStyle={{borderWidth: 0}}> <View - style={[a.flex_row, a.justify_center, gtMobile ? a.pt_4xl : a.px_xl]}> - <View style={[a.flex_1, {maxWidth: COL_WIDTH}]}> - <View - style={[a.w_full, a.justify_center, a.align_center, a.my_4xl]}> - <Logo width={120} /> - </View> - - <Text style={[a.text_4xl, a.font_bold, a.pb_sm]}> - <Trans>You're in line</Trans> - </Text> - <P style={[t.atoms.text_contrast_medium]}> - <Trans> - There's been a rush of new users to Bluesky! We'll activate your - account as soon as we can. - </Trans> - </P> + style={[ + a.px_2xl, + { + paddingTop: isWeb ? 64 : insets.top, + paddingBottom: isWeb ? 64 : insets.bottom, + }, + ]}> + <View style={[a.flex_row, a.justify_center]}> + <View style={[a.w_full, {maxWidth: COL_WIDTH}]}> + <View + style={[a.w_full, a.justify_center, a.align_center, a.pb_5xl]}> + <Logo width={40} /> + </View> - <View - style={[ - a.rounded_sm, - a.px_2xl, - a.py_4xl, - a.mt_2xl, - t.atoms.bg_contrast_50, - ]}> - {typeof placeInQueue === 'number' && ( - <Text - style={[a.text_5xl, a.text_center, a.font_bold, a.mb_2xl]}> - {placeInQueue} + <View style={[a.gap_xs, a.pb_3xl]}> + <Text style={[a.text_xl, a.font_bold, a.leading_snug]}> + <Trans>Welcome back!</Trans> </Text> - )} - <P style={[a.text_center]}> - {typeof placeInQueue === 'number' ? ( - <Trans>left to go.</Trans> - ) : ( - <Trans>You are in line.</Trans> - )}{' '} - {estimatedTime ? ( + <Text style={[a.text_sm, a.leading_snug]}> <Trans> - We estimate {estimatedTime} until your account is ready. + You previously deactivated @{currentAccount?.handle}. </Trans> - ) : ( + </Text> + <Text style={[a.text_sm, a.leading_snug, a.pb_md]}> <Trans> - We will let you know when your account is ready. + You can reactivate your account to continue logging in. Your + profile and posts will be visible to other users. </Trans> - )} - </P> - </View> + </Text> - {isWeb && gtMobile && ( - <View style={[a.w_full, a.flex_row, a.justify_between, a.pt_5xl]}> - <Button - variant="ghost" - size="large" - label={_(msg`Log out`)} - onPress={() => logout('Deactivated')}> - <ButtonText style={[{color: t.palette.primary_500}]}> - <Trans>Log out</Trans> - </ButtonText> - </Button> - {checkBtn} + <View style={[a.gap_sm]}> + <Button + label={_(msg`Reactivate your account`)} + size="medium" + variant="solid" + color="primary" + onPress={() => setShowLoggedOut(true)}> + <ButtonText> + <Trans>Yes, reactivate my account</Trans> + </ButtonText> + </Button> + <Button + label={_(msg`Cancel reactivation and log out`)} + size="medium" + variant="solid" + color="secondary" + onPress={onPressLogout}> + <ButtonText> + <Trans>Cancel</Trans> + </ButtonText> + </Button> + </View> </View> - )} - </View> - <View style={{height: 200}} /> - </View> - </ScrollView> + <View style={[a.pb_3xl]}> + <Divider /> + </View> - {(!isWeb || !gtMobile) && ( - <View - style={[ - a.align_center, - gtMobile ? a.px_5xl : a.px_xl, - { - paddingBottom: Math.max(insets.bottom, a.pb_5xl.paddingBottom), - }, - ]}> - <View style={[a.w_full, a.gap_sm, {maxWidth: COL_WIDTH}]}> - {checkBtn} - <Button - variant="ghost" - size="large" - label={_(msg`Log out`)} - onPress={() => logout('Deactivated')}> - <ButtonText style={[{color: t.palette.primary_500}]}> - <Trans>Log out</Trans> - </ButtonText> - </Button> + {hasOtherAccounts ? ( + <> + <Text + style={[ + t.atoms.text_contrast_medium, + a.pb_md, + a.leading_snug, + ]}> + <Trans>Or, log into one of your other accounts.</Trans> + </Text> + <AccountList + onSelectAccount={onSelectAccount} + onSelectOther={onPressAddAccount} + otherLabel={_(msg`Add account`)} + pendingDid={pendingDid} + /> + </> + ) : ( + <> + <Text + style={[ + t.atoms.text_contrast_medium, + a.pb_md, + a.leading_snug, + ]}> + <Trans>Or, continue with another account.</Trans> + </Text> + <Button + label={_(msg`Log in or sign up`)} + size="medium" + variant="solid" + color="secondary" + onPress={() => setShowLoggedOut(true)}> + <ButtonText> + <Trans>Log in or sign up</Trans> + </ButtonText> + </Button> + </> + )} + </View> </View> </View> - )} + </ScrollView> </View> ) } - -function msToString(ms: number | undefined): string | undefined { - if (ms && ms > 0) { - const estimatedTimeMins = Math.ceil(ms / 60e3) - if (estimatedTimeMins > 59) { - const estimatedTimeHrs = Math.round(estimatedTimeMins / 60) - if (estimatedTimeHrs > 6) { - // dont even bother - return undefined - } - // hours - return `${estimatedTimeHrs} ${plural(estimatedTimeHrs, { - one: 'hour', - other: 'hours', - })}` - } - // minutes - return `${estimatedTimeMins} ${plural(estimatedTimeMins, { - one: 'minute', - other: 'minutes', - })}` - } - return undefined -} |