HuggingFace download image support.

- Images now appear with HuggingFace links.
- Download inputs fill full width.
- Disabled (annoying) directory auto-suggest dropdown auto-selecting on arrow right or left.
This commit is contained in:
Christian Bastian
2024-02-13 11:30:39 -05:00
parent d4de1da26e
commit 04622b460d
2 changed files with 32 additions and 34 deletions

View File

@@ -457,3 +457,7 @@
.model-manager [data-name="Download"] summary { .model-manager [data-name="Download"] summary {
padding: 16px; padding: 16px;
} }
.model-manager [data-name="Download"] .download-settings {
flex: 1;
}

View File

@@ -56,7 +56,7 @@ const MODEL_SORT_DATE_MODIFIED = "dateModified";
const MODEL_SORT_DATE_NAME = "name"; const MODEL_SORT_DATE_NAME = "name";
const MODEL_EXTENSIONS = [".ckpt", ".pt", ".bin", ".pth", ".safetensors"]; // TODO: ask server for? const MODEL_EXTENSIONS = [".ckpt", ".pt", ".bin", ".pth", ".safetensors"]; // TODO: ask server for?
const IMAGE_EXTENSIONS = [".png", ".webp", ".gif"]; // TODO: ask server for? const IMAGE_EXTENSIONS = [".apng", ".gif", ".jpeg", ".jpg", ".png", ".webp"]; // TODO: ask server for?
/** /**
* Tries to return the related ComfyUI model directory if unambigious. * Tries to return the related ComfyUI model directory if unambigious.
@@ -271,36 +271,25 @@ async function huggingFace_getFilteredInfo(stringUrl) {
const modelId = urlPath.substring(i0, i2); const modelId = urlPath.substring(i0, i2);
const urlPathEnd = urlPath.substring(i2); const urlPathEnd = urlPath.substring(i2);
let branch = null; const isValidBranch = (
if (urlPathEnd.startsWith("/resolve")) { urlPathEnd.startsWith("/resolve") ||
branch = "/resolve"; urlPathEnd.startsWith("/blob") ||
} urlPathEnd.startsWith("/tree")
else if (urlPathEnd.startsWith("/blob")) { );
branch = "/blob";
}
else if (urlPathEnd.startsWith("/tree")) {
branch = "/tree";
}
let branch = "/main";
let filePath = ""; let filePath = "";
if (branch == null) { if (isValidBranch) {
branch = "/tree/main";
}
else {
const i0 = branch.length; const i0 = branch.length;
const i1 = urlPathEnd.indexOf("/", i0 + 1); const i1 = urlPathEnd.indexOf("/", i0 + 1);
if (i1 == -1) { if (i1 == -1) {
if (i0 == urlPathEnd.length) { if (i0 != urlPathEnd.length) {
// ends with '/tree' (invalid?)
branch = "/tree/main";
}
else {
// ends with branch // ends with branch
branch = "/tree" + urlPathEnd.substring(i0); branch = urlPathEnd.substring(i0);
} }
} }
else { else {
branch = "/tree" + urlPathEnd.substring(i0, i1); branch = urlPathEnd.substring(i0, i1);
if (urlPathEnd.length - 1 > i1) { if (urlPathEnd.length - 1 > i1) {
filePath = urlPathEnd.substring(i1); filePath = urlPathEnd.substring(i1);
} }
@@ -308,9 +297,9 @@ async function huggingFace_getFilteredInfo(stringUrl) {
} }
const modelInfo = await huggingFace_requestInfo(modelId); const modelInfo = await huggingFace_requestInfo(modelId);
//const modelInfo = await requestInfo(modelId + branch); // this only gives you the files at the given branch path... //const modelInfo = await requestInfo(modelId + "/tree" + branch); // this only gives you the files at the given branch path...
// oid: SHA-1?, lfs.oid: SHA-256 // oid: SHA-1?, lfs.oid: SHA-256
const clippedFilePath = filePath.substring(filePath[0] === "/" ? 1 : 0); const clippedFilePath = filePath.substring(filePath[0] === "/" ? 1 : 0);
const modelFiles = modelInfo["siblings"].filter((sib) => { const modelFiles = modelInfo["siblings"].filter((sib) => {
const filename = sib["rfilename"]; const filename = sib["rfilename"];
@@ -328,24 +317,24 @@ async function huggingFace_getFilteredInfo(stringUrl) {
return {}; return {};
} }
const imageFiles = modelInfo["siblings"].filter((sib) => { const baseDownloadUrl = url.origin + urlPath.substring(0, i2) + "/resolve" + branch;
const images = modelInfo["siblings"].filter((sib) => {
const filename = sib["rfilename"]; const filename = sib["rfilename"];
for (let i = 0; i < IMAGE_EXTENSIONS.length; i++) { for (let i = 0; i < IMAGE_EXTENSIONS.length; i++) {
if (filename.endsWith(IMAGE_EXTENSIONS[i])) { if (filename.endsWith(IMAGE_EXTENSIONS[i])) {
return filename.startsWith(filePath); return filename.startsWith(clippedFilePath);
} }
} }
return false; return false;
}).map((sib) => { }).map((sib) => {
const filename = sib["rfilename"]; return baseDownloadUrl + "/" + sib["rfilename"];
return filename;
}); });
const baseDownloadUrl = url.origin + urlPath.substring(0, i2) + "/resolve" + branch.replace("/tree", "");
return { return {
"baseDownloadUrl": baseDownloadUrl, "baseDownloadUrl": baseDownloadUrl,
"modelFiles": modelFiles, "modelFiles": modelFiles,
"imageFiles": imageFiles, "images": images,
}; };
} }
@@ -432,11 +421,13 @@ class DirectoryDropdown {
updateDropdown(); updateDropdown();
//updateCallback(); //updateCallback();
//submitCallback(); //submitCallback();
/*
const options = dropdown.children; const options = dropdown.children;
if (options.length > 0) { if (options.length > 0) {
// arrow key navigation // arrow key navigation
options[0].classList.add(DROPDOWN_DIRECTORY_SELECTION_CLASS); options[0].classList.add(DROPDOWN_DIRECTORY_SELECTION_CLASS);
} }
*/
} }
} }
else if (e.key === "ArrowLeft" && dropdown.style.display !== "none") { else if (e.key === "ArrowLeft" && dropdown.style.display !== "none") {
@@ -464,6 +455,7 @@ class DirectoryDropdown {
updateDropdown(); updateDropdown();
//updateCallback(); //updateCallback();
//submitCallback(); //submitCallback();
/*
const options = dropdown.children; const options = dropdown.children;
let isSelected = false; let isSelected = false;
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
@@ -481,6 +473,7 @@ class DirectoryDropdown {
options[0].classList.add(DROPDOWN_DIRECTORY_SELECTION_CLASS); options[0].classList.add(DROPDOWN_DIRECTORY_SELECTION_CLASS);
} }
} }
*/
} }
} }
} }
@@ -1673,8 +1666,9 @@ class ModelManager extends ComfyDialog {
*/ */
#downloadTab_modelInfo(info, modelTypes, modelDirectories, sep, id) { #downloadTab_modelInfo(info, modelTypes, modelDirectories, sep, id) {
// TODO: use passed in info // TODO: use passed in info
const RADIO_MODEL_PREVIEW_NONE = "No Preview";
const RADIO_MODEL_PREVIEW_DEFAULT = "Default Preview"; const RADIO_MODEL_PREVIEW_DEFAULT = "Default Preview";
const RADIO_MODEL_PREVIEW_CUSTOM = "Custom Preview Url"; const RADIO_MODEL_PREVIEW_CUSTOM = "Custom Preview";
const els = { const els = {
modelPreviewContainer: null, modelPreviewContainer: null,
@@ -1749,7 +1743,7 @@ class ModelManager extends ComfyDialog {
}, },
options: (() => { options: (() => {
const radios = []; const radios = [];
radios.push({ value: "No Preview" }); radios.push({ value: RADIO_MODEL_PREVIEW_NONE });
if (info["images"].length > 0) { if (info["images"].length > 0) {
radios.push({ value: RADIO_MODEL_PREVIEW_DEFAULT }); radios.push({ value: RADIO_MODEL_PREVIEW_DEFAULT });
} }
@@ -1800,7 +1794,7 @@ class ModelManager extends ComfyDialog {
}), }),
]), ]),
]), ]),
$el("div", [ $el("div.download-settings", [
$el("div", { $el("div", {
style: { "margin-top": "8px" } style: { "margin-top": "8px" }
}, [ }, [
@@ -2001,7 +1995,7 @@ class ModelManager extends ComfyDialog {
const indexSep = file.lastIndexOf("/"); const indexSep = file.lastIndexOf("/");
const filename = file.substring(indexSep + 1); const filename = file.substring(indexSep + 1);
return { return {
"images": [], // TODO: ambiguous? "images": hfInfo["images"],
"fileName": filename, "fileName": filename,
"modelType": "", "modelType": "",
"downloadUrl": baseDownloadUrl + "/" + file + "?download=true", "downloadUrl": baseDownloadUrl + "/" + file + "?download=true",