feat: add quick account switch interaction

This commit is contained in:
codytseng 2025-10-26 16:11:21 +08:00
parent f33c5260df
commit ad6b8890c5
24 changed files with 217 additions and 85 deletions

View file

@ -1,36 +1,57 @@
import { Skeleton } from '@/components/ui/skeleton'
import { LONG_PRESS_THRESHOLD } from '@/constants'
import { cn } from '@/lib/utils'
import { usePrimaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import { UserRound } from 'lucide-react'
import { useMemo } from 'react'
import { useMemo, useRef, useState } from 'react'
import LoginDialog from '../LoginDialog'
import { SimpleUserAvatar } from '../UserAvatar'
import BottomNavigationBarItem from './BottomNavigationBarItem'
export default function AccountButton() {
const { navigate, current, display } = usePrimaryPage()
const { pubkey, profile } = useNostr()
const [loginDialogOpen, setLoginDialogOpen] = useState(false)
const active = useMemo(() => current === 'me' && display, [display, current])
const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const handlePointerDown = () => {
pressTimerRef.current = setTimeout(() => {
setLoginDialogOpen(true)
pressTimerRef.current = null
}, LONG_PRESS_THRESHOLD)
}
const handlePointerUp = () => {
if (pressTimerRef.current) {
clearTimeout(pressTimerRef.current)
navigate('me')
pressTimerRef.current = null
}
}
return (
<BottomNavigationBarItem
onClick={() => {
navigate('me')
}}
active={active}
>
{pubkey ? (
profile ? (
<SimpleUserAvatar
userId={pubkey}
className={cn('w-7 h-7', active ? 'ring-primary ring-1' : '')}
/>
<>
<BottomNavigationBarItem
onPointerDown={handlePointerDown}
onPointerUp={handlePointerUp}
active={active}
>
{pubkey ? (
profile ? (
<SimpleUserAvatar
userId={pubkey}
className={cn('w-7 h-7', active ? 'ring-primary ring-1' : '')}
/>
) : (
<Skeleton className={cn('w-7 h-7 rounded-full', active ? 'ring-primary ring-1' : '')} />
)
) : (
<Skeleton className={cn('w-7 h-7 rounded-full', active ? 'ring-primary ring-1' : '')} />
)
) : (
<UserRound />
)}
</BottomNavigationBarItem>
<UserRound />
)}
</BottomNavigationBarItem>
<LoginDialog open={loginDialogOpen} setOpen={setLoginDialogOpen} />
</>
)
}

View file

@ -1,15 +1,19 @@
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import { Button } from '../ui/button'
import { MouseEventHandler } from 'react'
export default function BottomNavigationBarItem({
children,
active = false,
onClick
onClick,
onPointerDown,
onPointerUp
}: {
children: React.ReactNode
active?: boolean
onClick: MouseEventHandler
onClick?: MouseEventHandler
onPointerDown?: MouseEventHandler
onPointerUp?: MouseEventHandler
}) {
return (
<Button
@ -19,6 +23,8 @@ export default function BottomNavigationBarItem({
)}
variant="ghost"
onClick={onClick}
onPointerDown={onPointerDown}
onPointerUp={onPointerUp}
>
{children}
</Button>