Load image batch improvements

- Uses filter list behavior for LiteGraph context menu
- "Replace" button
- Can select from combo widget on node directly
This commit is contained in:
space-nuko 2023-06-08 20:27:08 -05:00
parent d4e73878e2
commit ec8678c45a
2 changed files with 65 additions and 26 deletions

View File

@ -453,14 +453,20 @@ async function loadImageAsync(imageURL) {
}
const MULTIIMAGEUPLOAD = (node, inputName, inputData, app) => {
const imagesWidget = node.addWidget("text", inputName, inputData, () => {})
imagesWidget.disabled = true;
let filepaths = { input: [], output: [] }
imagesWidget._filepaths = {}
if (inputData[1] && inputData[1].filepaths) {
imagesWidget._filepaths = inputData[1].filepaths
filepaths = inputData[1].filepaths
}
const update = function(v) {
this.value = v
}
const imagesWidget = node.addWidget("combo", inputName, inputData, update, { values: filepaths["input"] })
imagesWidget._filepaths = filepaths
imagesWidget._entries = filepaths["input"]
async function showImages(names) {
node.imgs = []
@ -616,10 +622,11 @@ const MULTIIMAGEUPLOAD = (node, inputName, inputData, app) => {
<option value="output">Output</option>
<option value="input">Input</option>
</select>
<select class='image-path'></select>
<button class='image-path'><span class="image-path-text"></span></button>
</div>
<div class="bar">
<div class="bar actions">
<button class="add-image">Add</button>
<button class="replace-image">Replace</button>
</div>`;
const previewElem = document.createElement("div");
previewElem.innerHTML = previewHtml;
@ -628,46 +635,64 @@ const MULTIIMAGEUPLOAD = (node, inputName, inputData, app) => {
const folderTypeSel = previewElem.querySelector('.folder-type');
const imagePathSel = previewElem.querySelector('.image-path');
const imagePathText = previewElem.querySelector('.image-path-text');
const imagePreview = previewElem.querySelector('.image-preview');
imagePathSel.addEventListener("change", (event) => {
const filename = event.target.value;
const type = folderTypeSel.value;
imagePreview.src = `/view?filename=${filename}&type=${type}`
folderTypeSel.addEventListener("change", (event) => {
const filepaths = imagesWidget._filepaths[event.target.value];
imagesWidget._entries = filepaths
imagePathText.innerHTML = filepaths[0];
imagePreview.src = `/view?filename=${filepaths[0]}&type=${event.target.value}`
});
folderTypeSel.addEventListener("change", (event) => {
imagePathSel.innerHTML = "";
const filepaths = imagesWidget._filepaths[event.target.value];
if (filepaths == null)
return;
imagePathSel.addEventListener("click", (event) => {
const type = folderTypeSel.value;
const filepaths = imagesWidget._filepaths[folderTypeSel.value];
const entries = imagesWidget._entries
for (const filepath of filepaths) {
const filename = filepath.split('\\').pop().split('/').pop();
const opt = document.createElement('option');
opt.value = filepath
opt.innerHTML = filename
imagePathSel.appendChild(opt);
const innerClicked = (v, _options, e, prev) => {
const filename = v;
imagePathText.innerHTML = filename;
imagePreview.src = `/view?filename=${filename}&type=${type}`
}
imagePathSel.value = filepaths[0]
imagePathSel.dispatchEvent(new Event('change'));
new LiteGraph.ContextMenu(entries, {
event,
callback: innerClicked,
node,
className: "dark" // required for contextMenuFilter.js to kick in
});
});
folderTypeSel.value = "output";
folderTypeSel.value = "input";
folderTypeSel.dispatchEvent(new Event('change'));
const addButton = previewElem.querySelector('.add-image');
addButton.addEventListener("click", async (event) => {
const filename = imagePathSel.value;
const filename = imagePathText.innerHTML;
const type = folderTypeSel.value;
const value = `${filename} [${type}]`;
let value = filename;
if (type !== "input")
value += ` [${type}]`
imagesWidget._real_value.push(value)
imagesWidget.value = imagesWidget._real_value
await showImages(imagesWidget.value);
inner_refresh();
})
const replaceButton = previewElem.querySelector('.replace-image');
replaceButton.addEventListener("click", async (event) => {
const filename = imagePathText.innerHTML;
const type = folderTypeSel.value;
let value = filename;
if (type !== "input")
value += ` [${type}]`
imagesWidget._real_value = [value]
imagesWidget.value = imagesWidget._real_value
await showImages(imagesWidget.value);
inner_refresh();
})
imagesWidget.panel.footer.style.display = "flex";
const clearButton = imagesWidget.panel.addButton("Clear", () => {

View File

@ -381,6 +381,15 @@ button.comfy-queue-btn {
border-radius: 3px;
}
.litegraph .dialog.multiimageupload_dialog .image-path-text {
max-width: 250px;
overflow: hidden;
white-space: nowrap;
display: block;
text-overflow: ellipsis;
text-align: left;
}
.litegraph .dialog select {
margin-right: 20px;
padding-left: 4px;
@ -471,6 +480,7 @@ button.comfy-queue-btn {
}
.multiimageupload_dialog button {
height: 28px;
background-color: #1c1c1c;
color: #aaa;
border: 0;
@ -479,6 +489,10 @@ button.comfy-queue-btn {
cursor: pointer;
}
.multiimageupload_dialog .actions button {
margin-right: 10px;
}
.multiimageupload_dialog.extra {
color: #ccc;
}