Files
SatadalAI-SATA_UtilityNode/web/resolution_machine.js
T
2025-09-18 09:34:20 +05:30

123 lines
3.8 KiB
JavaScript

// resolution_machine.js
import { app } from "../../../scripts/app.js";
async function fetchConfig() {
try {
const resp = await fetch("/sata/resolution_machine/config");
if (!resp.ok) {
console.warn("ResolutionMachine: fetch failed", resp.status);
return null;
}
return await resp.json();
} catch (e) {
console.warn("ResolutionMachine: fetch exception", e);
return null;
}
}
app.registerExtension({
name: "SATA_UtilityNode.ResolutionMachine",
async nodeCreated(node) {
if (node.comfyClass !== "Resolution_Machine") return;
const cfg = await fetchConfig();
if (!cfg) return;
// find widgets
let modelW = node.widgets.find(w => w.name === "model");
let resW = node.widgets.find(w => w.name === "resolution");
let wW = node.widgets.find(w => w.name === "width");
let hW = node.widgets.find(w => w.name === "height");
if (!modelW || !resW || !wW || !hW) {
console.warn("ResolutionMachine: widgets missing, check INPUT_TYPES");
return;
}
// --- rebuild widgets as dropdowns to force combo type ---
const idxModel = node.widgets.indexOf(modelW);
node.widgets.splice(idxModel, 1);
modelW = node.addWidget("combo", "model", "None", () => {}, {
values: cfg.models.map(m => m.model)
});
const idxRes = node.widgets.indexOf(resW);
node.widgets.splice(idxRes, 1);
resW = node.addWidget("combo", "resolution", "Custom (manual)", () => {}, {
values: ["Custom (manual)"]
});
// helper lookups
function getResNamesForModel(modelName) {
const m = cfg.models.find(x => x.model === modelName);
if (!m) return ["Custom (manual)"];
const names = m.resolutions.map(r => r.name);
if (!names.includes("Custom (manual)")) names.push("Custom (manual)");
return names;
}
function findResObj(modelName, resName) {
const m = cfg.models.find(x => x.model === modelName);
if (!m) return null;
return m.resolutions.find(r => r.name === resName) || null;
}
let suppressWH = false;
function programmaticSetWH(wVal, hVal) {
suppressWH = true;
wW.value = wVal;
hW.value = hVal;
if (wW.inputEl) wW.inputEl.value = wVal;
if (hW.inputEl) hW.inputEl.value = hVal;
setTimeout(() => { suppressWH = false; }, 0);
}
// model handler
modelW.callback = (newModel) => {
const names = getResNamesForModel(newModel);
resW.options.values = names;
if (!names.includes(resW.value)) {
resW.value = names[0];
}
resW.callback(resW.value); // trigger res change
node.graph?.setDirtyCanvas(true);
};
// resolution handler
resW.callback = (newRes) => {
const modelName = modelW.value;
const resObj = findResObj(modelName, newRes);
if (resObj && newRes !== "Custom (manual)") {
programmaticSetWH(resObj.width, resObj.height);
if (wW.inputEl) wW.inputEl.disabled = true;
if (hW.inputEl) hW.inputEl.disabled = true;
} else {
if (wW.inputEl) wW.inputEl.disabled = false;
if (hW.inputEl) hW.inputEl.disabled = false;
}
node.graph?.setDirtyCanvas(true);
};
// manual WH handler
function onManualWH() {
if (suppressWH) return;
if (resW.value !== "Custom (manual)") {
const names = getResNamesForModel(modelW.value);
if (!names.includes("Custom (manual)")) {
names.push("Custom (manual)");
resW.options.values = names;
}
resW.value = "Custom (manual)";
resW.callback("Custom (manual)");
}
}
wW.callback = onManualWH;
hW.callback = onManualWH;
// --- initialize ---
const firstModel = cfg.models[0]?.model;
if (firstModel) {
modelW.value = firstModel;
modelW.callback(firstModel);
}
}
});