diff --git a/src/components/BlossomUploadDialog.tsx b/src/components/BlossomUploadDialog.tsx index 7e1a32b..c15dc59 100644 --- a/src/components/BlossomUploadDialog.tsx +++ b/src/components/BlossomUploadDialog.tsx @@ -12,6 +12,7 @@ import { Archive, CheckCircle, XCircle, + Globe, } from "lucide-react"; import { Dialog, @@ -34,6 +35,16 @@ import { } from "@/services/blossom"; import type { Subscription } from "rxjs"; +/** + * Well-known public Blossom servers that can be used as fallbacks + * when the user doesn't have their own server list configured + */ +const FALLBACK_SERVERS = [ + "https://blossom.primal.net", + "https://nostr.download", + "https://files.v0l.io", +]; + interface BlossomUploadDialogProps { /** Whether the dialog is open */ open: boolean; @@ -75,6 +86,7 @@ export function BlossomUploadDialog({ new Set(), ); const [loadingServers, setLoadingServers] = useState(true); + const [usingFallback, setUsingFallback] = useState(false); const [uploading, setUploading] = useState(false); const [selectedFile, setSelectedFile] = useState(null); const [previewUrl, setPreviewUrl] = useState(null); @@ -93,26 +105,46 @@ export function BlossomUploadDialog({ setUploadResults([]); setUploadErrors([]); setUploading(false); + setUsingFallback(false); } }, [open]); + // Helper to set fallback servers + const useFallbackServers = useCallback(() => { + setServers(FALLBACK_SERVERS); + setSelectedServers(new Set([FALLBACK_SERVERS[0]])); // Select first by default + setUsingFallback(true); + setLoadingServers(false); + }, []); + // Fetch servers when dialog opens useEffect(() => { - if (!open || !pubkey) { + if (!open) { setLoadingServers(false); return; } + // If no pubkey (not logged in), use fallback servers + if (!pubkey) { + useFallbackServers(); + return; + } + setLoadingServers(true); + setUsingFallback(false); let subscription: Subscription | null = null; + let foundUserServers = false; // Check existing event first const event = eventStore.getReplaceable(USER_SERVER_LIST_KIND, pubkey, ""); if (event) { const s = getServersFromEvent(event); - setServers(s); - setSelectedServers(new Set(s)); // Select all by default - setLoadingServers(false); + if (s.length > 0) { + setServers(s); + setSelectedServers(new Set(s)); // Select all by default + setLoadingServers(false); + foundUserServers = true; + } } // Also fetch from network @@ -125,21 +157,31 @@ export function BlossomUploadDialog({ const e = eventStore.getReplaceable(USER_SERVER_LIST_KIND, pubkey, ""); if (e) { const s = getServersFromEvent(e); - setServers(s); - setSelectedServers((prev) => (prev.size === 0 ? new Set(s) : prev)); + if (s.length > 0) { + setServers(s); + setSelectedServers((prev) => (prev.size === 0 ? new Set(s) : prev)); + setUsingFallback(false); + foundUserServers = true; + } } setLoadingServers(false); }, error: () => setLoadingServers(false), }); - const timeout = setTimeout(() => setLoadingServers(false), 3000); + // After timeout, use fallbacks if no user servers found + const timeout = setTimeout(() => { + setLoadingServers(false); + if (!foundUserServers) { + useFallbackServers(); + } + }, 3000); return () => { subscription?.unsubscribe(); clearTimeout(timeout); }; - }, [open, pubkey, eventStore]); + }, [open, pubkey, eventStore, useFallbackServers]); // Create preview URL for selected file useEffect(() => { @@ -341,12 +383,20 @@ export function BlossomUploadDialog({
- ) : servers.length > 0 ? ( + ) : (
- - Servers ({selectedServers.size}/{servers.length}) - +
+ {usingFallback ? ( + + ) : ( + + )} + + {usingFallback ? "Public Servers" : "Your Servers"} ( + {selectedServers.size}/{servers.length}) + +
+ {usingFallback && ( +

+ No server list found. Using public servers. +

+ )}
{servers.map((server) => (
- ) : ( -
- -

- No Blossom servers configured -

-

- Publish a kind 10063 server list to use this feature -

-
)} {/* Upload Results */}