Remade download tab.
This commit is contained in:
26
README.md
26
README.md
@@ -12,22 +12,34 @@ Currently it is still missing some features it should have.
|
||||
|
||||
## Fork Improvements
|
||||
|
||||
### Download Tab
|
||||
|
||||
- Remade download tab.
|
||||
- View multiple models connected to url.
|
||||
- Download preview images.
|
||||
- Civitai and HuggingFace API token configurable in `server_settings.yaml`.
|
||||
|
||||
### Models Tab
|
||||
|
||||
- Search bar in models tab.
|
||||
- Advanced keyword search using `"multiple words in quotes"` or a minus sign to `-exclude`.
|
||||
- Search `/`subdirectories of model directories based on your file structure (for example, `/0/1.5/styles/clothing`).
|
||||
- Add `/` at the start of the search bar to see auto-complete suggestions.
|
||||
- Include models listed in ComfyUI's `extra_model_paths.yaml` or added in `ComfyUI/models`.
|
||||
- Sort for models (Date Created, Date Modified, Name).
|
||||
|
||||
### ComfyUI Node Graph
|
||||
|
||||
- Button to copy a model to the ComfyUI clipboard or embedding to system clipboard. (Embedding copying requires secure http connection.)
|
||||
- Button to add model to ComfyUI graph or embedding to selected nodes. (For small screens/low resolution.)
|
||||
- Right, left, top and bottom toggleable sidebar modes.
|
||||
- Drag a model onto the graph to add a new node.
|
||||
- Drag a model onto an existing node to set the model field.
|
||||
- Drag an embedding onto a text area to add it to the end.
|
||||
- Increased supported preview image types.
|
||||
|
||||
### Settings Tab
|
||||
|
||||
- Correctly change colors using ComfyUI's theme colors.
|
||||
- Simplified UI.
|
||||
- Civitai and HuggingFace API token configurable in `server_settings.yaml`.
|
||||
- Settings tab saved in `ui_settings.yaml`.
|
||||
- Hide/Show 'add' and 'copy-to-clipboard' buttons.
|
||||
- Text to always search.
|
||||
@@ -89,11 +101,3 @@ Currently it is still missing some features it should have.
|
||||
### Sidebar
|
||||
|
||||
- ☐ Drag sidebar width/height dynamically.
|
||||
|
||||
### Directory Browser and Downloading tab
|
||||
|
||||
(NOTE: It is a impossible to put a model automatically in the correct folder if model type information is not given or ambigious. To fully solve this requires making a file browser where files can be moved around.)
|
||||
|
||||
- ☐ Replace Install tab with Downloading tab (more practical IMO).
|
||||
- ☐ Download a model from a url.
|
||||
- ☐ Choose save path/directory to download within vaild model directories. (Alert Yes/No if need to create new dirs?)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.comfy-grid .item {
|
||||
.model-manager .item {
|
||||
position: relative;
|
||||
width: 230px;
|
||||
height: 345px;
|
||||
@@ -64,12 +64,29 @@
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.comfy-grid .item img {
|
||||
.model-manager .item img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.model-manager .model-preview-button-left,
|
||||
.model-manager .model-preview-button-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.model-manager .model-preview-button-right {
|
||||
right: 4px;
|
||||
}
|
||||
|
||||
.model-manager .model-preview-button-left {
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.comfy-grid .model-label {
|
||||
background-color: #000a;
|
||||
width: 100%;
|
||||
@@ -99,7 +116,7 @@
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.comfy-grid .item .model-preview-overlay {
|
||||
.model-manager .item .model-preview-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -306,13 +323,18 @@
|
||||
}
|
||||
|
||||
.model-manager .row {
|
||||
position: sticky;
|
||||
position: relative;
|
||||
padding-top: 2px;
|
||||
margin-top: -2px;
|
||||
padding-bottom: 18px;
|
||||
margin-bottom: 1px;
|
||||
top: -1px;
|
||||
background-color: var(--comfy-input-bg);
|
||||
}
|
||||
|
||||
.model-manager [data-name="Install"] .row,
|
||||
.model-manager [data-name="Models"] .row {
|
||||
position: sticky;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -347,9 +369,15 @@
|
||||
}
|
||||
|
||||
.model-manager .search-text-area,
|
||||
.model-manager .source-text-area,
|
||||
.model-manager .plain-text-area,
|
||||
.model-manager .model-select-dropdown {
|
||||
flex: 1;
|
||||
min-height: 36px;
|
||||
padding-block: 0;
|
||||
}
|
||||
|
||||
.model-manager .model-select-dropdown {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.model-manager .search-dropdown {
|
||||
@@ -424,3 +452,12 @@
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.model-manager [data-name="Download"] summary {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.model-manager .download-details {
|
||||
border-radius: 16px;
|
||||
padding: 0px 16px 0px 16px;
|
||||
}
|
||||
@@ -1439,10 +1439,10 @@ class ModelManager extends ComfyDialog {
|
||||
]
|
||||
),
|
||||
$tabs([
|
||||
$tab("Install", this.#createSourceInstall()),
|
||||
$tab("Download", [this.#downloadTab_new()]),
|
||||
//$tab("Install", this.#createSourceInstall()),
|
||||
$tab("Models", this.#modelTab_new()),
|
||||
$tab("Settings", [this.#settingsTab_new()]),
|
||||
//$tab("Download2", [this.#downloadTab_new()]),
|
||||
]),
|
||||
]),
|
||||
]
|
||||
@@ -1453,7 +1453,7 @@ class ModelManager extends ComfyDialog {
|
||||
|
||||
#init() {
|
||||
this.#settingsTab_reload(false);
|
||||
this.#refreshSourceList();
|
||||
//this.#refreshSourceList();
|
||||
this.#modelTab_updateModels();
|
||||
}
|
||||
|
||||
@@ -1471,7 +1471,7 @@ class ModelManager extends ComfyDialog {
|
||||
$: (el) => (this.#el.loadSourceBtn = el),
|
||||
onclick: () => this.#refreshSourceList(),
|
||||
}),
|
||||
$el("input.source-text-area", {
|
||||
$el("input.plain-text-area", {
|
||||
$: (el) => (this.#el.loadSourceFromInput = el),
|
||||
placeholder: "https://ComfyUI-Model-Manager/index.json",
|
||||
}),
|
||||
@@ -1718,7 +1718,7 @@ class ModelManager extends ComfyDialog {
|
||||
|
||||
if (reloadData) {
|
||||
// Is this slow?
|
||||
this.#refreshSourceList();
|
||||
//this.#refreshSourceList();
|
||||
this.#modelTab_updateModels();
|
||||
}
|
||||
}
|
||||
@@ -1940,11 +1940,11 @@ class ModelManager extends ComfyDialog {
|
||||
* @param {String[]} modelTypes
|
||||
* @param {DirectoryItem[]} modelDirectories
|
||||
* @param {String} sep
|
||||
* @param {int} id
|
||||
* @returns {HTMLDivElement}
|
||||
*/
|
||||
#downloadTab_modelInfo(info, modelTypes, modelDirectories, sep) {
|
||||
#downloadTab_modelInfo(info, modelTypes, modelDirectories, sep, id) {
|
||||
// TODO: use passed in info
|
||||
const RADIO_MODEL_PREVIEW_GROUP_NAME = "model-download-info-preview-model";
|
||||
const RADIO_MODEL_PREVIEW_DEFAULT = "Default Preview";
|
||||
const RADIO_MODEL_PREVIEW_CUSTOM = "Custom Preview Url";
|
||||
|
||||
@@ -1962,14 +1962,14 @@ class ModelManager extends ComfyDialog {
|
||||
filename: null,
|
||||
};
|
||||
|
||||
$el("input", {
|
||||
$el("input.search-text-area", {
|
||||
$: (el) => (els.saveDirectoryPath = el),
|
||||
type: "text",
|
||||
placeholder: "/0",
|
||||
value: "/0",
|
||||
});
|
||||
|
||||
$el("select", {
|
||||
$el("select.model-select-dropdown", {
|
||||
$: (el) => (els.modelTypeSelect = el),
|
||||
}, (() => {
|
||||
const options = [$el("option", { value: "" }, ["-- Model Type --"])];
|
||||
@@ -1997,172 +1997,208 @@ class ModelManager extends ComfyDialog {
|
||||
true,
|
||||
);
|
||||
|
||||
const radioGroupName = "model-download-info-preview-model" + "-" + id;
|
||||
const radioGroup = $radioGroup({
|
||||
name: radioGroupName,
|
||||
onchange: (value) => {
|
||||
switch (value) {
|
||||
case RADIO_MODEL_PREVIEW_DEFAULT:
|
||||
const bottonStyleDisplay = els.previewImgs.children.length > 1 ? "block" : "none";
|
||||
els.buttonLeft.style.display = bottonStyleDisplay;
|
||||
els.buttonRight.style.display = bottonStyleDisplay;
|
||||
els.modelPreviewContainer.style.display = "block";
|
||||
els.customPreviewContainer.style.display = "none";
|
||||
break;
|
||||
case RADIO_MODEL_PREVIEW_CUSTOM:
|
||||
els.modelPreviewContainer.style.display = "none";
|
||||
els.customPreviewContainer.style.display = "flex";
|
||||
break;
|
||||
default:
|
||||
els.modelPreviewContainer.style.display = "none";
|
||||
els.customPreviewContainer.style.display = "none";
|
||||
break;
|
||||
}
|
||||
},
|
||||
options: (() => {
|
||||
const radios = [];
|
||||
radios.push({ value: "No Preview" });
|
||||
if (info["images"].length > 0) {
|
||||
radios.push({ value: RADIO_MODEL_PREVIEW_DEFAULT });
|
||||
}
|
||||
radios.push({ value: RADIO_MODEL_PREVIEW_CUSTOM });
|
||||
return radios;
|
||||
})(),
|
||||
});
|
||||
|
||||
const filepath = info["downloadFilePath"];
|
||||
const modelInfo = $el("details", [
|
||||
const modelInfo = $el("details.download-details", [
|
||||
$el("summary", [filepath + info["fileName"]]),
|
||||
$el("div", [
|
||||
$el("div", [
|
||||
$el("button", {
|
||||
onclick: async (e) => {
|
||||
const record = {};
|
||||
record["download"] = info["downloadUrl"];
|
||||
record["type"] = els.modelTypeSelect.value;
|
||||
if (record["type"] === "") { return; } // TODO: notify user in app
|
||||
record["path"] = els.saveDirectoryPath.value;
|
||||
if (record["path"] === "/") { return; } // TODO: notify user in app
|
||||
record["name"] = (() => {
|
||||
const filename = info["fileName"];
|
||||
const name = els.filename.value;
|
||||
if (name === "") {
|
||||
return filename;
|
||||
}
|
||||
const ext = MODEL_EXTENSIONS.find((ext) => {
|
||||
return filename.endsWith(ext);
|
||||
}) ?? "";
|
||||
return name + ext;
|
||||
})();
|
||||
record["image"] = (() => {
|
||||
const value = document.querySelector(`input[name="${RADIO_MODEL_PREVIEW_GROUP_NAME}"]:checked`).value;
|
||||
switch (value) {
|
||||
case RADIO_MODEL_PREVIEW_DEFAULT:
|
||||
const children = els.previewImgs.children;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
if (child.style.display !== "none") {
|
||||
return child.src;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
case RADIO_MODEL_PREVIEW_CUSTOM:
|
||||
return els.customPreviewUrl.value;
|
||||
}
|
||||
return "";
|
||||
})();
|
||||
record["overwrite"] = true; // TODO: add to UI
|
||||
e.disabled = true;
|
||||
await request(
|
||||
"/model-manager/download",
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(record),
|
||||
}
|
||||
).then(data => {
|
||||
if (data["success"] !== true) {
|
||||
// TODO: notify user in app
|
||||
console.error('Failed to download model:', data);
|
||||
}
|
||||
}).catch(err => {
|
||||
// TODO: notify user in app
|
||||
console.error('Failed to download model:', err);
|
||||
$el("div", {
|
||||
style: { display: "flex", gap: "16px" },
|
||||
}, [
|
||||
$el("div.item", {
|
||||
$: (el) => (els.modelPreviewContainer = el),
|
||||
style: { display: "none" },
|
||||
}, [
|
||||
$el("div", {
|
||||
$: (el) => (els.previewImgs = el),
|
||||
}, (() => {
|
||||
const imgs = info["images"].map((url) => {
|
||||
return $el("img", {
|
||||
src: url,
|
||||
style: { display: "none" },
|
||||
loading: "lazy",
|
||||
});
|
||||
e.disabled = false;
|
||||
},
|
||||
}, ["Download"]),
|
||||
els.modelTypeSelect,
|
||||
$el("div", [
|
||||
els.saveDirectoryPath,
|
||||
searchDropdown.element,
|
||||
});
|
||||
if (imgs.length > 0) {
|
||||
imgs[0].style.display = "block";
|
||||
}
|
||||
return imgs;
|
||||
})()),
|
||||
$el("div.model-preview-overlay", [
|
||||
$el("button.icon-button.model-preview-button-left", {
|
||||
$: (el) => (els.buttonLeft = el),
|
||||
onclick: () => ModelManager.#downloadTab_updatePreview(els.previewImgs, -1),
|
||||
textContent: "←",
|
||||
}),
|
||||
$el("button.icon-button.model-preview-button-right", {
|
||||
$: (el) => (els.buttonRight = el),
|
||||
onclick: () => ModelManager.#downloadTab_updatePreview(els.previewImgs, 1),
|
||||
textContent: "→",
|
||||
}),
|
||||
]),
|
||||
$el("input", {
|
||||
$: (el) => (els.filename = el),
|
||||
type: "text",
|
||||
placeholder: (() => {
|
||||
const filename = info["fileName"];
|
||||
// TODO: only remove valid model file extensions
|
||||
const i = filename.lastIndexOf(".");
|
||||
return i === - 1 ? filename : filename.substring(0, i);
|
||||
})(),
|
||||
}),
|
||||
]),
|
||||
/*
|
||||
$el("div", (() => {
|
||||
return Object.entries(info["details"]).filter(([, value]) => {
|
||||
return value !== undefined && value !== null;
|
||||
}).map(([key, value]) => {
|
||||
const el = document.createElement("p");
|
||||
el.innerText = key + ": " + value;
|
||||
return el;
|
||||
});
|
||||
})()),
|
||||
*/
|
||||
$el("div.model-preview-select-radio-container", [
|
||||
$radioGroup({
|
||||
name: RADIO_MODEL_PREVIEW_GROUP_NAME,
|
||||
onchange: (value) => {
|
||||
switch (value) {
|
||||
case RADIO_MODEL_PREVIEW_DEFAULT:
|
||||
const bottonStyleDisplay = els.previewImgs.children.length > 1 ? "block" : "none";
|
||||
els.buttonLeft.style.display = bottonStyleDisplay;
|
||||
els.buttonRight.style.display = bottonStyleDisplay;
|
||||
els.modelPreviewContainer.style.display = "block";
|
||||
els.customPreviewContainer.style.display = "none";
|
||||
break;
|
||||
case RADIO_MODEL_PREVIEW_CUSTOM:
|
||||
els.modelPreviewContainer.style.display = "none";
|
||||
els.customPreviewContainer.style.display = "block";
|
||||
break;
|
||||
default:
|
||||
els.modelPreviewContainer.style.display = "none";
|
||||
els.customPreviewContainer.style.display = "none";
|
||||
break;
|
||||
}
|
||||
},
|
||||
options: (() => {
|
||||
const radios = [];
|
||||
radios.push({ value: "No Preview" });
|
||||
if (info["images"].length > 0) {
|
||||
radios.push({ value: RADIO_MODEL_PREVIEW_DEFAULT });
|
||||
}
|
||||
radios.push({ value: RADIO_MODEL_PREVIEW_CUSTOM });
|
||||
return radios;
|
||||
})(),
|
||||
}),
|
||||
$el("div", [
|
||||
$el("div", {
|
||||
$: (el) => (els.modelPreviewContainer = el),
|
||||
style: { display: "none" },
|
||||
}, [
|
||||
$el("div", {
|
||||
$: (el) => (els.previewImgs = el),
|
||||
}, (() => {
|
||||
const imgs = info["images"].map((url) => {
|
||||
return $el("img", {
|
||||
src: url,
|
||||
style: { display: "none" },
|
||||
loading: "lazy",
|
||||
});
|
||||
});
|
||||
if (imgs.length > 0) {
|
||||
imgs[0].style.display = "block";
|
||||
}
|
||||
return imgs;
|
||||
})()),
|
||||
$el("div", [
|
||||
$el("div", {
|
||||
style: { "margin-top": "8px" }
|
||||
}, [
|
||||
$el("div.model-preview-select-radio-container", [
|
||||
$el("div.row.tab-header-flex-block", [radioGroup]),
|
||||
$el("div", [
|
||||
$el("button", {
|
||||
$: (el) => (els.buttonLeft = el),
|
||||
onclick: () => ModelManager.#downloadTab_updatePreview(els.previewImgs, -1),
|
||||
}, ["LEFT"]),
|
||||
$el("button", {
|
||||
$: (el) => (els.buttonRight = el),
|
||||
onclick: () => ModelManager.#downloadTab_updatePreview(els.previewImgs, 1),
|
||||
}, ["RIGHT"]),
|
||||
$el("div.row.tab-header-flex-block", {
|
||||
$: (el) => (els.customPreviewContainer = el),
|
||||
style: { display: "none" },
|
||||
}, [
|
||||
$el("input.search-text-area", {
|
||||
$: (el) => (els.customPreviewUrl = el),
|
||||
type: "text",
|
||||
placeholder: "https://custom-image-preview.png"
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
$el("div", {
|
||||
$: (el) => (els.customPreviewContainer = el),
|
||||
style: { display: "none" },
|
||||
}, [
|
||||
$el("input.search-text-area", {
|
||||
$: (el) => (els.customPreviewUrl = el),
|
||||
$el("div.row.tab-header-flex-block", [
|
||||
els.modelTypeSelect,
|
||||
]),
|
||||
$el("div.row.tab-header-flex-block", [
|
||||
els.saveDirectoryPath,
|
||||
searchDropdown.element,
|
||||
]),
|
||||
$el("div.row.tab-header-flex-block", [
|
||||
$el("button.icon-button", {
|
||||
textContent: "📥︎",
|
||||
onclick: async (e) => {
|
||||
const record = {};
|
||||
record["download"] = info["downloadUrl"];
|
||||
record["type"] = els.modelTypeSelect.value;
|
||||
if (record["type"] === "") { return; } // TODO: notify user in app
|
||||
record["path"] = els.saveDirectoryPath.value;
|
||||
if (record["path"] === "/") { return; } // TODO: notify user in app
|
||||
record["name"] = (() => {
|
||||
const filename = info["fileName"];
|
||||
const name = els.filename.value;
|
||||
if (name === "") {
|
||||
return filename;
|
||||
}
|
||||
const ext = MODEL_EXTENSIONS.find((ext) => {
|
||||
return filename.endsWith(ext);
|
||||
}) ?? "";
|
||||
return name + ext;
|
||||
})();
|
||||
record["image"] = (() => {
|
||||
const value = document.querySelector(`input[name="${radioGroupName}"]:checked`).value;
|
||||
switch (value) {
|
||||
case RADIO_MODEL_PREVIEW_DEFAULT:
|
||||
const children = els.previewImgs.children;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
if (child.style.display !== "none") {
|
||||
return child.src;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
case RADIO_MODEL_PREVIEW_CUSTOM:
|
||||
return els.customPreviewUrl.value;
|
||||
}
|
||||
return "";
|
||||
})();
|
||||
record["overwrite"] = false; // TODO: add to UI
|
||||
e.target.disabled = true;
|
||||
let success = true;
|
||||
let resultText = "✔";
|
||||
await request(
|
||||
"/model-manager/download",
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(record),
|
||||
}
|
||||
).then(data => {
|
||||
if (data["success"] !== true) {
|
||||
// TODO: notify user in app
|
||||
console.error('Failed to download model:', data);
|
||||
success = false;
|
||||
resultText = "📥︎";
|
||||
}
|
||||
}).catch(err => {
|
||||
// TODO: notify user in app
|
||||
console.error('Failed to download model:', err);
|
||||
success = false;
|
||||
resultText = "📥︎";
|
||||
});
|
||||
buttonAlert(e.target, success, "✔", "✖", resultText);
|
||||
e.target.disabled = success;
|
||||
},
|
||||
}),
|
||||
$el("input.plain-text-area", {
|
||||
$: (el) => (els.filename = el),
|
||||
type: "text",
|
||||
placeholder: "(preview image url)"
|
||||
placeholder: (() => {
|
||||
const filename = info["fileName"];
|
||||
// TODO: only remove valid model file extensions
|
||||
const i = filename.lastIndexOf(".");
|
||||
return i === - 1 ? filename : filename.substring(0, i);
|
||||
})(),
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
/*
|
||||
$el("div", (() => {
|
||||
return Object.entries(info["details"]).filter(([, value]) => {
|
||||
return value !== undefined && value !== null;
|
||||
}).map(([key, value]) => {
|
||||
const el = document.createElement("p");
|
||||
el.innerText = key + ": " + value;
|
||||
return el;
|
||||
});
|
||||
})()),
|
||||
*/
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
|
||||
if (info["images"].length > 0) {
|
||||
const children = radioGroup.children;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
const radioButton = child.children[0];
|
||||
if (radioButton.value === RADIO_MODEL_PREVIEW_DEFAULT) {
|
||||
els.modelPreviewContainer.style.display = "block";
|
||||
radioButton.checked = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const modelTypeSelect = els.modelTypeSelect;
|
||||
modelTypeSelect.selectedIndex = 0; // reset
|
||||
const comfyUIModelType = (
|
||||
@@ -2257,12 +2293,13 @@ class ModelManager extends ComfyDialog {
|
||||
return MODEL_EXTENSIONS.find((ext) => {
|
||||
return filename.endsWith(ext);
|
||||
}) ?? false;
|
||||
}).map((modelInfo) => {
|
||||
}).map((modelInfo, id) => {
|
||||
return this.#downloadTab_modelInfo(
|
||||
modelInfo,
|
||||
modelTypes,
|
||||
this.#data.modelDirectories,
|
||||
this.#sep,
|
||||
id,
|
||||
);
|
||||
});
|
||||
if (modelInfos.length === 0) {
|
||||
@@ -2279,11 +2316,11 @@ class ModelManager extends ComfyDialog {
|
||||
*/
|
||||
#downloadTab_new() {
|
||||
return $el("div", [
|
||||
$el("div", [
|
||||
$el("div.row.tab-header-flex-block", [
|
||||
$el("input.search-text-area", {
|
||||
$: (el) => (this.#el.modelInfoUrl = el),
|
||||
type: "text",
|
||||
placeholder: "Civitai or HuggingFace model",
|
||||
placeholder: "example: https://civitai.com/models/207992/stable-video-diffusion-svd",
|
||||
onkeydown: (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.stopPropagation();
|
||||
@@ -2291,13 +2328,16 @@ class ModelManager extends ComfyDialog {
|
||||
}
|
||||
},
|
||||
}),
|
||||
$el("button", {
|
||||
$el("button.icon-button", {
|
||||
onclick: () => this.#downloadTab_search(),
|
||||
}, ["Search"]),
|
||||
textContent: "🔍︎",
|
||||
}),
|
||||
]),
|
||||
$el("div", {
|
||||
$: (el) => (this.#el.modelInfos = el),
|
||||
}),
|
||||
}, [
|
||||
$el("div", ["Input a URL to view download settings."]),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user