Browse Source

Add alternatives of A1111 menu.

Add local db mode
pull/7/head
Dr.Lt.Data 2 years ago
parent
commit
63af7efa63
  1. 119
      __init__.py
  2. 36
      alter-list.json
  3. 317
      js/comfyui-manager.js

119
__init__.py

@ -14,10 +14,37 @@ print("### Loading: ComfyUI-Manager")
comfy_path = os.path.dirname(folder_paths.__file__) comfy_path = os.path.dirname(folder_paths.__file__)
custom_nodes_path = os.path.join(comfy_path, 'custom_nodes') custom_nodes_path = os.path.join(comfy_path, 'custom_nodes')
comfyui_manager_path = os.path.dirname(__file__)
local_db_model = os.path.join(comfyui_manager_path, "model-list.json")
local_db_alter = os.path.join(comfyui_manager_path, "alter-list.json")
local_db_custom_node_list = os.path.join(comfyui_manager_path, "custom-node-list.json")
async def get_data(uri):
print(f"FECTH DATA from: {uri}")
if uri.startswith("http"):
async with aiohttp.ClientSession() as session:
async with session.get(uri) as resp:
json_text = await resp.text()
else:
with open(uri, "r") as f:
json_text = f.read()
json_obj = json.loads(json_text)
return json_obj
def setup_js(): def setup_js():
impact_path = os.path.dirname(__file__) # remove garbage
js_dest_path = os.path.join(comfy_path, "web", "extensions", "core") old_js_path = os.path.join(comfy_path, "web", "extensions", "core", "comfyui-manager.js")
js_src_path = os.path.join(impact_path, "js", "comfyui-manager.js") if os.path.exists(old_js_path):
os.remove(old_js_path)
# setup js
js_dest_path = os.path.join(comfy_path, "web", "extensions", "comfyui-manager")
if not os.path.exists(js_dest_path):
os.makedirs(js_dest_path)
js_src_path = os.path.join(comfyui_manager_path, "js", "comfyui-manager.js")
shutil.copy(js_src_path, js_dest_path) shutil.copy(js_src_path, js_dest_path)
setup_js() setup_js()
@ -64,40 +91,74 @@ def get_model_path(data):
return os.path.join(base_model, data['filename']) return os.path.join(base_model, data['filename'])
def check_custom_node_installed(json_obj): def check_a_custom_node_installed(item):
for item in json_obj['custom_nodes']: item['installed'] = 'None'
item['installed'] = 'None'
if item['install_type'] == 'git-clone' and len(item['files']) == 1: if item['install_type'] == 'git-clone' and len(item['files']) == 1:
dir_name = os.path.splitext(os.path.basename(item['files'][0]))[0].replace(".git", "") dir_name = os.path.splitext(os.path.basename(item['files'][0]))[0].replace(".git", "")
dir_path = os.path.join(custom_nodes_path, dir_name) dir_path = os.path.join(custom_nodes_path, dir_name)
if os.path.exists(dir_path): if os.path.exists(dir_path):
item['installed'] = 'True' item['installed'] = 'True'
else: else:
item['installed'] = 'False' item['installed'] = 'False'
elif item['install_type'] == 'copy' and len(item['files']) == 1: elif item['install_type'] == 'copy' and len(item['files']) == 1:
dir_name = os.path.basename(item['files'][0]) dir_name = os.path.basename(item['files'][0])
dir_path = os.path.join(custom_nodes_path, dir_name) dir_path = os.path.join(custom_nodes_path, dir_name)
if os.path.exists(dir_path): if os.path.exists(dir_path):
item['installed'] = 'True' item['installed'] = 'True'
else: else:
item['installed'] = 'False' item['installed'] = 'False'
def check_custom_nodes_installed(json_obj):
for item in json_obj['custom_nodes']:
check_a_custom_node_installed(item)
@server.PromptServer.instance.routes.post("/customnode/getlist") @server.PromptServer.instance.routes.get("/customnode/getlist")
async def fetch_customnode_list(request): async def fetch_customnode_list(request):
url = 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json' if request.rel_url.query["mode"] == "local":
uri = local_db_custom_node_list
else:
uri = 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json'
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get(url) as resp: async with session.get(uri) as resp:
json_text = await resp.text() json_text = await resp.text()
json_obj = json.loads(json_text) json_obj = json.loads(json_text)
check_custom_node_installed(json_obj) check_custom_nodes_installed(json_obj)
return web.json_response(json_obj, content_type='application/json') return web.json_response(json_obj, content_type='application/json')
@server.PromptServer.instance.routes.get("/alternatives/getlist")
async def fetch_alternatives_list(request):
if request.rel_url.query["mode"] == "local":
uri1 = local_db_alter
uri2 = local_db_custom_node_list
else:
uri1 = 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/alter-list.json'
uri2 = 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json'
alter_json = await get_data(uri1)
custom_node_json = await get_data(uri2)
fileurl_to_custom_node = {}
for item in custom_node_json['custom_nodes']:
for fileurl in item['files']:
fileurl_to_custom_node[fileurl] = item
for item in alter_json['items']:
fileurl = item['id']
if fileurl in fileurl_to_custom_node:
custom_node = fileurl_to_custom_node[fileurl]
check_a_custom_node_installed(custom_node)
item['custom_node'] = custom_node
return web.json_response(alter_json, content_type='application/json')
def check_model_installed(json_obj): def check_model_installed(json_obj):
for item in json_obj['models']: for item in json_obj['models']:
item['installed'] = 'None' item['installed'] = 'None'
@ -111,11 +172,15 @@ def check_model_installed(json_obj):
item['installed'] = 'False' item['installed'] = 'False'
@server.PromptServer.instance.routes.post("/externalmodel/getlist") @server.PromptServer.instance.routes.get("/externalmodel/getlist")
async def fetch_externalmodel_list(request): async def fetch_externalmodel_list(request):
url = 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/model-list.json' if request.rel_url.query["mode"] == "local":
uri = local_db_model
else:
uri = 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/model-list.json'
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get(url) as resp: async with session.get(uri) as resp:
json_text = await resp.text() json_text = await resp.text()
json_obj = json.loads(json_text) json_obj = json.loads(json_text)

