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:
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,7 +297,7 @@ 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);
|
||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user