From cd7209efe5b7780d07142c5208a84fe9d9864145 Mon Sep 17 00:00:00 2001 From: shrimbly Date: Sun, 5 Apr 2026 19:20:25 +1200 Subject: [PATCH] fix: outputGallery video handle mismatch and mediaStorage ref/data sync - Add "video" to outputGallery inputs in getNodeHandles() to match the component's rendered handles and isValidConnection logic - Guard against undefined images/videos arrays in dehydration - Keep imageRefs/videoRefs in sync when filtering empty entries after hydration, preventing index misalignment Co-Authored-By: Claude Sonnet 4.5 --- src/components/WorkflowCanvas.tsx | 2 +- src/utils/mediaStorage.ts | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/components/WorkflowCanvas.tsx b/src/components/WorkflowCanvas.tsx index 1eaa2b87..1c7ac359 100644 --- a/src/components/WorkflowCanvas.tsx +++ b/src/components/WorkflowCanvas.tsx @@ -168,7 +168,7 @@ const getNodeHandles = (nodeType: string): { inputs: string[]; outputs: string[] case "output": return { inputs: ["image", "video", "audio"], outputs: [] }; case "outputGallery": - return { inputs: ["image"], outputs: [] }; + return { inputs: ["image", "video"], outputs: [] }; case "imageCompare": return { inputs: ["image"], outputs: [] }; case "videoStitch": diff --git a/src/utils/mediaStorage.ts b/src/utils/mediaStorage.ts index 585417d0..27909e46 100644 --- a/src/utils/mediaStorage.ts +++ b/src/utils/mediaStorage.ts @@ -469,10 +469,10 @@ async function externalizeNodeMedia( } // Build cleaned arrays: clear base64 data where refs exist, keep HTTP URLs - const cleanedImages = d.images.map((img, i) => + const cleanedImages = (d.images || []).map((img, i) => galleryImageRefs[i] && isDataUrl(img) ? "" : img ); - const cleanedVideos = d.videos.map((vid, i) => + const cleanedVideos = (d.videos || []).map((vid, i) => galleryVideoRefs[i] && isDataUrl(vid) ? "" : vid ); @@ -1062,11 +1062,31 @@ async function hydrateNodeMedia( } } - // Filter out any empty entries that failed to hydrate + // Filter out any empty entries that failed to hydrate, keeping refs in sync + const filteredImages: string[] = []; + const filteredImageRefs: string[] = []; + for (let i = 0; i < images.length; i++) { + if (images[i] && images[i] !== "") { + filteredImages.push(images[i]); + if (d.imageRefs?.[i]) filteredImageRefs.push(d.imageRefs[i]); + else filteredImageRefs.push(""); + } + } + const filteredVideos: string[] = []; + const filteredVideoRefs: string[] = []; + for (let i = 0; i < videos.length; i++) { + if (videos[i] && videos[i] !== "") { + filteredVideos.push(videos[i]); + if (d.videoRefs?.[i]) filteredVideoRefs.push(d.videoRefs[i]); + else filteredVideoRefs.push(""); + } + } newData = { ...d, - images: images.filter(img => img && img !== ""), - videos: videos.filter(vid => vid && vid !== ""), + images: filteredImages, + imageRefs: filteredImageRefs.some(r => r !== "") ? filteredImageRefs : d.imageRefs, + videos: filteredVideos, + videoRefs: filteredVideoRefs.some(r => r !== "") ? filteredVideoRefs : d.videoRefs, }; break; }