Fix save image external folder feedback

This commit is contained in:
2026-08-05 11:47:14 +00:00
parent c691937933
commit f5ff914765
3 changed files with 52 additions and 19 deletions
+8
View File
@@ -365,6 +365,14 @@ class DumasSaveImageNode:
"type": "output",
}
)
else:
ui_images.append(
{
"filename": filename,
"subfolder": frame_dir.replace("\\", "/"),
"type": "external",
}
)
return {"ui": {"images": ui_images}}
+20 -13
View File
@@ -135,10 +135,16 @@ function imageUrl(meta) {
return `/view?filename=${encodeURIComponent(meta.filename)}&type=${encodeURIComponent(meta.type)}&subfolder=${encodeURIComponent(meta.subfolder || "")}&t=${Date.now()}`;
}
function canPreview(meta) {
return meta?.type === "output";
}
function updateActionState(node, ui) {
const hasImage = !!(node._dsiImages && node._dsiImages.length);
ui.openButton.disabled = !hasImage;
ui.copyButton.disabled = !hasImage;
const current = hasImage ? node._dsiImages[node._dsiImageIndex || 0] : null;
const previewable = canPreview(current);
ui.openButton.disabled = !previewable;
ui.copyButton.disabled = !previewable;
ui.prevButton.classList.toggle("show", !!(hasImage && node._dsiImages.length > 1));
ui.nextButton.classList.toggle("show", !!(hasImage && node._dsiImages.length > 1));
ui.count.style.display = hasImage && node._dsiImages.length > 1 ? "block" : "none";
@@ -176,14 +182,24 @@ function renderPreview(node, ui) {
}
const current = images[currentIndex];
ui.count.textContent = `${currentIndex + 1} / ${images.length}`;
if (canPreview(current)) {
ui.view.classList.add("has");
ui.placeholder.style.display = "none";
ui.img.style.display = "block";
ui.img.src = imageUrl(current);
ui.count.textContent = `${currentIndex + 1} / ${images.length}`;
ui.info.textContent = images.length > 1
? `Showing saved image ${currentIndex + 1} of ${images.length}`
: "Showing latest saved image";
} else {
ui.view.classList.remove("has");
ui.img.style.display = "none";
ui.placeholder.style.display = "flex";
ui.placeholder.textContent = "Saved outside ComfyUI output. Preview is unavailable here.";
ui.info.textContent = current?.subfolder
? `Saved to ${current.subfolder}/${current.filename}`
: `Saved to ${current.filename}`;
}
updateActionState(node, ui);
}
@@ -324,16 +340,7 @@ function createRoot(node) {
renderPreview(node, ui);
});
browseButton.addEventListener("click", async () => {
if (typeof window.showDirectoryPicker !== "function") return;
try {
const handle = await window.showDirectoryPicker();
if (!handle) return;
folderInput.value = handle.name || folderInput.value;
setWidgetValue(node, "folder", folderInput.value);
renderPreview(node, ui);
} catch (_error) {
// Ignore picker cancel/failure.
}
ui.info.textContent = "Browser folder picking cannot provide a real filesystem path here. Paste the full path into the folder field.";
});
fmtPng.addEventListener("click", () => {
ui.format = "png";
+18
View File
@@ -167,6 +167,24 @@ class DumasImageNodeTests(unittest.TestCase):
self.assertEqual(result["ui"]["images"][0]["type"], "output")
self.assertTrue(result["ui"]["images"][0]["filename"].endswith(".jpg"))
def test_save_image_returns_ui_entries_for_external_folder(self):
node = self.image_nodes.DumasSaveImageNode()
image = FakeTensorBatch()
external_dir = tempfile.mkdtemp(prefix="dumas-image-node-external-")
result = node.save_images(
images=image,
folder=external_dir,
pattern="external_%counter%",
format="png",
quality=100,
embed_workflow=False,
save_on_run=True,
)
self.assertEqual(result["ui"]["images"][0]["type"], "external")
self.assertEqual(result["ui"]["images"][0]["subfolder"], external_dir.replace("\\", "/"))
def test_save_image_skips_when_save_is_disabled(self):
node = self.image_nodes.DumasSaveImageNode()
image = FakeTensorBatch()