index.tsx raw
1 import { Button } from '@/components/ui/button'
2 import { Drawer, DrawerContent, DrawerOverlay } from '@/components/ui/drawer'
3 import {
4 DropdownMenu,
5 DropdownMenuContent,
6 DropdownMenuItem,
7 DropdownMenuTrigger
8 } from '@/components/ui/dropdown-menu'
9 import { Pubkey } from '@/domain'
10 import { useMuteList } from '@/providers/MuteListProvider'
11 import { useNostr } from '@/providers/NostrProvider'
12 import { useScreenSize } from '@/providers/ScreenSizeProvider'
13 import { Bell, BellOff, Copy, Ellipsis } from 'lucide-react'
14 import { useMemo, useState } from 'react'
15 import { useTranslation } from 'react-i18next'
16
17 export default function ProfileOptions({ pubkey }: { pubkey: string }) {
18 const { t } = useTranslation()
19 const { isSmallScreen } = useScreenSize()
20 const { pubkey: accountPubkey } = useNostr()
21 const { mutePubkeySet, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } = useMuteList()
22 const [isDrawerOpen, setIsDrawerOpen] = useState(false)
23 const isMuted = useMemo(() => mutePubkeySet.has(pubkey), [mutePubkeySet, pubkey])
24
25 if (pubkey === accountPubkey) return null
26
27 const trigger = (
28 <Button
29 variant="secondary"
30 size="icon"
31 className="rounded-full"
32 onClick={() => {
33 if (isSmallScreen) {
34 setIsDrawerOpen(true)
35 }
36 }}
37 >
38 <Ellipsis />
39 </Button>
40 )
41
42 if (isSmallScreen) {
43 return (
44 <>
45 {trigger}
46 <Drawer open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>
47 <DrawerOverlay onClick={() => setIsDrawerOpen(false)} />
48 <DrawerContent hideOverlay>
49 <div className="py-2">
50 <Button
51 onClick={() => {
52 setIsDrawerOpen(false)
53 navigator.clipboard.writeText(Pubkey.tryFromString(pubkey)?.npub ?? '')
54 }}
55 className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5"
56 variant="ghost"
57 >
58 <Copy />
59 {t('Copy user ID')}
60 </Button>
61 {accountPubkey ? (
62 isMuted ? (
63 <Button
64 onClick={() => {
65 setIsDrawerOpen(false)
66 unmutePubkey(pubkey)
67 }}
68 className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 text-destructive focus:text-destructive"
69 variant="ghost"
70 >
71 <Bell />
72 {t('Unmute user')}
73 </Button>
74 ) : (
75 <>
76 <Button
77 onClick={() => {
78 setIsDrawerOpen(false)
79 mutePubkeyPrivately(pubkey)
80 }}
81 className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 text-destructive focus:text-destructive"
82 variant="ghost"
83 >
84 <BellOff />
85 {t('Mute user privately')}
86 </Button>
87 <Button
88 onClick={() => {
89 setIsDrawerOpen(false)
90 mutePubkeyPublicly(pubkey)
91 }}
92 className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 text-destructive focus:text-destructive"
93 variant="ghost"
94 >
95 <BellOff />
96 {t('Mute user publicly')}
97 </Button>
98 </>
99 )
100 ) : null}
101 </div>
102 </DrawerContent>
103 </Drawer>
104 </>
105 )
106 }
107
108 return (
109 <DropdownMenu>
110 <DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
111 <DropdownMenuContent>
112 <DropdownMenuItem onClick={() => navigator.clipboard.writeText(Pubkey.tryFromString(pubkey)?.npub ?? '')}>
113 <Copy />
114 {t('Copy user ID')}
115 </DropdownMenuItem>
116 {accountPubkey ? (
117 isMuted ? (
118 <DropdownMenuItem
119 onClick={() => unmutePubkey(pubkey)}
120 className="text-destructive focus:text-destructive"
121 >
122 <Bell />
123 {t('Unmute user')}
124 </DropdownMenuItem>
125 ) : (
126 <>
127 <DropdownMenuItem
128 onClick={() => mutePubkeyPrivately(pubkey)}
129 className="text-destructive focus:text-destructive"
130 >
131 <BellOff />
132 {t('Mute user privately')}
133 </DropdownMenuItem>
134 <DropdownMenuItem
135 onClick={() => mutePubkeyPublicly(pubkey)}
136 className="text-destructive focus:text-destructive"
137 >
138 <BellOff />
139 {t('Mute user publicly')}
140 </DropdownMenuItem>
141 </>
142 )
143 ) : null}
144 </DropdownMenuContent>
145 </DropdownMenu>
146 )
147 }
148