feat: implement drawer for profile options on small screens

This commit is contained in:
codytseng 2025-11-02 23:02:37 +08:00
parent 962359dcf5
commit e4f250907f

View file

@ -1,4 +1,5 @@
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Drawer, DrawerContent, DrawerOverlay } from '@/components/ui/drawer'
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -8,31 +9,112 @@ import {
import { pubkeyToNpub } from '@/lib/pubkey' import { pubkeyToNpub } from '@/lib/pubkey'
import { useMuteList } from '@/providers/MuteListProvider' import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { Bell, BellOff, Copy, Ellipsis } from 'lucide-react' import { Bell, BellOff, Copy, Ellipsis } from 'lucide-react'
import { useMemo } from 'react' import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
export default function ProfileOptions({ pubkey }: { pubkey: string }) { export default function ProfileOptions({ pubkey }: { pubkey: string }) {
const { t } = useTranslation() const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { pubkey: accountPubkey } = useNostr() const { pubkey: accountPubkey } = useNostr()
const { mutePubkeySet, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } = useMuteList() const { mutePubkeySet, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } = useMuteList()
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const isMuted = useMemo(() => mutePubkeySet.has(pubkey), [mutePubkeySet, pubkey]) const isMuted = useMemo(() => mutePubkeySet.has(pubkey), [mutePubkeySet, pubkey])
if (pubkey === accountPubkey) return null if (pubkey === accountPubkey) return null
return ( const trigger = (
<DropdownMenu> <Button
<DropdownMenuTrigger asChild> variant="secondary"
<Button variant="secondary" size="icon" className="rounded-full"> size="icon"
className="rounded-full"
onClick={() => {
if (isSmallScreen) {
setIsDrawerOpen(true)
}
}}
>
<Ellipsis /> <Ellipsis />
</Button> </Button>
</DropdownMenuTrigger> )
if (isSmallScreen) {
return (
<>
{trigger}
<Drawer open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>
<DrawerOverlay onClick={() => setIsDrawerOpen(false)} />
<DrawerContent hideOverlay>
<div className="py-2">
<Button
onClick={() => {
setIsDrawerOpen(false)
navigator.clipboard.writeText(pubkeyToNpub(pubkey) ?? '')
}}
className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5"
variant="ghost"
>
<Copy />
{t('Copy user ID')}
</Button>
{accountPubkey ? (
isMuted ? (
<Button
onClick={() => {
setIsDrawerOpen(false)
unmutePubkey(pubkey)
}}
className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 text-destructive focus:text-destructive"
variant="ghost"
>
<Bell />
{t('Unmute user')}
</Button>
) : (
<>
<Button
onClick={() => {
setIsDrawerOpen(false)
mutePubkeyPrivately(pubkey)
}}
className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 text-destructive focus:text-destructive"
variant="ghost"
>
<BellOff />
{t('Mute user privately')}
</Button>
<Button
onClick={() => {
setIsDrawerOpen(false)
mutePubkeyPublicly(pubkey)
}}
className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 text-destructive focus:text-destructive"
variant="ghost"
>
<BellOff />
{t('Mute user publicly')}
</Button>
</>
)
) : null}
</div>
</DrawerContent>
</Drawer>
</>
)
}
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
<DropdownMenuContent> <DropdownMenuContent>
<DropdownMenuItem onClick={() => navigator.clipboard.writeText(pubkeyToNpub(pubkey) ?? '')}> <DropdownMenuItem onClick={() => navigator.clipboard.writeText(pubkeyToNpub(pubkey) ?? '')}>
<Copy /> <Copy />
{t('Copy user ID')} {t('Copy user ID')}
</DropdownMenuItem> </DropdownMenuItem>
{isMuted ? ( {accountPubkey ? (
isMuted ? (
<DropdownMenuItem <DropdownMenuItem
onClick={() => unmutePubkey(pubkey)} onClick={() => unmutePubkey(pubkey)}
className="text-destructive focus:text-destructive" className="text-destructive focus:text-destructive"
@ -57,7 +139,8 @@ export default function ProfileOptions({ pubkey }: { pubkey: string }) {
{t('Mute user publicly')} {t('Mute user publicly')}
</DropdownMenuItem> </DropdownMenuItem>
</> </>
)} )
) : null}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
) )