import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Separator } from '@/components/ui/separator' import { RECOMMENDED_BLOSSOM_SERVERS } from '@/constants' import { createBlossomServerListDraftEvent } from '@/lib/draft-event' import { getServersFromServerTags } from '@/lib/tag' import { normalizeHttpUrl } from '@/lib/url' import { cn } from '@/lib/utils' import { useNostr } from '@/providers/NostrProvider' import client from '@/services/client.service' import { AlertCircle, ArrowUpToLine, Loader, X } from 'lucide-react' import { Event } from 'nostr-tools' import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' export default function BlossomServerListSetting() { const { t } = useTranslation() const { pubkey, publish } = useNostr() const [blossomServerListEvent, setBlossomServerListEvent] = useState(null) const serverUrls = useMemo(() => { return getServersFromServerTags(blossomServerListEvent ? blossomServerListEvent.tags : []) }, [blossomServerListEvent]) const [url, setUrl] = useState('') const [removingIndex, setRemovingIndex] = useState(-1) const [movingIndex, setMovingIndex] = useState(-1) const [adding, setAdding] = useState(false) useEffect(() => { const init = async () => { if (!pubkey) { setBlossomServerListEvent(null) return } const event = await client.fetchBlossomServerListEvent(pubkey) setBlossomServerListEvent(event) } init() }, [pubkey]) const addBlossomUrl = async (url: string) => { if (!url || adding || removingIndex >= 0 || movingIndex >= 0) return setAdding(true) try { const draftEvent = createBlossomServerListDraftEvent([...serverUrls, url]) const newEvent = await publish(draftEvent) await client.updateBlossomServerListEventCache(newEvent) setBlossomServerListEvent(newEvent) setUrl('') } catch (error) { console.error('Failed to add Blossom URL:', error) } finally { setAdding(false) } } const handleUrlInputKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { event.preventDefault() const normalizedUrl = normalizeHttpUrl(url.trim()) if (!normalizedUrl) return addBlossomUrl(normalizedUrl) } } const removeBlossomUrl = async (idx: number) => { if (removingIndex >= 0 || adding || movingIndex >= 0) return setRemovingIndex(idx) try { const draftEvent = createBlossomServerListDraftEvent(serverUrls.filter((_, i) => i !== idx)) const newEvent = await publish(draftEvent) await client.updateBlossomServerListEventCache(newEvent) setBlossomServerListEvent(newEvent) } catch (error) { console.error('Failed to remove Blossom URL:', error) } finally { setRemovingIndex(-1) } } const moveToTop = async (idx: number) => { if (removingIndex >= 0 || adding || movingIndex >= 0 || idx === 0) return setMovingIndex(idx) try { const newUrls = [serverUrls[idx], ...serverUrls.filter((_, i) => i !== idx)] const draftEvent = createBlossomServerListDraftEvent(newUrls) const newEvent = await publish(draftEvent) await client.updateBlossomServerListEventCache(newEvent) setBlossomServerListEvent(newEvent) } catch (error) { console.error('Failed to move Blossom URL to top:', error) } finally { setMovingIndex(-1) } } return (
{t('Blossom server URLs')}
{serverUrls.length === 0 && (
{t('You need to add at least one media server in order to upload media files.')}
{t('Recommended blossom servers')}:
{RECOMMENDED_BLOSSOM_SERVERS.map((recommendedUrl) => ( ))}
)} {serverUrls.map((url, idx) => (
{url}
{idx > 0 ? ( ) : ( {t('Preferred')} )}
))}
setUrl(e.target.value)} placeholder={t('Enter Blossom server URL')} onKeyDown={handleUrlInputKeyDown} />
) }