132 lines
6.9 KiB
JavaScript
132 lines
6.9 KiB
JavaScript
import { ImageEditor } from "./editor.js";
|
|
import { IMAGE_EDITOR_SUBFOLDER } from "./constants.js";
|
|
import {
|
|
parseImageWidgetValue,
|
|
extractFilenameFromSrc,
|
|
buildEditorFilename,
|
|
buildImageReference,
|
|
updateWidgetWithRef,
|
|
createImageURLFromRef,
|
|
setImageSource,
|
|
refreshComboLists,
|
|
} from "./reference.js";
|
|
|
|
export function registerImageEditorExtension(app, api) {
|
|
app.registerExtension({
|
|
name: "SDVN.ImageEditor",
|
|
async beforeRegisterNodeDef(nodeType) {
|
|
const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;
|
|
nodeType.prototype.getExtraMenuOptions = function (_, options) {
|
|
if (this.imgs && this.imgs.length > 0) {
|
|
options.push({
|
|
content: "🎨 Image Editor",
|
|
callback: () => {
|
|
const img = this.imgs[this.imgs.length - 1];
|
|
let src = null;
|
|
if (img && img.src) src = img.src;
|
|
else if (img && img.image) src = img.image.src;
|
|
|
|
if (src) {
|
|
new ImageEditor(src, async (blob) => {
|
|
const formData = new FormData();
|
|
const inferredName = extractFilenameFromSrc(src);
|
|
const editorName = buildEditorFilename(inferredName);
|
|
formData.append("image", blob, editorName);
|
|
formData.append("overwrite", "false");
|
|
formData.append("type", "input");
|
|
formData.append("subfolder", IMAGE_EDITOR_SUBFOLDER);
|
|
|
|
try {
|
|
const resp = await api.fetchApi("/upload/image", {
|
|
method: "POST",
|
|
body: formData,
|
|
});
|
|
const data = await resp.json();
|
|
const ref = buildImageReference(data, {
|
|
type: "input",
|
|
subfolder: IMAGE_EDITOR_SUBFOLDER,
|
|
filename: editorName,
|
|
});
|
|
const imageWidget = this.widgets?.find?.(
|
|
(w) => w.name === "image" || w.type === "image"
|
|
);
|
|
if (imageWidget) {
|
|
updateWidgetWithRef(this, imageWidget, ref);
|
|
}
|
|
const newSrc = createImageURLFromRef(api, ref);
|
|
if (newSrc) {
|
|
setImageSource(img, newSrc);
|
|
app.graph.setDirtyCanvas(true);
|
|
}
|
|
await refreshComboLists(app);
|
|
console.info("[SDVN.ImageEditor] Image saved to input folder:", data?.name || editorName);
|
|
} catch (e) {
|
|
console.error("[SDVN.ImageEditor] Upload failed", e);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
});
|
|
} else if (this.widgets) {
|
|
const imageWidget = this.widgets.find((w) => w.name === "image" || w.type === "image");
|
|
if (imageWidget && imageWidget.value) {
|
|
options.push({
|
|
content: "🎨 Image Editor",
|
|
callback: () => {
|
|
const parsed = parseImageWidgetValue(imageWidget.value);
|
|
if (!parsed.filename) {
|
|
console.warn("[SDVN.ImageEditor] Image not available for editing.");
|
|
return;
|
|
}
|
|
const src = api.apiURL(
|
|
`/view?filename=${encodeURIComponent(parsed.filename)}&type=${parsed.type}&subfolder=${encodeURIComponent(
|
|
parsed.subfolder
|
|
)}`
|
|
);
|
|
|
|
new ImageEditor(src, async (blob) => {
|
|
const formData = new FormData();
|
|
const newName = buildEditorFilename(parsed.filename);
|
|
formData.append("image", blob, newName);
|
|
formData.append("overwrite", "false");
|
|
formData.append("type", "input");
|
|
formData.append("subfolder", IMAGE_EDITOR_SUBFOLDER);
|
|
|
|
try {
|
|
const resp = await api.fetchApi("/upload/image", {
|
|
method: "POST",
|
|
body: formData,
|
|
});
|
|
const data = await resp.json();
|
|
const ref = buildImageReference(data, {
|
|
type: "input",
|
|
subfolder: IMAGE_EDITOR_SUBFOLDER,
|
|
filename: newName,
|
|
});
|
|
|
|
if (imageWidget) {
|
|
updateWidgetWithRef(this, imageWidget, ref);
|
|
}
|
|
|
|
const newSrc = createImageURLFromRef(api, ref);
|
|
|
|
if (this.imgs && this.imgs.length > 0) {
|
|
this.imgs.forEach((img) => setImageSource(img, newSrc));
|
|
}
|
|
|
|
this.setDirtyCanvas?.(true, true);
|
|
app.graph.setDirtyCanvas(true, true);
|
|
await refreshComboLists(app);
|
|
} catch (e) {
|
|
console.error("[SDVN.ImageEditor] Upload failed", e);
|
|
}
|
|
});
|
|
},
|
|
});
|
|
}
|
|
}
|
|
return getExtraMenuOptions?.apply(this, arguments);
|
|
};
|
|
},
|
|
});
|
|
}
|