diff --git a/README.md b/README.md index d479d0e..ed8e2ea 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,8 @@ Inputs: `Text (Multiline)` node; each non-empty line keeps an exact displayed name or full relative LoRA path - each bank has a LoRA dropdown plus separate model and CLIP strengths; a bank - is bypassed when both strengths are zero + is bypassed when both strengths are zero; changing `banks` adds or removes + complete bank controls while retaining their values during the session Outputs: @@ -189,7 +190,8 @@ Outputs: The node uses ComfyUI's normal combo refresh behavior. Press `R` on the canvas or use **Refresh Node Definitions** to re-enumerate LoRAs and folders, then reapply the folder and allow-list filters. Saved selections are preserved when -still valid and otherwise move to the first visible option. +still valid and otherwise move to the first visible option. Refreshes do not +resize the node; only changing the number of visible banks adjusts its height. The earlier standard and model-only Enviral LoRA loaders remain registered for existing workflows but are deprecated and hidden from normal node discovery. diff --git a/pyproject.toml b/pyproject.toml index d7eea19..7d07b48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "enviral-design-node-pack" -version = "0.1.28" +version = "0.1.29" description = "Small, dependency-light ComfyUI utility nodes from Enviral Design." readme = "README.md" requires-python = ">=3.10" diff --git a/web/filtered_lora_loader.js b/web/filtered_lora_loader.js index b7e6114..7109ac1 100644 --- a/web/filtered_lora_loader.js +++ b/web/filtered_lora_loader.js @@ -160,23 +160,43 @@ function configureLoraFilter(node, folderWidget, loraWidget) { return syncSelection; } -function updateBankVisibility(node) { - const bankCount = getBankCount(node); +function configureBankWidgets(node) { + const widgetsByBank = new Map(); for (let bankIndex = 2; bankIndex <= MAX_BANKS; bankIndex += 1) { - const hidden = bankIndex > bankCount; - for (const name of BANK_WIDGET_NAMES) { - const widget = getWidget(node, getBankWidgetName(name, bankIndex)); - if (widget) { - widget.hidden = hidden; - } - } + widgetsByBank.set( + bankIndex, + BANK_WIDGET_NAMES.map((name) => + getWidget(node, getBankWidgetName(name, bankIndex)), + ).filter(Boolean), + ); } + const bankWidgets = new Set([...widgetsByBank.values()].flat()); + const firstBankEnd = getWidget(node, "strength_clip"); + let visibleBankCount = null; - const size = node.computeSize?.(); - if (size) { - node.setSize?.(size); - } - node.setDirtyCanvas?.(true, true); + return function updateBankWidgets() { + const bankCount = getBankCount(node); + if (bankCount === visibleBankCount) { + return; + } + + const visibleWidgets = []; + for (let bankIndex = 2; bankIndex <= bankCount; bankIndex += 1) { + visibleWidgets.push(...widgetsByBank.get(bankIndex)); + } + const baseWidgets = node.widgets.filter((widget) => !bankWidgets.has(widget)); + const insertAt = Math.max(0, baseWidgets.indexOf(firstBankEnd) + 1); + baseWidgets.splice(insertAt, 0, ...visibleWidgets); + node.widgets.splice(0, node.widgets.length, ...baseWidgets); + visibleBankCount = bankCount; + + const width = node.size?.[0]; + const naturalSize = node.computeSize?.(); + if (naturalSize) { + node.setSize?.([width ?? naturalSize[0], naturalSize[1]]); + } + node.setDirtyCanvas?.(true, true); + }; } function configureFilter(node) { @@ -185,12 +205,14 @@ function configureFilter(node) { return; } + const loraWidgets = []; const syncSelections = []; for (let bankIndex = 1; bankIndex <= MAX_BANKS; bankIndex += 1) { const loraWidget = getWidget(node, getBankWidgetName("lora_name", bankIndex)); if (!loraWidget) { continue; } + loraWidgets.push(loraWidget); const syncSelection = configureLoraFilter(node, folderWidget, loraWidget); if (syncSelection) { syncSelections.push(syncSelection); @@ -199,6 +221,7 @@ function configureFilter(node) { if (syncSelections.length === 0) { return; } + const updateBankWidgets = configureBankWidgets(node); function sync() { const { sourceWidget } = getConnectedAllowList(node); @@ -224,7 +247,7 @@ function configureFilter(node) { for (const syncSelection of syncSelections) { syncSelection(); } - updateBankVisibility(node); + updateBankWidgets(); } const bankCountWidget = getWidget(node, "bank_count"); @@ -273,11 +296,8 @@ function configureFilter(node) { } } if (loras) { - for (let bankIndex = 1; bankIndex <= MAX_BANKS; bankIndex += 1) { - const loraWidget = getWidget(this, getBankWidgetName("lora_name", bankIndex)); - if (loraWidget) { - loraWidget.options.values = loras; - } + for (const loraWidget of loraWidgets) { + loraWidget.options.values = loras; } } this.enviralSyncLoraFilter?.(); @@ -285,7 +305,7 @@ function configureFilter(node) { }; node.enviralSyncLoraFilter = sync; - sync(); + queueMicrotask(sync); } app.registerExtension({