feat: add quick account switch interaction
This commit is contained in:
parent
f33c5260df
commit
ad6b8890c5
24 changed files with 217 additions and 85 deletions
|
|
@ -1,22 +1,24 @@
|
|||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { toWallet } from '@/lib/link'
|
||||
import { formatPubkey, generateImageByPubkey } from '@/lib/pubkey'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { usePrimaryPage, useSecondaryPage } from '@/PageManager'
|
||||
import { useSecondaryPage } from '@/PageManager'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
import { ArrowDownUp, LogIn, LogOut, UserRound, Wallet } from 'lucide-react'
|
||||
import { LogIn, LogOut, Plus, Wallet } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import LoginDialog from '../LoginDialog'
|
||||
import LogoutDialog from '../LogoutDialog'
|
||||
import SignerTypeBadge from '../SignerTypeBadge'
|
||||
import { SimpleUserAvatar } from '../UserAvatar'
|
||||
import { SimpleUsername } from '../Username'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function AccountButton({ collapse }: { collapse: boolean }) {
|
||||
|
|
@ -31,17 +33,13 @@ export default function AccountButton({ collapse }: { collapse: boolean }) {
|
|||
|
||||
function ProfileButton({ collapse }: { collapse: boolean }) {
|
||||
const { t } = useTranslation()
|
||||
const { account, profile } = useNostr()
|
||||
const { account, accounts, switchAccount } = useNostr()
|
||||
const pubkey = account?.pubkey
|
||||
const { navigate } = usePrimaryPage()
|
||||
const { push } = useSecondaryPage()
|
||||
const [loginDialogOpen, setLoginDialogOpen] = useState(false)
|
||||
const [logoutDialogOpen, setLogoutDialogOpen] = useState(false)
|
||||
if (!pubkey) return null
|
||||
|
||||
const defaultAvatar = generateImageByPubkey(pubkey)
|
||||
const { username, avatar } = profile || { username: formatPubkey(pubkey), avatar: defaultAvatar }
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
|
@ -53,37 +51,68 @@ function ProfileButton({ collapse }: { collapse: boolean }) {
|
|||
)}
|
||||
>
|
||||
<div className="flex gap-2 items-center flex-1 w-0">
|
||||
<Avatar className="w-8 h-8">
|
||||
<AvatarImage src={avatar} />
|
||||
<AvatarFallback>
|
||||
<img src={defaultAvatar} />
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
{!collapse && <div className="truncate font-semibold text-lg">{username}</div>}
|
||||
<SimpleUserAvatar size="medium" userId={pubkey} />
|
||||
{!collapse && (
|
||||
<SimpleUsername className="truncate font-semibold text-lg" userId={pubkey} />
|
||||
)}
|
||||
</div>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent side="top">
|
||||
<DropdownMenuItem onClick={() => navigate('profile')}>
|
||||
<UserRound />
|
||||
{t('Profile')}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuContent side="top" className="w-72">
|
||||
<DropdownMenuItem onClick={() => push(toWallet())}>
|
||||
<Wallet />
|
||||
{t('Wallet')}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={() => setLoginDialogOpen(true)}>
|
||||
<ArrowDownUp />
|
||||
{t('Switch account')}
|
||||
<DropdownMenuLabel>{t('Switch account')}</DropdownMenuLabel>
|
||||
{accounts.map((act) => (
|
||||
<DropdownMenuItem
|
||||
className={act.pubkey === pubkey ? 'cursor-default focus:bg-background' : ''}
|
||||
key={`${act.pubkey}:${act.signerType}`}
|
||||
onClick={() => {
|
||||
if (act.pubkey !== pubkey) {
|
||||
switchAccount(act)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="flex gap-2 items-center flex-1">
|
||||
<SimpleUserAvatar userId={act.pubkey} />
|
||||
<div className="flex-1 w-0">
|
||||
<SimpleUsername
|
||||
userId={act.pubkey}
|
||||
className="font-medium truncate"
|
||||
skeletonClassName="h-3"
|
||||
/>
|
||||
<SignerTypeBadge signerType={act.signerType} />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
'border border-muted-foreground rounded-full size-3.5',
|
||||
act.pubkey === pubkey && 'size-4 border-4 border-primary'
|
||||
)}
|
||||
/>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
<DropdownMenuItem
|
||||
onClick={() => setLoginDialogOpen(true)}
|
||||
className="border border-dashed m-2 focus:border-muted-foreground focus:bg-background"
|
||||
>
|
||||
<div className="flex gap-2 items-center justify-center w-full py-2">
|
||||
<Plus />
|
||||
{t('Add an Account')}
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="text-destructive focus:text-destructive"
|
||||
onClick={() => setLogoutDialogOpen(true)}
|
||||
>
|
||||
<LogOut />
|
||||
{t('Logout')}
|
||||
<span className="shrink-0">{t('Logout')}</span>
|
||||
<SimpleUsername
|
||||
userId={pubkey}
|
||||
className="text-muted-foreground border border-muted-foreground px-1 rounded-md text-xs truncate"
|
||||
/>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
<LoginDialog open={loginDialogOpen} setOpen={setLoginDialogOpen} />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue