fix: 🐛

This commit is contained in:
codytseng
2025-09-22 22:45:38 +08:00
parent 766f890b93
commit 1ff965969d

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,
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
@@ -6,11 +7,14 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger DropdownMenuTrigger
} from '@/components/ui/dropdown-menu' } from '@/components/ui/dropdown-menu'
import { Separator } from '@/components/ui/separator'
import { isProtectedEvent } from '@/lib/event' import { isProtectedEvent } from '@/lib/event'
import { simplifyUrl } from '@/lib/url' import { simplifyUrl } from '@/lib/url'
import { useCurrentRelays } from '@/providers/CurrentRelaysProvider' import { useCurrentRelays } from '@/providers/CurrentRelaysProvider'
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider' import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import client from '@/services/client.service' import client from '@/services/client.service'
import { Check } from 'lucide-react'
import { NostrEvent } from 'nostr-tools' import { NostrEvent } from 'nostr-tools'
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react' import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@@ -42,6 +46,8 @@ export default function PostRelaySelector({
setAdditionalRelayUrls: Dispatch<SetStateAction<string[]>> setAdditionalRelayUrls: Dispatch<SetStateAction<string[]>>
}) { }) {
const { t } = useTranslation() const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const { relayUrls } = useCurrentRelays() const { relayUrls } = useCurrentRelays()
const { relaySets, favoriteRelays } = useFavoriteRelays() const { relaySets, favoriteRelays } = useFavoriteRelays()
const [postTargetItems, setPostTargetItems] = useState<TPostTargetItem[]>([]) const [postTargetItems, setPostTargetItems] = useState<TPostTargetItem[]>([])
@@ -147,63 +153,135 @@ export default function PostRelaySelector({
[] []
) )
return ( const content = useMemo(() => {
<DropdownMenu> return (
<div className="flex items-center gap-2"> <>
{t('Post to')} <MenuItem
<DropdownMenuTrigger asChild>
<Button variant="outline" className="px-2">
{description}
</Button>
</DropdownMenuTrigger>
</div>
<DropdownMenuContent align="start" className="max-w-96">
<DropdownMenuCheckboxItem
checked={postTargetItems.some((item) => item.type === 'writeRelays')} checked={postTargetItems.some((item) => item.type === 'writeRelays')}
onSelect={(e) => e.preventDefault()}
onCheckedChange={handleWriteRelaysCheckedChange} onCheckedChange={handleWriteRelaysCheckedChange}
> >
{t('Write relays')} {t('Write relays')}
</DropdownMenuCheckboxItem> </MenuItem>
{relaySets.length > 0 && ( {relaySets.length > 0 && (
<> <>
<DropdownMenuSeparator /> <MenuSeparator />
{relaySets {relaySets
.filter(({ relayUrls }) => relayUrls.length) .filter(({ relayUrls }) => relayUrls.length)
.map(({ id, name, relayUrls }) => ( .map(({ id, name, relayUrls }) => (
<DropdownMenuCheckboxItem <MenuItem
key={id} key={id}
checked={postTargetItems.some( checked={postTargetItems.some(
(item) => item.type === 'relaySet' && item.id === id (item) => item.type === 'relaySet' && item.id === id
)} )}
onSelect={(e) => e.preventDefault()}
onCheckedChange={(checked) => handleRelaySetCheckedChange(checked, id, relayUrls)} onCheckedChange={(checked) => handleRelaySetCheckedChange(checked, id, relayUrls)}
> >
<div className="truncate"> <div className="truncate">
{name} ({relayUrls.length}) {name} ({relayUrls.length})
</div> </div>
</DropdownMenuCheckboxItem> </MenuItem>
))} ))}
</> </>
)} )}
{selectableRelays.length > 0 && ( {selectableRelays.length > 0 && (
<> <>
<DropdownMenuSeparator /> <MenuSeparator />
{selectableRelays.map((url) => ( {selectableRelays.map((url) => (
<DropdownMenuCheckboxItem <MenuItem
key={url} key={url}
checked={postTargetItems.some((item) => item.type === 'relay' && item.url === url)} checked={postTargetItems.some((item) => item.type === 'relay' && item.url === url)}
onSelect={(e) => e.preventDefault()}
onCheckedChange={(checked) => handleRelayCheckedChange(checked, url)} onCheckedChange={(checked) => handleRelayCheckedChange(checked, url)}
className="flex items-center gap-2"
> >
<RelayIcon url={url} /> <div className="flex items-center gap-2">
<div className="truncate">{simplifyUrl(url)}</div> <RelayIcon url={url} />
</DropdownMenuCheckboxItem> <div className="truncate">{simplifyUrl(url)}</div>
</div>
</MenuItem>
))} ))}
</> </>
)} )}
</>
)
}, [postTargetItems, relaySets, selectableRelays])
if (isSmallScreen) {
return (
<>
<div className="flex items-center gap-2">
{t('Post to')}
<Button
variant="outline"
className="px-2 flex-1 max-w-fit justify-start"
onClick={() => setIsDrawerOpen(true)}
>
<div className="truncate">{description}</div>
</Button>
</div>
<Drawer open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>
<DrawerOverlay onClick={() => setIsDrawerOpen(false)} />
<DrawerContent hideOverlay>{content}</DrawerContent>
</Drawer>
</>
)
}
return (
<DropdownMenu>
<div className="flex items-center gap-2">
{t('Post to')}
<DropdownMenuTrigger asChild>
<Button variant="outline" className="px-2 flex-1 max-w-fit justify-start">
<div className="truncate">{description}</div>
</Button>
</DropdownMenuTrigger>
</div>
<DropdownMenuContent align="start" className="max-w-96">
{content}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
) )
} }
function MenuSeparator() {
const { isSmallScreen } = useScreenSize()
if (isSmallScreen) {
return <Separator />
}
return <DropdownMenuSeparator />
}
function MenuItem({
children,
checked,
onCheckedChange
}: {
children: React.ReactNode
checked: boolean
onCheckedChange: (checked: boolean) => void
}) {
const { isSmallScreen } = useScreenSize()
if (isSmallScreen) {
return (
<div
onClick={() => onCheckedChange(!checked)}
className="flex items-center gap-2 px-4 py-3 clickable"
>
<div className="flex items-center justify-center size-4 shrink-0">
{checked && <Check className="size-4" />}
</div>
{children}
</div>
)
}
return (
<DropdownMenuCheckboxItem
checked={checked}
onSelect={(e) => e.preventDefault()}
onCheckedChange={onCheckedChange}
className="flex items-center gap-2"
>
{children}
</DropdownMenuCheckboxItem>
)
}