diff --git a/py/better_combos.py b/py/better_combos.py index 99e3e01..6326124 100644 --- a/py/better_combos.py +++ b/py/better_combos.py @@ -66,13 +66,13 @@ async def get_examples(request): file_path_no_ext = os.path.splitext(file_path)[0] examples = [] - - if os.path.isfile(file_path_no_ext + ".txt"): - examples += ["notes"] if os.path.isdir(file_path_no_ext): examples += sorted(map(lambda t: os.path.relpath(t, file_path_no_ext), glob.glob(file_path_no_ext + "/*.txt"))) + + if os.path.isfile(file_path_no_ext + ".txt"): + examples += ["notes"] return web.json_response(examples) @@ -95,11 +95,9 @@ async def save_example(request): example_name += ".txt" file_path_no_ext = os.path.splitext(file_path)[0] - file_name = os.path.split(file_path_no_ext)[1] - example_path = os.path.join(file_path_no_ext, file_name) - example_file = os.path.join(example_path, example_name) - if not os.path.exists(example_path): - os.mkdir(example_path) + example_file = os.path.join(file_path_no_ext, example_name) + if not os.path.exists(file_path_no_ext): + os.mkdir(file_path_no_ext) with open(example_file, 'w', encoding='utf8') as f: f.write(example) @@ -132,16 +130,14 @@ def populate_items(names, type): class LoraLoaderWithImages(LoraLoader): - RETURN_TYPES = ("MODEL", "CLIP", "STRING") + RETURN_TYPES = (*LoraLoader.RETURN_TYPES, "STRING",) @classmethod def INPUT_TYPES(s): types = super().INPUT_TYPES() names = types["required"]["lora_name"][0] populate_items(names, "loras") - types["optional"] = { "prompt": ("HIDDEN",) } - return types @classmethod @@ -162,11 +158,14 @@ class LoraLoaderWithImages(LoraLoader): class CheckpointLoaderSimpleWithImages(CheckpointLoaderSimple): + RETURN_TYPES = (*CheckpointLoaderSimple.RETURN_TYPES, "STRING",) + @classmethod def INPUT_TYPES(s): types = super().INPUT_TYPES() names = types["required"]["ckpt_name"][0] populate_items(names, "checkpoints") + types["optional"] = { "prompt": ("HIDDEN",) } return types @classmethod @@ -182,7 +181,8 @@ class CheckpointLoaderSimpleWithImages(CheckpointLoaderSimple): def load_checkpoint(self, **kwargs): kwargs["ckpt_name"] = kwargs["ckpt_name"]["content"] - return super().load_checkpoint(**kwargs) + prompt = kwargs.pop("prompt", "") + return (*super().load_checkpoint(**kwargs), prompt) NODE_CLASS_MAPPINGS = { diff --git a/web/js/betterCombos.js b/web/js/betterCombos.js index dd0689f..267f354 100644 --- a/web/js/betterCombos.js +++ b/web/js/betterCombos.js @@ -268,6 +268,7 @@ app.registerExtension({ return exampleCb?.apply(this, arguments) ?? exampleList.value; }; + const listExamples = async () => { exampleList.disabled = true; exampleList.options.values = ["[none]"]; @@ -285,6 +286,9 @@ app.registerExtension({ app.graph.setDirtyCanvas(true, true); }; + // Expose function to update examples + nodeType.prototype["pysssss.updateExamples"] = listExamples; + const modelWidget = this.widgets[0]; const modelCb = modelWidget.callback; let prev = undefined; @@ -305,14 +309,12 @@ app.registerExtension({ }, 30); }; - if (isLora) { - // Prevent adding HIDDEN inputs - const addInput = nodeType.prototype.addInput ?? LGraphNode.prototype.addInput; - nodeType.prototype.addInput = function (_, type) { - if (type === "HIDDEN") return; - return addInput.apply(this, arguments); - }; - } + // Prevent adding HIDDEN inputs + const addInput = nodeType.prototype.addInput ?? LGraphNode.prototype.addInput; + nodeType.prototype.addInput = function (_, type) { + if (type === "HIDDEN") return; + return addInput.apply(this, arguments); + }; } const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions; diff --git a/web/js/common/modelInfoDialog.js b/web/js/common/modelInfoDialog.js index 8655867..1722273 100644 --- a/web/js/common/modelInfoDialog.js +++ b/web/js/common/modelInfoDialog.js @@ -23,9 +23,10 @@ class MetadataDialog extends ComfyDialog { } export class ModelInfoDialog extends ComfyDialog { - constructor(name) { + constructor(name, node) { super(); this.name = name; + this.node = node; this.element.classList.add("pysssss-model-info"); } @@ -164,6 +165,7 @@ export class ModelInfoDialog extends ComfyDialog { textarea = null; notesContainer.replaceChildren(...parseNote.call(this)); + this.node?.["pysssss.updateExamples"]?.(); } else { e.target.textContent = "💾 Save"; textarea = $el("textarea", { diff --git a/web/js/modelInfo.js b/web/js/modelInfo.js index 6e7b8a4..085f877 100644 --- a/web/js/modelInfo.js +++ b/web/js/modelInfo.js @@ -194,6 +194,7 @@ export class LoraInfoDialog extends ModelInfoDialog { "content-type": "application/json", }, }); + this.node?.["pysssss.updateExamples"]?.(); alert("Saved!"); } catch (error) { console.error(error); @@ -299,7 +300,7 @@ function addInfoOption(node, type, infoClass, widgetNamePattern, opts) { opts.push({ content: optName, callback: async () => { - new infoClass(value).show(type, value); + new infoClass(value, node).show(type, value); }, }); }