mirror of
https://github.com/justUmen/Bjornulf_custom_nodes.git
synced 2026-03-21 12:42:11 -03:00
110 lines
4.6 KiB
JavaScript
110 lines
4.6 KiB
JavaScript
import { app } from "../../../scripts/app.js";
|
|
|
|
app.registerExtension({
|
|
name: "Bjornulf.AllLoraSelector",
|
|
async nodeCreated(node) {
|
|
if (node.comfyClass === "Bjornulf_AllLoraSelector") {
|
|
node.properties = node.properties || {};
|
|
|
|
const updateLoraInputs = () => {
|
|
const initialWidth = node.size[0];
|
|
const numLorasWidget = node.widgets.find(w => w.name === "number_of_loras");
|
|
if (!numLorasWidget) return;
|
|
|
|
const numLoras = numLorasWidget.value;
|
|
const loraList = node.widgets.find(w => w.name === "lora_1")?.options?.values || [];
|
|
|
|
// Save existing values
|
|
node.widgets.forEach(w => {
|
|
if (w.name.startsWith("lora_") || w.name.startsWith("strength_model_") || w.name.startsWith("strength_clip_")) {
|
|
node.properties[w.name] = w.value;
|
|
}
|
|
});
|
|
|
|
// Remove existing LoRA-related widgets
|
|
node.widgets = node.widgets.filter(w =>
|
|
!w.name.startsWith("lora_") &&
|
|
!w.name.startsWith("strength_model_") &&
|
|
!w.name.startsWith("strength_clip_")
|
|
);
|
|
|
|
// Add number_of_loras widget if it doesn't exist
|
|
const ensureWidget = (name, type, defaultValue, config) => {
|
|
let widget = node.widgets.find(w => w.name === name);
|
|
if (!widget) {
|
|
widget = node.addWidget(type, name,
|
|
node.properties[name] !== undefined ? node.properties[name] : defaultValue,
|
|
value => { node.properties[name] = value; },
|
|
config
|
|
);
|
|
}
|
|
};
|
|
|
|
ensureWidget("number_of_loras", "number", 3, { min: 1, max: 20, step: 1 });
|
|
|
|
// Add LoRA widgets for each slot
|
|
for (let i = 1; i <= numLoras; i++) {
|
|
const loraName = `lora_${i}`;
|
|
const strengthModelName = `strength_model_${i}`;
|
|
const strengthClipName = `strength_clip_${i}`;
|
|
|
|
// Add LoRA selector
|
|
node.addWidget("combo", loraName,
|
|
node.properties[loraName] || loraList[0],
|
|
value => { node.properties[loraName] = value; },
|
|
{ values: loraList }
|
|
);
|
|
|
|
// Add strength sliders
|
|
node.addWidget("number", strengthModelName,
|
|
node.properties[strengthModelName] !== undefined ? node.properties[strengthModelName] : 1.0,
|
|
value => { node.properties[strengthModelName] = value; },
|
|
{ min: -100.0, max: 100.0, step: 0.01 }
|
|
);
|
|
|
|
node.addWidget("number", strengthClipName,
|
|
node.properties[strengthClipName] !== undefined ? node.properties[strengthClipName] : 1.0,
|
|
value => { node.properties[strengthClipName] = value; },
|
|
{ min: -100.0, max: 100.0, step: 0.01 }
|
|
);
|
|
}
|
|
|
|
node.setSize(node.computeSize());
|
|
node.size[0] = Math.max(initialWidth, node.size[0]);
|
|
};
|
|
|
|
// Set up number_of_loras widget callback
|
|
const numLorasWidget = node.widgets.find(w => w.name === "number_of_loras");
|
|
if (numLorasWidget) {
|
|
numLorasWidget.callback = () => {
|
|
updateLoraInputs();
|
|
app.graph.setDirtyCanvas(true);
|
|
};
|
|
}
|
|
|
|
// Handle serialization
|
|
const originalOnSerialize = node.onSerialize;
|
|
node.onSerialize = function(info) {
|
|
if (originalOnSerialize) {
|
|
originalOnSerialize.call(this, info);
|
|
}
|
|
info.properties = { ...this.properties };
|
|
};
|
|
|
|
// Handle deserialization
|
|
const originalOnConfigure = node.onConfigure;
|
|
node.onConfigure = function(info) {
|
|
if (originalOnConfigure) {
|
|
originalOnConfigure.call(this, info);
|
|
}
|
|
if (info.properties) {
|
|
Object.assign(this.properties, info.properties);
|
|
}
|
|
updateLoraInputs();
|
|
};
|
|
|
|
// Initial setup
|
|
updateLoraInputs();
|
|
}
|
|
}
|
|
}); |