diff --git a/.github/assets/example_2.png b/.github/assets/example_2.png new file mode 100644 index 0000000..1e468c1 Binary files /dev/null and b/.github/assets/example_2.png differ diff --git a/.github/assets/example_wf.png b/.github/assets/example_wf.png new file mode 100644 index 0000000..f7fc979 Binary files /dev/null and b/.github/assets/example_wf.png differ diff --git a/.github/assets/io_nodes.png b/.github/assets/io_nodes.png new file mode 100644 index 0000000..9d00ccc Binary files /dev/null and b/.github/assets/io_nodes.png differ diff --git a/.github/assets/lineage_large.png b/.github/assets/lineage_large.png new file mode 100644 index 0000000..2a7c2ff Binary files /dev/null and b/.github/assets/lineage_large.png differ diff --git a/.github/assets/retrieval_nodes.png b/.github/assets/retrieval_nodes.png new file mode 100644 index 0000000..d08a24e Binary files /dev/null and b/.github/assets/retrieval_nodes.png differ diff --git a/.github/assets/webui_3.png b/.github/assets/webui_3.png new file mode 100644 index 0000000..33e9683 Binary files /dev/null and b/.github/assets/webui_3.png differ diff --git a/README.md b/README.md index 0b26afb..db819f5 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,25 @@ 4. Run Embeddr-CLI with `embeddr serve` 5. Run ComfyUI + +## Usage + + +### Use New Load & Save Image + +![Example IO](.github/assets/io_nodes.png) + +![Example](.github/assets/example_2.png) + +### Retrieve from your collections + +![Example Retrieval](.github/assets/retrieval_nodes.png) + + +### Access more info on the [WebUI](https://github.com/embeddr-net/embeddr-cli) + +![Example Lineage](.github/assets/lineage_large.png) + ## Development To get a development version working. diff --git a/pyproject.toml b/pyproject.toml index 6e9e539..8b2934a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ [project] name = "embeddr-extension" description = "Embeddr ComfyUI Extension" -version = "1.2.0" +version = "1.2.1" license = { file = "LICENSE.md" } dependencies = [] requires-python = ">=3.8" diff --git a/ui/main.tsx b/ui/main.tsx index 0fbdeaa..b8dcd24 100644 --- a/ui/main.tsx +++ b/ui/main.tsx @@ -7,6 +7,7 @@ import { app } from "../../../scripts/app.js"; import EmbeddrPanel from "./components/panels/EmbeddrPanel.js"; import { GlobalDialog } from "./components/GlobalDialog"; import "./nodes/EmbeddrLoadImage.js"; +import "./nodes/EmbeddrMergeIds.js"; // @ts-ignore import "./globals.css"; diff --git a/ui/nodes/EmbeddrMergeIds.ts b/ui/nodes/EmbeddrMergeIds.ts new file mode 100644 index 0000000..5a3e847 --- /dev/null +++ b/ui/nodes/EmbeddrMergeIds.ts @@ -0,0 +1,67 @@ +import { app } from "../../../scripts/app.js"; + +const _ID = "embeddr.MergeIDs"; +const _PREFIX = "id"; +const _TYPE = "STRING"; + +app.registerExtension({ + name: "embeddr.dynamic_merge_ids", + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if (nodeData.name !== _ID) { + return; + } + + // Add initial input on creation + const onNodeCreated = nodeType.prototype.onNodeCreated; + nodeType.prototype.onNodeCreated = function () { + const me = onNodeCreated?.apply(this); + // Start with one dynamic input if none exist + if (!this.inputs || this.inputs.length === 0) { + this.addInput(`${_PREFIX}1`, _TYPE); + } + return me; + }; + + // Handle connections + const onConnectionsChange = nodeType.prototype.onConnectionsChange; + nodeType.prototype.onConnectionsChange = function ( + slotType, + slotIdx, + event, + linkInfo, + nodeSlot + ) { + const me = onConnectionsChange?.apply(this, arguments); + + // Only care about inputs (slotType 1) + if (slotType !== 1) return me; + + const inputs = this.inputs || []; + const lastInput = inputs[inputs.length - 1]; + + // If last input is connected, add a new one + if (lastInput && lastInput.link) { + this.addInput(`${_PREFIX}${inputs.length + 1}`, _TYPE); + } + + // Compact: Remove unconnected inputs that are NOT the last one + // Iterate backwards to avoid index issues + for (let i = inputs.length - 2; i >= 0; i--) { + if (!inputs[i].link) { + this.removeInput(i); + } + } + + // Rename all inputs to be sequential + for (let i = 0; i < this.inputs.length; i++) { + this.inputs[i].name = `${_PREFIX}${i + 1}`; + } + + if (this.graph) { + this.graph.setDirtyCanvas(true); + } + + return me; + }; + }, +});