diff --git a/src/components/BlossomUploadDialog.tsx b/src/components/BlossomUploadDialog.tsx index c28ef9e..4d6401e 100644 --- a/src/components/BlossomUploadDialog.tsx +++ b/src/components/BlossomUploadDialog.tsx @@ -57,6 +57,8 @@ interface BlossomUploadDialogProps { onError?: (error: Error) => void; /** File types to accept (e.g., "image/*,video/*,audio/*") */ accept?: string; + /** Additional blossom servers from communikey (NIP-CC) */ + communikeyServers?: string[]; } /** @@ -75,6 +77,7 @@ export function BlossomUploadDialog({ onCancel, onError, accept = "image/*,video/*,audio/*", + communikeyServers = [], }: BlossomUploadDialogProps) { const eventStore = useEventStore(); const activeAccount = use$(accountManager.active$); @@ -134,18 +137,34 @@ export function BlossomUploadDialog({ let subscription: Subscription | null = null; let foundUserServers = false; + // Helper to merge user servers with communikey servers + const mergeServers = (userServers: string[]) => { + // Combine user servers + communikey servers, removing duplicates + const allServers = [...new Set([...userServers, ...communikeyServers])]; + return allServers; + }; + // Check existing event first const event = eventStore.getReplaceable(USER_SERVER_LIST_KIND, pubkey, ""); if (event) { - const s = getServersFromEvent(event); - if (s.length > 0) { - setServers(s); - setSelectedServers(new Set(s)); // Select all by default + const userServers = getServersFromEvent(event); + if (userServers.length > 0) { + const allServers = mergeServers(userServers); + setServers(allServers); + setSelectedServers(new Set(allServers)); // Select all by default setLoadingServers(false); foundUserServers = true; } } + // If we have communikey servers but no user servers yet, use them + if (!foundUserServers && communikeyServers.length > 0) { + setServers(communikeyServers); + setSelectedServers(new Set(communikeyServers)); + setLoadingServers(false); + setUsingFallback(false); + } + // Also fetch from network subscription = addressLoader({ kind: USER_SERVER_LIST_KIND, @@ -155,10 +174,13 @@ export function BlossomUploadDialog({ next: () => { const e = eventStore.getReplaceable(USER_SERVER_LIST_KIND, pubkey, ""); if (e) { - const s = getServersFromEvent(e); - if (s.length > 0) { - setServers(s); - setSelectedServers((prev) => (prev.size === 0 ? new Set(s) : prev)); + const userServers = getServersFromEvent(e); + if (userServers.length > 0) { + const allServers = mergeServers(userServers); + setServers(allServers); + setSelectedServers((prev) => + prev.size === 0 ? new Set(allServers) : prev, + ); setUsingFallback(false); foundUserServers = true; } @@ -171,7 +193,7 @@ export function BlossomUploadDialog({ // After timeout, use fallbacks if no user servers found const timeout = setTimeout(() => { setLoadingServers(false); - if (!foundUserServers) { + if (!foundUserServers && communikeyServers.length === 0) { applyFallbackServers(); } }, 3000); @@ -180,7 +202,7 @@ export function BlossomUploadDialog({ subscription?.unsubscribe(); clearTimeout(timeout); }; - }, [open, pubkey, eventStore, applyFallbackServers]); + }, [open, pubkey, eventStore, applyFallbackServers, communikeyServers]); // Create preview URL for selected file useEffect(() => { diff --git a/src/components/ChatViewer.tsx b/src/components/ChatViewer.tsx index ae492f6..6452d7e 100644 --- a/src/components/ChatViewer.tsx +++ b/src/components/ChatViewer.tsx @@ -446,9 +446,24 @@ export function ChatViewer({ // Ref to MentionEditor for programmatic submission const editorRef = useRef(null); + // Extract communikey blossom servers if available + const communikeyServers = useMemo(() => { + if ( + conversationResult.status === "success" && + conversationResult.conversation.protocol === "communikeys" + ) { + return ( + conversationResult.conversation.metadata?.communikeyConfig + ?.blossomServers || [] + ); + } + return []; + }, [conversationResult]); + // Blossom upload hook for file attachments const { open: openUpload, dialog: uploadDialog } = useBlossomUpload({ accept: "image/*,video/*,audio/*", + communikeyServers, onSuccess: (results) => { if (results.length > 0 && editorRef.current) { // Insert the first successful upload as a blob attachment with metadata diff --git a/src/hooks/useBlossomUpload.tsx b/src/hooks/useBlossomUpload.tsx index aee53a5..effc7e7 100644 --- a/src/hooks/useBlossomUpload.tsx +++ b/src/hooks/useBlossomUpload.tsx @@ -11,6 +11,8 @@ export interface UseBlossomUploadOptions { onError?: (error: Error) => void; /** File types to accept (e.g., "image/*,video/*,audio/*") */ accept?: string; + /** Additional blossom servers from communikey (NIP-CC) */ + communikeyServers?: string[]; } export interface UseBlossomUploadReturn { @@ -84,9 +86,17 @@ export function useBlossomUpload( onCancel={handleCancel} onError={handleError} accept={options.accept} + communikeyServers={options.communikeyServers} /> ), - [isOpen, handleSuccess, handleCancel, handleError, options.accept], + [ + isOpen, + handleSuccess, + handleCancel, + handleError, + options.accept, + options.communikeyServers, + ], ); return { open, close, isOpen, dialog };