Move global "Sign out" out of the current account row (#4941)

* Rename logout to logoutEveryAccount

* Add logoutCurrentAccount()

* Make all "Log out" buttons refer to current account

Each of these usages is completely contextual and refers to a specific account.

* Add Sign out of all accounts to Settings

* Move single account Sign Out below as well

* Prompt on account removal

* Add Other Accounts header to reduce ambiguity

* Spacing fix

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
This commit is contained in:
dan 2024-08-15 20:58:13 +01:00 committed by GitHub
parent f3b57dd456
commit b6e515c664
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 247 additions and 77 deletions

View file

@ -20,7 +20,7 @@ const BTN = {height: 1, width: 1, backgroundColor: 'red'}
export function TestCtrls() {
const queryClient = useQueryClient()
const {logout, login} = useSessionApi()
const {logoutEveryAccount, login} = useSessionApi()
const {openModal} = useModalControls()
const onboardingDispatch = useOnboardingDispatch()
const {setShowLoggedOut} = useLoggedOutViewControls()
@ -60,7 +60,7 @@ export function TestCtrls() {
/>
<Pressable
testID="e2eSignOut"
onPress={() => logout('Settings')}
onPress={() => logoutEveryAccount('Settings')}
accessibilityRole="button"
style={BTN}
/>

View file

@ -4,26 +4,27 @@ import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {DropdownItem, NativeDropdown} from './forms/NativeDropdown'
import * as Toast from '../../com/util/Toast'
import {useSessionApi, SessionAccount} from '#/state/session'
import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {SessionAccount, useSessionApi} from '#/state/session'
import {usePalette} from 'lib/hooks/usePalette'
import {s} from 'lib/styles'
import {useDialogControl} from '#/components/Dialog'
import * as Prompt from '#/components/Prompt'
import * as Toast from '../../com/util/Toast'
import {DropdownItem, NativeDropdown} from './forms/NativeDropdown'
export function AccountDropdownBtn({account}: {account: SessionAccount}) {
const pal = usePalette('default')
const {removeAccount} = useSessionApi()
const removePromptControl = useDialogControl()
const {_} = useLingui()
const items: DropdownItem[] = [
{
label: _(msg`Remove account`),
onPress: () => {
removeAccount(account)
Toast.show(_(msg`Account removed from quick access`))
},
onPress: removePromptControl.open,
icon: {
ios: {
name: 'trash',
@ -34,17 +35,32 @@ export function AccountDropdownBtn({account}: {account: SessionAccount}) {
},
]
return (
<Pressable accessibilityRole="button" style={s.pl10}>
<NativeDropdown
testID="accountSettingsDropdownBtn"
items={items}
accessibilityLabel={_(msg`Account options`)}
accessibilityHint="">
<FontAwesomeIcon
icon="ellipsis-h"
style={pal.textLight as FontAwesomeIconStyle}
/>
</NativeDropdown>
</Pressable>
<>
<Pressable accessibilityRole="button" style={s.pl10}>
<NativeDropdown
testID="accountSettingsDropdownBtn"
items={items}
accessibilityLabel={_(msg`Account options`)}
accessibilityHint="">
<FontAwesomeIcon
icon="ellipsis-h"
style={pal.textLight as FontAwesomeIconStyle}
/>
</NativeDropdown>
</Pressable>
<Prompt.Basic
control={removePromptControl}
title={_(msg`Remove from quick access?`)}
description={_(
msg`This will remove @${account.handle} from the quick access list.`,
)}
onConfirm={() => {
removeAccount(account)
Toast.show(_(msg`Account removed from quick access`))
}}
confirmButtonCta={_(msg`Remove`)}
confirmButtonColor="negative"
/>
</>
)
}

View file

@ -57,7 +57,6 @@ import {DeactivateAccountDialog} from '#/screens/Settings/components/DeactivateA
import {atoms as a, useTheme} from '#/alf'
import {useDialogControl} from '#/components/Dialog'
import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings'
import {navigate, resetToTab} from '#/Navigation'
import {Email2FAToggle} from './Email2FAToggle'
import {ExportCarDialog} from './ExportCarDialog'
@ -77,7 +76,6 @@ function SettingsAccountCard({
const {_} = useLingui()
const t = useTheme()
const {currentAccount} = useSession()
const {logout} = useSessionApi()
const {data: profile} = useProfileQuery({did: account.did})
const isCurrentAccount = account.did === currentAccount?.did
@ -103,31 +101,7 @@ function SettingsAccountCard({
{account.handle}
</Text>
</View>
{isCurrentAccount ? (
<TouchableOpacity
testID="signOutBtn"
onPress={() => {
if (isNative) {
logout('Settings')
resetToTab('HomeTab')
} else {
navigate('Home').then(() => {
logout('Settings')
})
}
}}
accessibilityRole="button"
accessibilityLabel={_(msg`Sign out`)}
accessibilityHint={`Signs ${profile?.displayName} out of Bluesky`}
activeOpacity={0.8}>
<Text type="lg" style={pal.link}>
<Trans>Sign out</Trans>
</Text>
</TouchableOpacity>
) : (
<AccountDropdownBtn account={account} />
)}
<AccountDropdownBtn account={account} />
</View>
)
@ -173,6 +147,7 @@ export function SettingsScreen({}: Props) {
const {accounts, currentAccount} = useSession()
const {mutate: clearPreferences} = useClearPreferencesMutation()
const {setShowLoggedOut} = useLoggedOutViewControls()
const {logoutEveryAccount} = useSessionApi()
const closeAllActiveElements = useCloseAllActiveElements()
const exportCarControl = useDialogControl()
const birthdayControl = useDialogControl()
@ -237,6 +212,10 @@ export function SettingsScreen({}: Props) {
openModal({name: 'delete-account'})
}, [openModal])
const onPressLogoutEveryAccount = React.useCallback(() => {
logoutEveryAccount('Settings')
}, [logoutEveryAccount])
const onPressResetPreferences = React.useCallback(async () => {
clearPreferences()
}, [clearPreferences])
@ -394,6 +373,15 @@ export function SettingsScreen({}: Props) {
) : null}
<View pointerEvents={pendingDid ? 'none' : 'auto'}>
{accounts.length > 1 && (
<View style={[s.flexRow, styles.heading, a.mt_sm]}>
<Text type="xl-bold" style={pal.text} numberOfLines={1}>
<Trans>Other accounts</Trans>
</Text>
<View style={s.flex1} />
</View>
)}
{accounts
.filter(a => a.did !== currentAccount?.did)
.map(account => (
@ -422,6 +410,29 @@ export function SettingsScreen({}: Props) {
<Trans>Add account</Trans>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.linkCard, pal.view]}
onPress={
isSwitchingAccounts ? undefined : onPressLogoutEveryAccount
}
accessibilityRole="button"
accessibilityLabel={_(msg`Sign out of all accounts`)}
accessibilityHint={undefined}>
<View style={[styles.iconContainer, pal.btn]}>
<FontAwesomeIcon
icon="arrow-right-from-bracket"
style={pal.text as FontAwesomeIconStyle}
/>
</View>
<Text type="lg" style={pal.text}>
{accounts.length > 1 ? (
<Trans>Sign out of all accounts</Trans>
) : (
<Trans>Sign out</Trans>
)}
</Text>
</TouchableOpacity>
</View>
<View style={styles.spacer20} />