36
alter-list.json

@ -3,99 +3,71 @@
{ {
"id":"https://github.com/Fannovel16/comfy_controlnet_preprocessors", "id":"https://github.com/Fannovel16/comfy_controlnet_preprocessors",
"tags":"controlnet", "tags":"controlnet",
"author":"Fannovel16",
"title":"ControlNet Preprocessors",
"description": "This extension provides preprocessor nodes for using controlnet." "description": "This extension provides preprocessor nodes for using controlnet."
}, },
{ {
"id":"https://github.com/comfyanonymous/ComfyUI_experiments", "id":"https://github.com/comfyanonymous/ComfyUI_experiments/raw/master/sampler_tonemap.py",
"tags":"Dynamic Thresholding, DT", "tags":"Dynamic Thresholding, DT",
"author":"comfyanonymous",
"title":"ComfyUI_experiments/sampler_tonemap",
"description": "Increasing the CFG prevents the degradation of color accuracy." "description": "Increasing the CFG prevents the degradation of color accuracy."
}, },
{ {
"id":"https://github.com/ltdrdata/ComfyUI-Impact-Pack", "id":"https://github.com/ltdrdata/ComfyUI-Impact-Pack",
"tags":"ddetailer, adetailer, ddsd, DD", "tags":"ddetailer, adetailer, ddsd, DD",
"author":"Dr.Lt.Data",
"title":"ComfyUI Impact Pack",
"description": "To implement the feature of automatically detecting faces and enhancing details, various detection nodes and detailers provided by the Impact Pack can be applied." "description": "To implement the feature of automatically detecting faces and enhancing details, various detection nodes and detailers provided by the Impact Pack can be applied."
}, },
{ {
"id":"https://github.com/biegert/ComfyUI-CLIPSeg", "id":"https://github.com/biegert/ComfyUI-CLIPSeg/raw/main/custom_nodes/clipseg.py",
"tags":"ddsd", "tags":"ddsd",
"author":"biegert",
"title":"CLIPSeg",
"description": "This extension provides a feature that generates segment masks on an image using a text prompt. When used in conjunction with Impact Pack, it enables applications such as DDSD." "description": "This extension provides a feature that generates segment masks on an image using a text prompt. When used in conjunction with Impact Pack, it enables applications such as DDSD."
}, },
{ {
"id":"https://github.com/BadCafeCode/masquerade-nodes-comfyui", "id":"https://github.com/BadCafeCode/masquerade-nodes-comfyui",
"tags":"ddetailer", "tags":"ddetailer",
"author":"BadCafeCode",
"title":"Masquerade Nodes",
"description": "This extension provides a way to recognize and enhance masks for faces similar to Impact Pack." "description": "This extension provides a way to recognize and enhance masks for faces similar to Impact Pack."
}, },
{ {
"id":"https://github.com/BlenderNeko/ComfyUI_Cutoff", "id":"https://github.com/BlenderNeko/ComfyUI_Cutoff",
"tags":"cutoff", "tags":"cutoff",
"author":"BlenderNeko",
"title":"ComfyUI Cutoff",
"description": "By using this extension, prompts like 'blue hair' can be prevented from interfering with other prompts by blocking the attribute 'blue' from being used in prompts other than 'hair'." "description": "By using this extension, prompts like 'blue hair' can be prevented from interfering with other prompts by blocking the attribute 'blue' from being used in prompts other than 'hair'."
}, },
{ {
"id":"https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb", "id":"https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb",
"tags":"prompt, weight", "tags":"prompt, weight",
"author":"BlenderNeko",
"title":"Advanced CLIP Text Encode",
"description": "There are differences in the processing methods of prompts, such as weighting and scheduling, between A1111 and ComfyUI. With this extension, various settings can be used to implement prompt processing methods similar to A1111. As this feature is also integrated into ComfyUI Cutoff, please download the Cutoff extension if you plan to use it in conjunction with Cutoff." "description": "There are differences in the processing methods of prompts, such as weighting and scheduling, between A1111 and ComfyUI. With this extension, various settings can be used to implement prompt processing methods similar to A1111. As this feature is also integrated into ComfyUI Cutoff, please download the Cutoff extension if you plan to use it in conjunction with Cutoff."
}, },
{ {
"id":"https://github.com/BlenderNeko/ComfyUI_Noise", "id":"https://github.com/BlenderNeko/ComfyUI_Noise",
"tags":"img2img alt", "tags":"img2img alt, random",
"author":"BlenderNeko", "description": "The extension provides an unsampler that reverses the sampling process, allowing for a function similar to img2img alt to be implemented. Furthermore, ComfyUI uses CPU's Random instead of GPU's Random for better reproducibility compared to A1111. This extension provides the ability to use GPU's Random for Latent Noise. However, since GPU's Random may vary depending on the GPU model, reproducibility on different devices cannot be guaranteed."
"title":"ComfyUI Noise",
"description": "The extension provides an unsampler that reverses the sampling process, allowing for a function similar to img2img alt to be implemented."
}, },
{ {
"id":"https://github.com/lilly1987/ComfyUI_node_Lilly", "id":"https://github.com/lilly1987/ComfyUI_node_Lilly",
"tags":"prompt, wildcard", "tags":"prompt, wildcard",
"author":"lilly1987",
"title":"simple wildcard for ComfyUI",
"description": "This extension provides features such as a wildcard function that randomly selects prompts belonging to a category and the ability to directly load lora from prompts." "description": "This extension provides features such as a wildcard function that randomly selects prompts belonging to a category and the ability to directly load lora from prompts."
}, },
{ {
"id":"https://github.com/Davemane42/ComfyUI_Dave_CustomNode", "id":"https://github.com/Davemane42/ComfyUI_Dave_CustomNode",
"tags":"latent couple", "tags":"latent couple",
"author":"Davemane42",
"title":"Visual Area Conditioning / Latent composition",
"description": "ComfyUI already provides the ability to composite latents by default. However, this extension makes it more convenient to use by visualizing the composite area." "description": "ComfyUI already provides the ability to composite latents by default. However, this extension makes it more convenient to use by visualizing the composite area."
}, },
{ {
"id":"https://github.com/LEv145/images-grid-comfy-plugin", "id":"https://github.com/LEv145/images-grid-comfy-plugin",
"tags":"X/Y Plot", "tags":"X/Y Plot",
"author":"LEv145",
"title":"ImagesGrid",
"description": "This tool provides a viewer node that allows for checking multiple outputs in a grid, similar to the X/Y Plot extension." "description": "This tool provides a viewer node that allows for checking multiple outputs in a grid, similar to the X/Y Plot extension."
}, },
{ {
"id":"https://github.com/gamert/ComfyUI_tagger", "id":"https://github.com/gamert/ComfyUI_tagger",
"tags":"deepbooru, clip interrogation", "tags":"deepbooru, clip interrogation",
"author":"gamert",
"title":"ComfyUI_tagger",
"description": "This extension generates clip text by taking an image as input and using the Deepbooru model." "description": "This extension generates clip text by taking an image as input and using the Deepbooru model."
}, },
{ {
"id":"https://github.com/szhublox/ambw_comfyui", "id":"https://github.com/szhublox/ambw_comfyui",
"tags":"supermerger", "tags":"supermerger",
"author":"szhublox",
"title":"Auto-MBW",
"description": "This node takes two models, merges individual blocks together at various ratios, and automatically rates each merge, keeping the ratio with the highest score. " "description": "This node takes two models, merges individual blocks together at various ratios, and automatically rates each merge, keeping the ratio with the highest score. "
}, },
{ {
"id":"https://github.com/asd417/tomeSD_for_Comfy/raw/main/tomeloader.py", "id":"https://github.com/asd417/tomeSD_for_Comfy/raw/main/tomeloader.py",
"tags":"tomesd", "tags":"tomesd",
"author":"szhublox",
"title":"Auto-MBW",
"description": "This extension is a ComfyUI wrapper for 'tomesd' that improves generation speed through token merging." "description": "This extension is a ComfyUI wrapper for 'tomesd' that improves generation speed through token merging."
} }
] ]

