import { app } from "/scripts/app.js"; // Widget hide/show via type-mangling (standard ComfyUI pattern) const HIDDEN_TAG = "loraopt_hidden"; const origProps = {}; function toggleWidget(node, widget, show) { if (!widget) return; if (!origProps[widget.name]) { origProps[widget.name] = { origType: widget.type, origComputeSize: widget.computeSize, }; } widget.type = show ? origProps[widget.name].origType : HIDDEN_TAG; widget.computeSize = show ? origProps[widget.name].origComputeSize : () => [0, -4]; if (widget.linkedWidgets) { for (const w of widget.linkedWidgets) { toggleWidget(node, w, show); } } } function findWidget(node, name) { return node.widgets ? node.widgets.find((w) => w.name === name) : null; } function updateVisibility(node) { const modeWidget = findWidget(node, "mode"); const countWidget = findWidget(node, "lora_count"); if (!modeWidget || !countWidget) return; const isSimple = modeWidget.value === "simple"; const count = countWidget.value; const MAX = 10; for (let i = 1; i <= MAX; i++) { const visible = i <= count; toggleWidget(node, findWidget(node, `lora_name_${i}`), visible); toggleWidget(node, findWidget(node, `strength_${i}`), visible && isSimple); toggleWidget(node, findWidget(node, `model_strength_${i}`), visible && !isSimple); toggleWidget(node, findWidget(node, `clip_strength_${i}`), visible && !isSimple); } const newHeight = node.computeSize()[1]; node.setSize([node.size[0], newHeight]); } app.registerExtension({ name: "LoRAOptimizer.LoRAStackDynamic", nodeCreated(node) { if (node.comfyClass !== "LoRAStackDynamic") return; // Intercept mode and lora_count changes to update visibility for (const w of node.widgets || []) { if (w.name !== "mode" && w.name !== "lora_count") continue; let widgetValue = w.value; const originalDescriptor = Object.getOwnPropertyDescriptor(w, "value") || Object.getOwnPropertyDescriptor( Object.getPrototypeOf(w), "value" ); Object.defineProperty(w, "value", { get() { return originalDescriptor?.get ? originalDescriptor.get.call(w) : widgetValue; }, set(newVal) { if (originalDescriptor?.set) { originalDescriptor.set.call(w, newVal); } else { widgetValue = newVal; } updateVisibility(node); }, }); } // Initial visibility update (after a tick so widgets are fully initialized) requestAnimationFrame(() => updateVisibility(node)); }, });