diff --git a/README.md b/README.md index 84b39805..71642b5a 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ # Changes +* **0.9** Support keyword search in installer menu. * **V0.7.1** Bug fix for the issue where updates were not being applied on Windows. * **For those who have been using versions 0.6, please perform a manual git pull in the custom_nodes/ComfyUI-Manager directory.** * **V0.7** To address the issue of a slow list refresh, separate the fetch update and update check processes. diff --git a/__init__.py b/__init__.py index f340f594..3f73ed52 100644 --- a/__init__.py +++ b/__init__.py @@ -16,7 +16,7 @@ sys.path.append('../..') from torchvision.datasets.utils import download_url # ensure .js -print("### Loading: ComfyUI-Manager (V0.8)") +print("### Loading: ComfyUI-Manager (V0.9)") comfy_path = os.path.dirname(folder_paths.__file__) custom_nodes_path = os.path.join(comfy_path, 'custom_nodes') diff --git a/extension-node-map.json b/extension-node-map.json index e686faa9..2d11cca8 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -207,15 +207,29 @@ ], "https://github.com/LucianoCirino/efficiency-nodes-comfyui": [ "Efficient Loader", + "Evaluate Floats", "Evaluate Integers", "Evaluate Strings", "Image Overlay", + "Join XY Inputs", "KSampler (Efficient)", + "Simple Eval Examples", + "XY Input: CFG Scale", + "XY Input: Checkpoint", + "XY Input: Denoise", + "XY Input: LoRA", + "XY Input: LoRA (Advanced)", + "XY Input: Sampler", + "XY Input: Scheduler", + "XY Input: Seeds++ Batch", + "XY Input: Steps", + "XY Input: VAE", "XY Plot" ], "https://github.com/Nourepide/ComfyUI-Allore": [ "AlphaChanelAsMask", "AlphaChanelByMask", + "AlphaChanelRemove", "AlphaChanelRestore", "ClipClamp", "ClipVisionClamp", @@ -225,20 +239,46 @@ "GligenClamp", "ImageClamp", "ImageCompositeAbsolute", + "ImageCompositeAbsoluteByContainer", "ImageCompositeRelative", + "ImageCompositeRelativeByContainer", "ImageContainer", "ImageContainerInheritanceAdd", "ImageContainerInheritanceMax", "ImageContainerInheritanceScale", "ImageContainerInheritanceSum", "ImageDrawArc", + "ImageDrawArcByContainer", "ImageDrawChord", + "ImageDrawChordByContainer", "ImageDrawEllipse", + "ImageDrawEllipseByContainer", "ImageDrawLine", + "ImageDrawLineByContainer", "ImageDrawPieslice", + "ImageDrawPiesliceByContainer", "ImageDrawPolygon", "ImageDrawRectangle", + "ImageDrawRectangleByContainer", "ImageDrawRectangleRounded", + "ImageDrawRectangleRoundedByContainer", + "ImageFilterBlur", + "ImageFilterBoxBlur", + "ImageFilterContour", + "ImageFilterDetail", + "ImageFilterEdgeEnhance", + "ImageFilterEdgeEnhanceMore", + "ImageFilterEmboss", + "ImageFilterFindEdges", + "ImageFilterGaussianBlur", + "ImageFilterMax", + "ImageFilterMedian", + "ImageFilterMin", + "ImageFilterMode", + "ImageFilterRank", + "ImageFilterSharpen", + "ImageFilterSmooth", + "ImageFilterSmoothMore", "ImageSegmentation", "ImageSegmentationCustom", "ImageSegmentationCustomAdvanced", @@ -258,12 +298,15 @@ "LatentSelector" ], "https://github.com/TinyTerra/ComfyUI_tinyterraNodes.git": [ + "ttN busIN", + "ttN busOUT", "ttN concat", + "ttN debugInput", "ttN float", + "ttN hiresfixScale", "ttN imageOutput", "ttN imageREMBG", "ttN int", - "ttN modelScale", "ttN pipe2BASIC", "ttN pipe2DETAILER", "ttN pipeEDIT", diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index e604486b..5a8e9416 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -218,6 +218,7 @@ class CustomNodesInstaller extends ComfyDialog { constructor() { super(); + this.search_keyword = ''; this.element = $el("div.comfy-modal", { parent: document.body }, []); } @@ -232,6 +233,22 @@ class CustomNodesInstaller extends ComfyDialog { } } + apply_searchbox(data) { + let keyword = this.search_box.value.toLowerCase(); + for(let i in this.grid_rows) { + let data = this.grid_rows[i].data; + let content = data.author.toLowerCase() + data.description.toLowerCase() + data.title.toLowerCase(); + if(keyword == "") + this.grid_rows[i].control.style.display = null; + else if(content.includes(keyword)) { + this.grid_rows[i].control.style.display = null; + } + else { + this.grid_rows[i].control.style.display = 'none'; + } + } + } + async filter_missing_node(data) { const mappings = await getCustomnodeMappings(); @@ -280,7 +297,9 @@ class CustomNodesInstaller extends ComfyDialog { const msg = $el('div', {id:'custom-message'}, [$el('br'), - 'The custom node DB is currently being updated, and updates to custom nodes are being checked for.', + 'The custom node DB is currently being updated, and updates to custom nodes are being checked for.', + $el('br'), + 'NOTE: Update only checks for extensions that have been fetched.', $el('br')]); msg.style.height = '100px'; msg.style.verticalAlign = 'middle'; @@ -298,8 +317,10 @@ class CustomNodesInstaller extends ComfyDialog { this.element.removeChild(this.element.children[0]); } + this.createHeaderControls(); await this.createGrid(); - this.createControls(); + this.apply_searchbox(this.data); + this.createBottomControls(); } updateMessage(msg) { @@ -343,6 +364,8 @@ class CustomNodesInstaller extends ComfyDialog { headerRow.style.padding = "0"; grid.appendChild(headerRow); + this.grid_rows = {}; + if(this.data) for (var i = 0; i < this.data.length; i++) { const data = this.data[i]; @@ -455,6 +478,8 @@ class CustomNodesInstaller extends ComfyDialog { dataRow.appendChild(data4); dataRow.appendChild(data5); grid.appendChild(dataRow); + + this.grid_rows[i] = {data:data, control:dataRow}; } const panel = document.createElement('div'); @@ -466,10 +491,43 @@ class CustomNodesInstaller extends ComfyDialog { this.element.appendChild(panel); } - async createControls() { - var close_button = document.createElement("button"); + createHeaderControls() { + this.search_box = $el('input', {type:'text', id:'manager-customnode-search-box', placeholder:'input search keyword', value:this.search_keyword}, []); + this.search_box.style.height = "25px"; + this.search_box.onkeydown = (event) => { + if (event.key === 'Enter') { + this.search_keyword = this.search_box.value; + this.apply_searchbox(); + } + if (event.key === 'Escape') { + this.search_keyword = this.search_box.value; + this.search_box.value = ''; + this.apply_searchbox(); + } + }; + + let search_button = document.createElement("button"); + search_button.innerHTML = "Search"; + search_button.onclick = () => { + this.apply_searchbox(); + }; + search_button.style.display = "inline-block"; + + let cell = $el('td', {width:'100%'}, [this.search_box, ' ', search_button]); + let search_control = $el('table', {width:'100%'}, + [ + $el('tr', {}, [cell]) + ] + ); + + cell.style.textAlign = "right"; + this.element.appendChild(search_control); + } + + async createBottomControls() { + let close_button = document.createElement("button"); close_button.innerHTML = "Close"; - close_button.onclick = () => { this.close(); } + close_button.onclick = () => { this.search_keyword = ''; this.close(); } close_button.style.display = "inline-block"; this.message_box = $el('div', {id:'custom-installer-message'}, [$el('br'), '']); @@ -509,6 +567,7 @@ class AlternativesInstaller extends ComfyDialog { constructor() { super(); + this.search_keyword = ''; this.element = $el("div.comfy-modal", { parent: document.body }, []); } @@ -523,6 +582,23 @@ class AlternativesInstaller extends ComfyDialog { } } + apply_searchbox(data) { + let keyword = this.search_box.value.toLowerCase(); + for(let i in this.grid_rows) { + let data1 = this.grid_rows[i].data; + let data2 = data1.custom_node; + let content = data1.tags.toLowerCase() + data1.description.toLowerCase() + data2.author.toLowerCase() + data2.description.toLowerCase() + data2.title.toLowerCase(); + if(keyword == "") + this.grid_rows[i].control.style.display = null; + else if(content.includes(keyword)) { + this.grid_rows[i].control.style.display = null; + } + else { + this.grid_rows[i].control.style.display = 'none'; + } + } + } + async invalidateControl() { this.clear(); @@ -534,6 +610,8 @@ class AlternativesInstaller extends ComfyDialog { const msg = $el('div', {id:'custom-message'}, [$el('br'), 'The custom node DB is currently being updated, and updates to custom nodes are being checked for.', + $el('br'), + 'NOTE: Update only checks for extensions that have been fetched.', $el('br')]); msg.style.height = '100px'; msg.style.verticalAlign = 'middle'; @@ -548,8 +626,10 @@ class AlternativesInstaller extends ComfyDialog { this.element.removeChild(this.element.children[0]); } + this.createHeaderControls(); await this.createGrid(); - this.createControls(); + this.apply_searchbox(this.data); + this.createBottomControls(); } updateMessage(msg) { @@ -597,6 +677,8 @@ class AlternativesInstaller extends ComfyDialog { headerRow.style.padding = "0"; grid.appendChild(headerRow); + this.grid_rows = {}; + if(this.data) for (var i = 0; i < this.data.length; i++) { const data = this.data[i]; @@ -724,6 +806,8 @@ class AlternativesInstaller extends ComfyDialog { dataRow.appendChild(data5); dataRow.appendChild(data6); grid.appendChild(dataRow); + + this.grid_rows[i] = {data:data, control:dataRow}; } const panel = document.createElement('div'); @@ -735,7 +819,40 @@ class AlternativesInstaller extends ComfyDialog { this.element.appendChild(panel); } - async createControls() { + createHeaderControls() { + this.search_box = $el('input', {type:'text', id:'manager-alternode-search-box', placeholder:'input search keyword', value:this.search_keyword}, []); + this.search_box.style.height = "25px"; + this.search_box.onkeydown = (event) => { + if (event.key === 'Enter') { + this.search_keyword = this.search_box.value; + this.apply_searchbox(); + } + if (event.key === 'Escape') { + this.search_keyword = this.search_box.value; + this.search_box.value = ''; + this.apply_searchbox(); + } + }; + + let search_button = document.createElement("button"); + search_button.innerHTML = "Search"; + search_button.onclick = () => { + this.apply_searchbox(); + }; + search_button.style.display = "inline-block"; + + let cell = $el('td', {width:'100%'}, [this.search_box, ' ', search_button]); + let search_control = $el('table', {width:'100%'}, + [ + $el('tr', {}, [cell]) + ] + ); + + cell.style.textAlign = "right"; + this.element.appendChild(search_control); + } + + async createBottomControls() { var close_button = document.createElement("button"); close_button.innerHTML = "Close"; close_button.onclick = () => { this.close(); } @@ -778,6 +895,7 @@ class ModelInstaller extends ComfyDialog { constructor() { super(); + this.search_keyword = ''; this.element = $el("div.comfy-modal", { parent: document.body }, []); } @@ -802,6 +920,22 @@ class ModelInstaller extends ComfyDialog { } } + apply_searchbox(data) { + let keyword = this.search_box.value.toLowerCase(); + for(let i in this.grid_rows) { + let data = this.grid_rows[i].data; + let content = data.name.toLowerCase() + data.type.toLowerCase() + data.base.toLowerCase() + data.description.toLowerCase(); + if(keyword == "") + this.grid_rows[i].control.style.display = null; + else if(content.includes(keyword)) { + this.grid_rows[i].control.style.display = null; + } + else { + this.grid_rows[i].control.style.display = 'none'; + } + } + } + async invalidateControl() { this.clear(); this.data = (await getModelList()).models; @@ -810,8 +944,9 @@ class ModelInstaller extends ComfyDialog { this.element.removeChild(this.element.children[0]); } + await this.createHeaderControls(); await this.createGrid(); - this.createControls(); + await this.createBottomControls(); } updateMessage(msg) { @@ -865,6 +1000,8 @@ class ModelInstaller extends ComfyDialog { headerRow.style.padding = "0"; grid.appendChild(headerRow); + this.grid_rows = {}; + if(this.data) for (var i = 0; i < this.data.length; i++) { const data = this.data[i]; @@ -925,6 +1062,8 @@ class ModelInstaller extends ComfyDialog { dataRow.appendChild(data6); dataRow.appendChild(data_install); grid.appendChild(dataRow); + + this.grid_rows[i] = {data:data, control:dataRow}; } const panel = document.createElement('div'); @@ -936,7 +1075,40 @@ class ModelInstaller extends ComfyDialog { this.element.appendChild(panel); } - async createControls() { + createHeaderControls() { + this.search_box = $el('input', {type:'text', id:'manager-model-search-box', placeholder:'input search keyword', value:this.search_keyword}, []); + this.search_box.style.height = "25px"; + this.search_box.onkeydown = (event) => { + if (event.key === 'Enter') { + this.search_keyword = this.search_box.value; + this.apply_searchbox(); + } + if (event.key === 'Escape') { + this.search_keyword = this.search_box.value; + this.search_box.value = ''; + this.apply_searchbox(); + } + }; + + let search_button = document.createElement("button"); + search_button.innerHTML = "Search"; + search_button.onclick = () => { + this.apply_searchbox(); + }; + search_button.style.display = "inline-block"; + + let cell = $el('td', {width:'100%'}, [this.search_box, ' ', search_button]); + let search_control = $el('table', {width:'100%'}, + [ + $el('tr', {}, [cell]) + ] + ); + + cell.style.textAlign = "right"; + this.element.appendChild(search_control); + } + + async createBottomControls() { var close_button = document.createElement("button"); close_button.innerHTML = "Close"; close_button.onclick = () => { this.close(); } diff --git a/misc/custom-nodes.png b/misc/custom-nodes.png index 4e125b59..59708d0f 100644 Binary files a/misc/custom-nodes.png and b/misc/custom-nodes.png differ diff --git a/misc/models.png b/misc/models.png index 7062b33f..3d3c9918 100644 Binary files a/misc/models.png and b/misc/models.png differ diff --git a/model-list.json b/model-list.json index 4c7257ec..4dc519e9 100644 --- a/model-list.json +++ b/model-list.json @@ -1,9 +1,9 @@ { "models": [ { - "name": "TASED Decoder", + "name": "TAESD Decoder", "type": "VAE", - "base": "TASED", + "base": "TAESD", "save_path": "vae_approx", "description": "To view the preview in high quality while running samples in ComfyUI, you will need this model.", "reference": "https://github.com/madebyollin/taesd", @@ -11,9 +11,9 @@ "url": "https://github.com/madebyollin/taesd/raw/main/taesd_decoder.pth" }, { - "name": "TASED Encoder", + "name": "TAESD Encoder", "type": "VAE", - "base": "TASED", + "base": "TAESD", "save_path": "vae_approx", "description": "To view the preview in high quality while running samples in ComfyUI, you will need this model.", "reference": "https://github.com/madebyollin/taesd",