317
js/comfyui-manager.js vendored

@ -3,30 +3,41 @@ import { ComfyDialog, $el } from "/scripts/ui.js";
import {ComfyWidgets} from "../../scripts/widgets.js"; import {ComfyWidgets} from "../../scripts/widgets.js";
async function getCustomNodes() { async function getCustomNodes() {
const response = await fetch('/customnode/getlist', { var mode = "url";
method: 'POST', if(ManagerMenuDialog.instance.local_mode_checkbox.checked)
headers: { 'Content-Type': 'application/json' }, mode = "local";
body: JSON.stringify({})
}); const response = await fetch(`/customnode/getlist?mode=${mode}`);
const data = await response.json();
return data;
}
async function getAlterList() {
var mode = "url";
if(ManagerMenuDialog.instance.local_mode_checkbox.checked)
mode = "local";
const response = await fetch(`/alternatives/getlist?mode=${mode}`);
const data = await response.json(); const data = await response.json();
return data; return data;
} }
async function getModelList() { async function getModelList() {
const response = await fetch('/externalmodel/getlist', { var mode = "url";
method: 'POST', if(ManagerMenuDialog.instance.local_mode_checkbox.checked)
headers: { 'Content-Type': 'application/json' }, mode = "local";
body: JSON.stringify({})
}); const response = await fetch(`/externalmodel/getlist?mode=${mode}`);
const data = await response.json(); const data = await response.json();
return data; return data;
} }
async function install_custom_node(target) { async function install_custom_node(target, caller) {
if(CustomNodesInstaller.instance) { if(caller) {
CustomNodesInstaller.instance.startInstall(target); caller.startInstall(target);
try { try {
const response = await fetch('/customnode/install', { const response = await fetch('/customnode/install', {
@ -46,7 +57,7 @@ async function install_custom_node(target) {
return false; return false;
} }
finally { finally {
CustomNodesInstaller.instance.stopInstall(); caller.invalidateControl();
} }
} }
} }
@ -73,12 +84,13 @@ async function install_model(target) {
return false; return false;
} }
finally { finally {
ModelInstaller.instance.stopInstall(); ModelInstaller.instance.invalidateControl();
} }
} }
} }
// -----
class CustomNodesInstaller extends ComfyDialog { class CustomNodesInstaller extends ComfyDialog {
static instance = null; static instance = null;
@ -98,7 +110,6 @@ class CustomNodesInstaller extends ComfyDialog {
} }
startInstall(target) { startInstall(target) {
console.log(target);
this.message_box.innerHTML = `<BR><font color="green">Installing '${target.title}'</font>`; this.message_box.innerHTML = `<BR><font color="green">Installing '${target.title}'</font>`;
for(let i in this.install_buttons) { for(let i in this.install_buttons) {
@ -107,29 +118,16 @@ class CustomNodesInstaller extends ComfyDialog {
} }
} }
stopInstall() { async invalidateControl() {
this.message_box.innerHTML = '<BR>To apply the installed custom node, please restart ComfyUI.'; this.clear();
this.data = (await getCustomNodes()).custom_nodes;
for(let i in this.install_buttons) { while (this.element.children.length) {
switch(this.data[i].installed) this.element.removeChild(this.element.children[0]);
{
case 'True':
this.install_buttons[i].innerHTML = 'Installed';
this.install_buttons[i].style.backgroundColor = 'green';
this.install_buttons[i].disabled = true;
break;
case 'False':
this.install_buttons[i].innerHTML = 'Install';
this.install_buttons[i].style.backgroundColor = 'black';
this.install_buttons[i].disabled = false;
break;
default:
this.install_buttons[i].innerHTML = 'Try Install';
this.install_buttons[i].style.backgroundColor = 'brown';
this.install_buttons[i].disabled = false;
break;
}
} }
await this.createGrid();
this.createControls();
} }
async createGrid() { async createGrid() {
@ -205,7 +203,7 @@ class CustomNodesInstaller extends ComfyDialog {
} }
installBtn.addEventListener('click', function() { installBtn.addEventListener('click', function() {
install_custom_node(data); install_custom_node(data, CustomNodesInstaller.instance);
}); });
data5.appendChild(installBtn); data5.appendChild(installBtn);
@ -247,23 +245,197 @@ class CustomNodesInstaller extends ComfyDialog {
async show() { async show() {
try { try {
this.clear(); this.invalidateControl();
this.data = (await getCustomNodes()).custom_nodes;
this.element.style.display = "block";
}
catch(exception) {
app.ui.dialog.show(`Failed to get custom node list. / ${exception}`);
}
}
}
// -----
class AlternativesInstaller extends ComfyDialog {
static instance = null;
install_buttons = [];
message_box = null;
data = null;
clear() {
this.install_buttons = [];
this.message_box = null;
this.data = null;
}
constructor() {
super();
this.element = $el("div.comfy-modal", { parent: document.body }, []);
}
startInstall(target) {
this.message_box.innerHTML = `<BR><font color="green">Installing '${target.title}'</font>`;
for(let i in this.install_buttons) {
this.install_buttons[i].disabled = true;
this.install_buttons[i].style.backgroundColor = 'gray';
}
}
async invalidateControl() {
this.clear();
this.data = (await getAlterList()).items;
while (this.element.children.length) {
this.element.removeChild(this.element.children[0]);
}
await this.createGrid();
this.createControls();
}
async createGrid() {
var grid = document.createElement('table');
grid.setAttribute('id', 'alternatives-grid');
grid.style.position = "relative";
grid.style.display = "inline-block";
grid.style.width = "100%"
while (this.element.children.length) { var headerRow = document.createElement('tr');
this.element.removeChild(this.element.children[0]); var header1 = document.createElement('th');
header1.innerHTML = '&nbsp;&nbsp;ID&nbsp;&nbsp;';
header1.style.width = "20px";
var header2 = document.createElement('th');
header2.innerHTML = 'Tags';
header2.style.width = "200px";
var header3 = document.createElement('th');
header3.innerHTML = 'Author';
header3.style.width = "150px";
var header4 = document.createElement('th');
header4.innerHTML = 'Title';
header4.style.width = "200px";
var header5 = document.createElement('th');
header5.innerHTML = 'Description';
header5.style.width = "500px";
var header6 = document.createElement('th');
header6.innerHTML = 'Install';
header6.style.width = "130px";
headerRow.appendChild(header1);
headerRow.appendChild(header2);
headerRow.appendChild(header3);
headerRow.appendChild(header4);
headerRow.appendChild(header5);
headerRow.appendChild(header6);
headerRow.style.backgroundColor = "Black";
headerRow.style.color = "White";
headerRow.style.textAlign = "center";
headerRow.style.width = "100%";
headerRow.style.padding = "0";
grid.appendChild(headerRow);
if(this.data)
for (var i = 0; i < this.data.length; i++) {
const data = this.data[i];
var dataRow = document.createElement('tr');
var data1 = document.createElement('td');
data1.style.textAlign = "center";
data1.innerHTML = i+1;
var data2 = document.createElement('td');
data2.innerHTML = `&nbsp;${data.tags}`;
var data3 = document.createElement('td');
var data4 = document.createElement('td');
if(data.custom_node) {
data3.innerHTML = `&nbsp;${data.custom_node.author}`;
data4.innerHTML = `&nbsp;<a href=${data.custom_node.reference} target="_blank"><font color="skyblue"><b>${data.custom_node.title}</b></font></a>`;
}
else {
data3.innerHTML = `&nbsp;Unknown`;
data4.innerHTML = `&nbsp;Unknown`;
}
var data5 = document.createElement('td');
data5.innerHTML = data.description;
var data6 = document.createElement('td');
data6.style.textAlign = "center";
if(data.custom_node) {
var installBtn = document.createElement('button');
this.install_buttons.push(installBtn);
switch(data.custom_node.installed) {
case 'True':
installBtn.innerHTML = 'Installed';
installBtn.style.backgroundColor = 'green';
installBtn.disabled = true;
break;
case 'False':
installBtn.innerHTML = 'Install';
installBtn.style.backgroundColor = 'black';
break;
default:
installBtn.innerHTML = 'Try Install';
installBtn.style.backgroundColor = 'brown';
}
installBtn.addEventListener('click', function() {
install_custom_node(data.custom_node, AlternativesInstaller.instance);
});
data6.appendChild(installBtn);
}
dataRow.style.backgroundColor = "#444444";
dataRow.style.color = "White";
dataRow.style.textAlign = "left";
dataRow.appendChild(data1);
dataRow.appendChild(data2);
dataRow.appendChild(data3);
dataRow.appendChild(data4);
dataRow.appendChild(data5);
dataRow.appendChild(data6);
grid.appendChild(dataRow);
} }
await this.createGrid(); const panel = document.createElement('div');
this.createControls(); panel.style.height = "400px";
panel.style.width = "1000px";
panel.style.overflowY = "scroll";
panel.appendChild(grid);
this.element.appendChild(panel);
}
async createControls() {
var close_button = document.createElement("button");
close_button.innerHTML = "Close";
close_button.onclick = () => { this.close(); }
close_button.style.display = "inline-block";
this.message_box = $el('div', {id:'alternatives-installer-message'}, [$el('br'), '']);
this.message_box.style.height = '60px';
this.message_box.style.verticalAlign = 'middle';
this.element.appendChild(this.message_box);
this.element.appendChild(close_button);
}
async show() {
try {
this.invalidateControl();
this.element.style.display = "block"; this.element.style.display = "block";
} }
catch(exception) { catch(exception) {
app.ui.dialog.show(`Failed to get custom node list. / ${exception}`); app.ui.dialog.show(`Failed to get alternatives list. / ${exception}`);
console.error(exception);
} }
} }
} }
// ----------- // -----------
class ModelInstaller extends ComfyDialog { class ModelInstaller extends ComfyDialog {
static instance = null; static instance = null;
@ -302,24 +474,16 @@ class ModelInstaller extends ComfyDialog {
} }
} }
stopInstall() { async invalidateControl() {
this.message_box.innerHTML = "<BR>To apply the installed model, please click the 'Refresh' button on the main menu."; this.clear();
this.data = (await getModelList()).models;
for(let i in this.install_buttons) { while (this.element.children.length) {
switch(this.data[i].installed) this.element.removeChild(this.element.children[0]);
{
case 'True':
this.install_buttons[i].innerHTML = 'Installed';
this.install_buttons[i].style.backgroundColor = 'green';
this.install_buttons[i].disabled = true;
break;
default:
this.install_buttons[i].innerHTML = 'Install';
this.install_buttons[i].style.backgroundColor = 'black';
this.install_buttons[i].disabled = false;
break;
}
} }
await this.createGrid();
this.createControls();
} }
async createGrid(models_json) { async createGrid(models_json) {
@ -452,15 +616,7 @@ class ModelInstaller extends ComfyDialog {
async show() { async show() {
try { try {
this.clear(); this.invalidateControl();
this.data = (await getModelList()).models;
while (this.element.children.length) {
this.element.removeChild(this.element.children[0]);
}
await this.createGrid();
this.createControls();
this.element.style.display = "block"; this.element.style.display = "block";
} }
catch(exception) { catch(exception) {
@ -469,15 +625,22 @@ class ModelInstaller extends ComfyDialog {
} }
} }
// ----------- // -----------
class ManagerMenuDialog extends ComfyDialog { class ManagerMenuDialog extends ComfyDialog {
static instance = null; static instance = null;
local_mode_checkbox = null;
createButtons() { createButtons() {
this.local_mode_checkbox = $el("input",{type:'checkbox', id:"use_local_db"},[])
const checkbox_text = $el("label",{},["Use local DB"])
checkbox_text.style.color = "var(--fg-color)"
const res = const res =
[ [
$el("tr.td", {width:"100%"}, [$el("font", {size:6, color:"white"}, ["Manager Menu"])]), $el("tr.td", {width:"100%"}, [$el("font", {size:6, color:"white"}, ["Manager Menu"])]),
$el("br", {}, []), $el("br", {}, []),
$el("div", {}, [this.local_mode_checkbox, checkbox_text]),
$el("button", { $el("button", {
type: "button", type: "button",
textContent: "Install Custom Nodes", textContent: "Install Custom Nodes",
@ -500,6 +663,19 @@ class ManagerMenuDialog extends ComfyDialog {
} }
}), }),
$el("br", {}, []),
$el("button", {
type: "button",
textContent: "Alternatives of A1111",
onclick:
() => {
if(!AlternativesInstaller.instance)
AlternativesInstaller.instance = new AlternativesInstaller(app);
AlternativesInstaller.instance.show();
}
}),
$el("br", {}, []),
$el("button", { $el("button", {
type: "button", type: "button",
textContent: "Close", textContent: "Close",
@ -507,7 +683,6 @@ class ManagerMenuDialog extends ComfyDialog {
}) })
]; ];
console.log(res);
res[0].style.backgroundColor = "black"; res[0].style.backgroundColor = "black";
res[0].style.textAlign = "center"; res[0].style.textAlign = "center";
res[0].style.height = "45px"; res[0].style.height = "45px";

Loading…
Cancel
Save