import { Button } from '@/components/ui/button'
import {
Drawer,
DrawerContent,
DrawerHeader,
DrawerOverlay,
DrawerTitle
} from '@/components/ui/drawer'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { Separator } from '@/components/ui/separator'
import { normalizeUrl } from '@/lib/url'
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { TRelaySet } from '@/types'
import { Ban, Check, FolderPlus, Loader2, Plus, Star } from 'lucide-react'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import DrawerMenuItem from '../DrawerMenuItem'
export default function SaveRelayDropdownMenu({
urls,
bigButton = false
}: {
urls: string[]
bigButton?: boolean
}) {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { favoriteRelays, relaySets } = useFavoriteRelays()
const normalizedUrls = useMemo(() => urls.map((url) => normalizeUrl(url)).filter(Boolean), [urls])
const alreadySaved = useMemo(() => {
return (
normalizedUrls.every((url) => favoriteRelays.includes(url)) ||
relaySets.some((set) => normalizedUrls.every((url) => set.relayUrls.includes(url)))
)
}, [relaySets, normalizedUrls])
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const trigger = bigButton ? (
) : (
)
if (isSmallScreen) {
return (
{trigger}
e.stopPropagation()}>
setIsDrawerOpen(false)} />
{t('Save to')} ...
{relaySets.map((set) => (
))}
)
}
return (
{trigger}
e.stopPropagation()}>
{t('Save to')} ...
{relaySets.map((set) => (
))}
)
}
function RelayItem({ urls }: { urls: string[] }) {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { favoriteRelays, addFavoriteRelays, deleteFavoriteRelays } = useFavoriteRelays()
const [isLoading, setIsLoading] = useState(false)
const saved = useMemo(
() => urls.every((url) => favoriteRelays.includes(url)),
[favoriteRelays, urls]
)
const handleClick = async () => {
if (isLoading) return
setIsLoading(true)
try {
if (saved) {
await deleteFavoriteRelays(urls)
} else {
await addFavoriteRelays(urls)
}
} catch (error) {
console.error('Failed to toggle favorite relay:', error)
} finally {
setIsLoading(false)
}
}
if (isSmallScreen) {
return (
{isLoading ? '...' : (saved ? : )}
{isLoading ? t('Loading...') : (saved ? t('Unfavorite') : t('Favorite'))}
)
}
return (
{isLoading ? '...' : (saved ? : )}
{isLoading ? t('Loading...') : (saved ? t('Unfavorite') : t('Favorite'))}
)
}
function RelaySetItem({ set, urls }: { set: TRelaySet; urls: string[] }) {
const { isSmallScreen } = useScreenSize()
const { pubkey, startLogin } = useNostr()
const { updateRelaySet } = useFavoriteRelays()
const saved = urls.every((url) => set.relayUrls.includes(url))
const handleClick = () => {
if (!pubkey) {
startLogin()
return
}
if (saved) {
updateRelaySet({
...set,
relayUrls: set.relayUrls.filter((u) => !urls.includes(u))
})
} else {
updateRelaySet({
...set,
relayUrls: Array.from(new Set([
...set.relayUrls.map(url => normalizeUrl(url) || url),
...urls.map(url => normalizeUrl(url) || url)
]))
})
}
}
if (isSmallScreen) {
return (
{saved ? : }
{set.name}
)
}
return (
{saved ? : }
{set.name}
)
}
function SaveToNewSet({ urls }: { urls: string[] }) {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { pubkey, startLogin } = useNostr()
const { createRelaySet } = useFavoriteRelays()
const handleSave = () => {
if (!pubkey) {
startLogin()
return
}
const newSetName = prompt(t('Enter a name for the new relay set'))
if (newSetName) {
createRelaySet(newSetName, urls)
}
}
if (isSmallScreen) {
return (
{t('Save to a new relay set')}
)
}
return (
{t('Save to a new relay set')}
)
}
function BlockRelayItem({ urls }: { urls: string[] }) {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { blockedRelays, addBlockedRelays, deleteBlockedRelays } = useFavoriteRelays()
const [isLoading, setIsLoading] = useState(false)
const blocked = useMemo(
() => urls.every((url) => blockedRelays.includes(url)),
[blockedRelays, urls]
)
const handleClick = async () => {
if (isLoading) return
setIsLoading(true)
try {
if (blocked) {
await deleteBlockedRelays(urls)
} else {
await addBlockedRelays(urls)
}
} catch (error) {
console.error('Failed to toggle blocked relay:', error)
} finally {
setIsLoading(false)
}
}
if (isSmallScreen) {
return (
{isLoading ? : }
{isLoading ? t('Processing...') : blocked ? t('Unblock') : t('Block')}
)
}
return (
{isLoading ? : }
{isLoading ? t('Processing...') : blocked ? t('Unblock') : t('Block')}
)
}