Files
2024-07-28 15:56:45 +08:00

148 lines
4.0 KiB
JavaScript

import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
// Load Image With Subfolder
app.registerExtension({
name: "LoadImageWithSubfolder",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name === "LoadImageWithSubfolder") {
if (nodeData?.input?.required?.image?.[1]?.image_upload === true) {
nodeData.input.required.upload = ["IMAGELOADER"];
}
}
},
async getCustomWidgets(app) {
return {
IMAGELOADER(node, inputName, inputData, app) {
const subfolderWidget = node.widgets.find((w) => w.name === (inputData[1]?.widget ?? "subfolder"));
const imageWidget = node.widgets.find((w) => w.name === (inputData[1]?.widget ?? "image"));
let uploadWidget;
function showImage(name) {
const img = new Image();
img.onload = () => {
node.imgs = [img];
app.graph.setDirtyCanvas(true);
};
if (name) {
let subfolder = subfolderWidget.value ?? "";
img.src = api.apiURL(`/view?filename=${encodeURIComponent(name)}&type=input&subfolder=${subfolder}${app.getPreviewFormatParam()}${app.getRandParam()}`);
node.setSizeForImage?.();
}
else {
node.imgs = [];
app.graph.setDirtyCanvas(true);
}
}
async function getImages(subfolder) {
const resp = await api.fetchApi("/images_in_directory", {
method: "POST",
body: JSON.stringify({
filetype: "input",
subfolder: subfolder
})
});
if (resp.status === 200) {
const data = await resp.json();
imageWidget.options.values = []
for (const name of data.images) {
imageWidget.options.values.push(name);
}
if (imageWidget.options.values.length > 0) {
imageWidget.value = imageWidget.options.values[0];
}
else {
imageWidget.value = undefined;
}
showImage(imageWidget.value);
}
}
getImages(subfolderWidget.value ?? "");
const cb = node.callback;
imageWidget.callback = function () {
showImage(imageWidget.value);
if (cb) {
return cb.apply(this, arguments);
}
};
subfolderWidget.callback = function () {
getImages(subfolderWidget.value ?? "")
if (cb) {
return cb.apply(this, arguments);
}
}
// On load if we have a value then render the image
// The value isnt set immediately so we need to wait a moment
// No change callbacks seem to be fired on initial setting of the value
requestAnimationFrame(() => {
if (imageWidget.value) {
showImage(imageWidget.value);
}
});
async function uploadFile(file, updateNode) {
try {
// Wrap file in formdata so it includes filename
const body = new FormData();
body.append("image", file);
if (subfolderWidget.value) body.append("subfolder", subfolderWidget.value);
const resp = await api.fetchApi("/upload/image", {
method: "POST",
body,
});
if (resp.status === 200) {
const data = await resp.json();
// Add the file to the dropdown list and update the widget value
let path = data.name;
if (!imageWidget.options.values.includes(path)) {
imageWidget.options.values.push(path);
}
if (updateNode) {
showImage(path);
imageWidget.value = path;
}
} else {
alert(resp.status + " - " + resp.statusText);
}
} catch (error) {
alert(error);
}
}
const fileInput = document.createElement("input");
Object.assign(fileInput, {
type: "file",
accept: "image/jpeg,image/png,image/webp",
style: "display: none",
onchange: async () => {
if (fileInput.files.length) {
await uploadFile(fileInput.files[0], true);
}
},
});
document.body.append(fileInput);
// Create the button widget for selecting the files
uploadWidget = node.addWidget("button", inputName, "image", () => {
fileInput.click();
});
uploadWidget.label = "choose file to upload";
uploadWidget.serialize = false;
return { widget: uploadWidget };
}
}
},
});