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')} ) }