diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx
index fe0daed50e..db91c26a69 100644
--- a/src/components/AccountList.tsx
+++ b/src/components/AccountList.tsx
@@ -7,30 +7,34 @@ import {useLingui} from '@lingui/react'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useProfilesQuery} from '#/state/queries/profile'
-import {type SessionAccount, useSession} from '#/state/session'
+import {type SessionAccount, useSession, useSessionApi} from '#/state/session'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme} from '#/alf'
-import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
-import {ChevronRight_Stroke2_Corner0_Rounded as Chevron} from '#/components/icons/Chevron'
-import {Button} from './Button'
-import {Text} from './Typography'
+import {Button, ButtonText} from '#/components/Button'
+import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
+import {ChevronRight_Stroke2_Corner0_Rounded as ChevronIcon} from '#/components/icons/Chevron'
+import {Text} from '#/components/Typography'
+import {useDialogContext} from './Dialog'
export function AccountList({
onSelectAccount,
onSelectOther,
otherLabel,
pendingDid,
+ editing = false,
}: {
onSelectAccount: (account: SessionAccount) => void
onSelectOther: () => void
otherLabel?: string
pendingDid: string | null
+ editing?: boolean
}) {
const {currentAccount, accounts} = useSession()
const t = useTheme()
const {_} = useLingui()
const {data: profiles} = useProfilesQuery({
handles: accounts.map(acc => acc.did),
+ keepPrevious: true,
})
const onPressAddAccount = useCallback(() => {
@@ -46,46 +50,55 @@ export function AccountList({
{borderWidth: 1},
t.atoms.border_contrast_low,
]}>
- {accounts.map(account => (
-
+ {accounts.map((account, i) => (
+
p.did === account.did)}
account={account}
onSelect={onSelectAccount}
isCurrentAccount={account.did === currentAccount?.did}
isPendingAccount={account.did === pendingDid}
+ editing={editing}
/>
-
-
+
))}
-
+
+ {otherLabel ?? Other account}
+
+
+
+ )}
+
+ )}
)
}
@@ -96,20 +109,52 @@ function AccountItem({
onSelect,
isCurrentAccount,
isPendingAccount,
+ editing,
}: {
profile?: AppBskyActorDefs.ProfileViewDetailed
account: SessionAccount
onSelect: (account: SessionAccount) => void
isCurrentAccount: boolean
isPendingAccount: boolean
+ editing?: boolean
}) {
const t = useTheme()
const {_} = useLingui()
+ const control = useDialogContext()
+ const {logoutCurrentAccount, removeAccount} = useSessionApi()
const onPress = useCallback(() => {
onSelect(account)
}, [account, onSelect])
+ const onPressRemove = useCallback(() => {
+ if (isCurrentAccount) {
+ control.close(() => {
+ logoutCurrentAccount('AccountList')
+ })
+ } else {
+ removeAccount(account)
+ }
+ }, [control, logoutCurrentAccount, removeAccount, account, isCurrentAccount])
+
+ if (editing) {
+ return (
+
+
+
+ )
+ }
+
return (
)
}
+
+function AccountItemContent({
+ highlight,
+ profile,
+ account,
+
+ children,
+}: {
+ highlight?: boolean
+ profile?: AppBskyActorDefs.ProfileViewDetailed
+ account: SessionAccount
+ children?: React.ReactNode
+}) {
+ const t = useTheme()
+
+ return (
+
+
+
+
+
+
+ {sanitizeDisplayName(
+ profile?.displayName || profile?.handle || account.handle,
+ )}
+ {' '}
+
+ {sanitizeHandle(account.handle)}
+
+
+ {children}
+
+ )
+}
diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts
index b479bc7f06..3fb30c289d 100644
--- a/src/components/Dialog/context.ts
+++ b/src/components/Dialog/context.ts
@@ -9,7 +9,7 @@ import {
import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomSheet.types'
export const Context = React.createContext({
- close: () => {},
+ close: cb => cb?.(),
isNativeDialog: false,
nativeSnapPoint: BottomSheetSnapPoint.Hidden,
disableDrag: false,
diff --git a/src/components/dialogs/SwitchAccount.tsx b/src/components/dialogs/SwitchAccount.tsx
index ea870e2da9..509b963029 100644
--- a/src/components/dialogs/SwitchAccount.tsx
+++ b/src/components/dialogs/SwitchAccount.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback} from 'react'
+import React, {useCallback, useState} from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -7,9 +7,10 @@ import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
import {type SessionAccount, useSession} from '#/state/session'
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
import {atoms as a} from '#/alf'
+import {AccountList} from '#/components/AccountList'
+import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
-import {AccountList} from '../AccountList'
-import {Text} from '../Typography'
+import {Text} from '#/components/Typography'
export function SwitchAccountDialog({
control,
@@ -20,6 +21,7 @@ export function SwitchAccountDialog({
const {currentAccount} = useSession()
const {onPressSwitchAccount, pendingDid} = useAccountSwitcher()
const {setShowLoggedOut} = useLoggedOutViewControls()
+ const [editing, setEditing] = useState(false)
const onSelectAccount = useCallback(
(account: SessionAccount) => {
@@ -44,16 +46,34 @@ export function SwitchAccountDialog({
-
-
- Switch Account
-
+
+
+
+ Switch account
+
+
+
+
diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts
index 9a306ee4f4..024b69696e 100644
--- a/src/lib/statsig/events.ts
+++ b/src/lib/statsig/events.ts
@@ -13,7 +13,12 @@ export type LogEvents = {
withPassword: boolean
}
'account:loggedOut': {
- logContext: 'SwitchAccount' | 'Settings' | 'SignupQueued' | 'Deactivated'
+ logContext:
+ | 'SwitchAccount'
+ | 'Settings'
+ | 'SignupQueued'
+ | 'Deactivated'
+ | 'AccountList'
scope: 'current' | 'every'
}
'notifications:openApp': {}
diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts
index 3059d9efea..1726d6f677 100644
--- a/src/state/queries/profile.ts
+++ b/src/state/queries/profile.ts
@@ -10,6 +10,7 @@ import {
ComAtprotoRepoUploadBlob,
} from '@atproto/api'
import {
+ keepPreviousData,
QueryClient,
useMutation,
useQuery,
@@ -81,7 +82,13 @@ export function useProfileQuery({
})
}
-export function useProfilesQuery({handles}: {handles: string[]}) {
+export function useProfilesQuery({
+ handles,
+ keepPrevious,
+}: {
+ handles: string[]
+ keepPrevious: boolean
+}) {
const agent = useAgent()
return useQuery({
staleTime: STALE.MINUTES.FIVE,
@@ -90,6 +97,7 @@ export function useProfilesQuery({handles}: {handles: string[]}) {
const res = await agent.getProfiles({actors: handles})
return res.data
},
+ placeholderData: keepPrevious ? keepPreviousData : undefined,
})
}