Verify save token chips and preview counter

This commit is contained in:
2026-08-05 13:54:08 +00:00
parent 18de59fed1
commit d89335f1eb
3 changed files with 127 additions and 2 deletions
+44 -2
View File
@@ -15,6 +15,7 @@ const CHIPS = [
{ label: "+ Height", token: "%height%" },
{ label: "+ Batch #", token: "%batch_num%" },
];
const COUNTER_DIGITS = 3;
let cssDone = false;
@@ -127,11 +128,47 @@ function buildPreviewPath(node, ui) {
.replaceAll("%input2%", "input2")
.replaceAll("%width%", String(node._dsiImageWidth || 0))
.replaceAll("%height%", String(node._dsiImageHeight || 0))
.replaceAll("%batch_num%", "0")
.replaceAll("%counter%", "001");
.replaceAll("%batch_num%", "0");
if (
ui._dsiCounterResolved
&& ui._dsiCounterKey === `${folder}\u0000${pattern}${format}`
) {
return `${folder}/${ui._dsiCounterResolved}`.replaceAll("\\", "/");
}
pattern = pattern.replaceAll("%counter%", String(ui._dsiNextCounter || 1).padStart(COUNTER_DIGITS, "0"));
return `${folder}/${pattern}${format}`.replaceAll("\\", "/");
}
function scheduleCounterFetch(node, ui) {
const folder = (ui.folderInput.value || "").trim();
const format = ui.format === "jpg" ? ".jpg" : ".png";
let pattern = ui.patternInput.value || DEFAULT_PATTERN;
pattern = resolveDateTokens(pattern)
.replaceAll("%input%", "input")
.replaceAll("%input2%", "input2")
.replaceAll("%width%", String(node._dsiImageWidth || 0))
.replaceAll("%height%", String(node._dsiImageHeight || 0))
.replaceAll("%batch_num%", "0");
const key = `${folder}\u0000${pattern}${format}`;
if (ui._dsiCounterKey === key && ui._dsiCounterResolved) return;
clearTimeout(ui._dsiCounterTimer);
ui._dsiCounterTimer = setTimeout(async () => {
try {
const response = await fetch(
`/dumas/api/save_image/next_counter?folder=${encodeURIComponent(folder)}&name=${encodeURIComponent(pattern + format)}&digits=${COUNTER_DIGITS}`,
);
const data = await response.json();
if (!data?.ok) return;
ui._dsiNextCounter = data.counter || 1;
ui._dsiCounterResolved = data.resolved || "";
ui._dsiCounterKey = key;
ui.prevPath.textContent = buildPreviewPath(node, ui);
} catch (_error) {
// Leave the fallback preview in place.
}
}, 150);
}
function imageUrl(meta) {
return `/view?filename=${encodeURIComponent(meta.filename)}&type=${encodeURIComponent(meta.type)}&subfolder=${encodeURIComponent(meta.subfolder || "")}&t=${Date.now()}`;
}
@@ -175,6 +212,7 @@ function renderPreview(node, ui) {
const currentIndex = Math.max(0, Math.min(node._dsiImageIndex || 0, images.length - 1));
node._dsiImageIndex = currentIndex;
ui.prevPath.textContent = buildPreviewPath(node, ui);
scheduleCounterFetch(node, ui);
ui.folderButton.title = (ui.folderInput.value || "").trim()
? `Copy folder path: ${(ui.folderInput.value || "").trim()}`
: "Using ComfyUI output folder";
@@ -339,6 +377,10 @@ function createRoot(node) {
format: "png",
saveOnRun: true,
embedWorkflow: true,
_dsiNextCounter: 1,
_dsiCounterResolved: "",
_dsiCounterKey: "",
_dsiCounterTimer: null,
};
folderInput.addEventListener("input", () => {