fix: 🐛
This commit is contained in:
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user