Remove model type selection in Download Tab.

- Refactored Directory Dropdown update.
This commit is contained in:
Christian Bastian
2024-03-30 01:58:02 -04:00
parent 581d8f4a26
commit 2eba51c668
2 changed files with 63 additions and 98 deletions

View File

@@ -105,10 +105,9 @@ def folder_paths_get_supported_pt_extensions(folder_name, refresh = False): # Mi
def search_path_to_system_path(model_path): def search_path_to_system_path(model_path):
sep = os.path.sep sep = os.path.sep
model_path = os.path.normpath(model_path.replace("/", sep)) model_path = os.path.normpath(model_path.replace("/", sep))
model_path = model_path.lstrip(sep)
isep0 = 0 if model_path[0] == sep else -1 isep1 = model_path.find(sep, 0)
isep1 = model_path.find(sep, isep0 + 1)
if isep1 == -1 or isep1 == len(model_path): if isep1 == -1 or isep1 == len(model_path):
return (None, None) return (None, None)
@@ -116,7 +115,7 @@ def search_path_to_system_path(model_path):
if isep2 == -1 or isep2 - isep1 == 1: if isep2 == -1 or isep2 - isep1 == 1:
isep2 = len(model_path) isep2 = len(model_path)
model_path_type = model_path[isep0 + 1:isep1] model_path_type = model_path[0:isep1]
paths = folder_paths_get_folder_paths(model_path_type) paths = folder_paths_get_folder_paths(model_path_type)
if len(paths) == 0: if len(paths) == 0:
return (None, None) return (None, None)

View File

@@ -655,9 +655,8 @@ class DirectoryDropdown {
/** @type {HTMLInputElement} */ /** @type {HTMLInputElement} */
#input = null; #input = null;
// TODO: remove this /** @type {() => string} */
/** @type {() => void} */ #getModelType = null;
#updateDropdown = null;
/** @type {ModelData} */ /** @type {ModelData} */
#modelData = null; // READ ONLY #modelData = null; // READ ONLY
@@ -668,15 +667,21 @@ class DirectoryDropdown {
/** @type {() => Promise<void>} */ /** @type {() => Promise<void>} */
#submitCallback = null; #submitCallback = null;
/** @type {string} */
#currentPath = "/";
/** @type {string} */
#deepestPreviousPath = "/";
/** /**
* @param {ModelData} modelData * @param {ModelData} modelData
* @param {HTMLInputElement} input * @param {HTMLInputElement} input
* @param {() => void} updateDropdown * @param {Boolean} [showDirectoriesOnly=false]
* @param {() => string} [getModelType= () => { return ""; }]
* @param {() => void} [updateCallback= () => {}] * @param {() => void} [updateCallback= () => {}]
* @param {() => Promise<void>} [submitCallback= () => {}] * @param {() => Promise<void>} [submitCallback= () => {}]
* @param {Boolean} [showDirectoriesOnly=false]
*/ */
constructor(modelData, input, updateDropdown, updateCallback = () => {}, submitCallback = () => {}, showDirectoriesOnly = false) { constructor(modelData, input, showDirectoriesOnly = false, getModelType = () => { return ""; }, updateCallback = () => {}, submitCallback = () => {}) {
/** @type {HTMLDivElement} */ /** @type {HTMLDivElement} */
const dropdown = $el("div.search-dropdown", { // TODO: change to `search-directory-dropdown` const dropdown = $el("div.search-dropdown", { // TODO: change to `search-directory-dropdown`
style: { style: {
@@ -686,13 +691,19 @@ class DirectoryDropdown {
this.element = dropdown; this.element = dropdown;
this.#modelData = modelData; this.#modelData = modelData;
this.#input = input; this.#input = input;
this.#updateDropdown = updateDropdown; this.#getModelType = getModelType;
this.#updateCallback = updateCallback; this.#updateCallback = updateCallback;
this.#submitCallback = submitCallback; this.#submitCallback = submitCallback;
this.showDirectoriesOnly = showDirectoriesOnly; this.showDirectoriesOnly = showDirectoriesOnly;
input.addEventListener("input", () => updateDropdown()); input.addEventListener("input", () => {
input.addEventListener("focus", () => updateDropdown()); this.#update();
updateCallback();
});
input.addEventListener("focus", () => {
this.#update();
updateCallback();
});
input.addEventListener("blur", () => { dropdown.style.display = "none"; }); input.addEventListener("blur", () => { dropdown.style.display = "none"; });
input.addEventListener( input.addEventListener(
"keydown", "keydown",
@@ -722,8 +733,8 @@ class DirectoryDropdown {
e.preventDefault(); // prevent cursor move e.preventDefault(); // prevent cursor move
const input = e.target; const input = e.target;
DirectoryDropdown.selectionToInput(input, selection, modelData.searchSeparator); DirectoryDropdown.selectionToInput(input, selection, modelData.searchSeparator);
updateDropdown(); this.#update();
//updateCallback(); updateCallback();
//submitCallback(); //submitCallback();
/* /*
const options = dropdown.children; const options = dropdown.children;
@@ -756,8 +767,8 @@ class DirectoryDropdown {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); // prevent cursor move e.preventDefault(); // prevent cursor move
input.value = newFilterText; input.value = newFilterText;
updateDropdown(); this.#update();
//updateCallback(); updateCallback();
//submitCallback(); //submitCallback();
/* /*
const options = dropdown.children; const options = dropdown.children;
@@ -787,7 +798,7 @@ class DirectoryDropdown {
const selection = options[iSelection]; const selection = options[iSelection];
if (selection !== undefined && selection !== null) { if (selection !== undefined && selection !== null) {
DirectoryDropdown.selectionToInput(input, selection, modelData.searchSeparator); DirectoryDropdown.selectionToInput(input, selection, modelData.searchSeparator);
updateDropdown(); this.#update();
updateCallback(); updateCallback();
} }
submitCallback(); submitCallback();
@@ -851,16 +862,13 @@ class DirectoryDropdown {
input.value = previousPath + selectedText; input.value = previousPath + selectedText;
} }
/** #update() {
* @param {string} [modelType = ""]
*/
update(modelType = "") {
// TODO: create a wrapper around ModelData.directories to make access easier // TODO: create a wrapper around ModelData.directories to make access easier
const directories = this.#modelData.directories; const directories = this.#modelData.directories;
const searchSeparator = this.#modelData.searchSeparator; const searchSeparator = this.#modelData.searchSeparator;
const dropdown = this.element; const dropdown = this.element;
const input = this.#input; const input = this.#input;
const updateDropdown = this.#updateDropdown; const modelType = this.#getModelType();
const updateCallback = this.#updateCallback; const updateCallback = this.#updateCallback;
const submitCallback = this.#submitCallback; const submitCallback = this.#submitCallback;
const showDirectoriesOnly = this.showDirectoriesOnly; const showDirectoriesOnly = this.showDirectoriesOnly;
@@ -930,10 +938,15 @@ class DirectoryDropdown {
} }
let options = []; let options = [];
const lastWord = filter.substring(indexLastWord); let indexPathEnd = indexLastWord;
const item = directories[cwd]; {
const cwdIsDir = item["childIndex"] !== undefined; const lastWord = filter.substring(indexLastWord);
if (cwdIsDir) { const item = directories[cwd];
if (item["childIndex"] === undefined) {
dropdown.style.display = "none";
return;
}
const childIndex = item["childIndex"]; const childIndex = item["childIndex"];
const childCount = item["childCount"]; const childCount = item["childCount"];
const children = directories.slice(childIndex, childIndex + childCount); const children = directories.slice(childIndex, childIndex + childCount);
@@ -962,19 +975,21 @@ class DirectoryDropdown {
if (itemName.startsWith(lastWord)) { if (itemName.startsWith(lastWord)) {
options.push(itemName + (isDir && grandChildCount > 0 ? searchSeparator : "")); options.push(itemName + (isDir && grandChildCount > 0 ? searchSeparator : ""));
} }
if (!isDir && itemName == lastWord) {
indexPathEnd += searchSeparator.length + itemName.length + 1;
}
} }
} }
} }
else if (!showDirectoriesOnly) {
const filename = item["name"];
if (filename.startsWith(lastWord)) {
options.push(filename);
}
}
if (options.length === 0) { if (options.length === 0) {
dropdown.style.display = "none"; dropdown.style.display = "none";
return; return;
} }
const path = filter.substring(0, indexPathEnd);
this.#currentPath = path;
if (!this.#deepestPreviousPath.startsWith(path)) {
this.#deepestPreviousPath = path;
}
const selection_select = (e) => { const selection_select = (e) => {
const selection = e.target; const selection = e.target;
@@ -999,7 +1014,7 @@ class DirectoryDropdown {
e.stopPropagation(); e.stopPropagation();
const selection = e.target; const selection = e.target;
DirectoryDropdown.selectionToInput(input, selection, searchSeparator); DirectoryDropdown.selectionToInput(input, selection, searchSeparator);
updateDropdown(); this.#update();
updateCallback(); updateCallback();
submitCallback(); submitCallback();
}; };
@@ -1443,14 +1458,9 @@ class ModelInfoView {
value: modelData.searchSeparator, value: modelData.searchSeparator,
}); });
/** @type {DirectoryDropdown} */ const searchDropdown = new DirectoryDropdown(
let searchDropdown = null;
searchDropdown = new DirectoryDropdown(
modelData, modelData,
moveDestinationInput, moveDestinationInput,
() => searchDropdown.update(),
() => {},
() => {},
true, true,
); );
@@ -2138,47 +2148,34 @@ class DownloadTab {
/** /**
* @param {Object} info * @param {Object} info
* @param {String[]} modelTypes
* @param {ModelData} modelData * @param {ModelData} modelData
* @param {int} id * @param {int} id
* @returns {HTMLDivElement} * @returns {HTMLDivElement}
*/ */
#modelInfo(info, modelTypes, modelData, id) { #modelInfo(info, modelData, id) {
const downloadPreviewSelect = new ImageSelect( const downloadPreviewSelect = new ImageSelect(
"model-download-info-preview-model" + "-" + id, "model-download-info-preview-model" + "-" + id,
info["images"], info["images"],
); );
const el_modelTypeSelect = $el("select.model-select-dropdown", { const comfyUIModelType = (
name: "model select dropdown", DownloadTab.modelTypeToComfyUiDirectory(info["details"]["fileType"]) ??
}, (() => { DownloadTab.modelTypeToComfyUiDirectory(info["modelType"]) ??
const options = [$el("option", { value: "" }, ["-- Model Type --"])]; ""
modelTypes.forEach((modelType) => { );
options.push($el("option", { value: modelType }, [modelType]));
});
return options;
})());
const searchSeparator = modelData.searchSeparator; const searchSeparator = modelData.searchSeparator;
const defaultBasePath = searchSeparator + (comfyUIModelType === "" ? "" : comfyUIModelType + searchSeparator + "0");
const el_saveDirectoryPath = $el("input.search-text-area", { const el_saveDirectoryPath = $el("input.search-text-area", {
type: "text", type: "text",
name: "save directory", name: "save directory",
autocomplete: "off", autocomplete: "off",
placeholder: searchSeparator + "0", placeholder: defaultBasePath,
value: searchSeparator + "0", value: defaultBasePath,
}); });
/** @type {DirectoryDropdown} */ const searchDropdown = new DirectoryDropdown(
let searchDropdown = null;
searchDropdown = new DirectoryDropdown(
modelData, modelData,
el_saveDirectoryPath, el_saveDirectoryPath,
() => {
const modelType = el_modelTypeSelect.value;
if (modelType === "") { return; }
searchDropdown.update(modelType);
},
() => {},
() => {},
true, true,
); );
@@ -2207,9 +2204,6 @@ class DownloadTab {
$el("div", { $el("div", {
style: { "margin-top": "8px" } style: { "margin-top": "8px" }
}, [ }, [
$el("div.row.tab-header-flex-block", [
el_modelTypeSelect,
]),
$el("div.row.tab-header-flex-block", [ $el("div.row.tab-header-flex-block", [
el_saveDirectoryPath, el_saveDirectoryPath,
searchDropdown.element, searchDropdown.element,
@@ -2220,11 +2214,7 @@ class DownloadTab {
onclick: async (e) => { onclick: async (e) => {
const formData = new FormData(); const formData = new FormData();
formData.append("download", info["downloadUrl"]); formData.append("download", info["downloadUrl"]);
formData.append("path", formData.append("path", el_saveDirectoryPath.value);
el_modelTypeSelect.value +
searchSeparator + // NOTE: this may add multiple separators (server should handle carefully)
el_saveDirectoryPath.value
);
formData.append("name", (() => { formData.append("name", (() => {
const filename = info["fileName"]; const filename = info["fileName"];
const name = el_filename.value; const name = el_filename.value;
@@ -2270,23 +2260,6 @@ class DownloadTab {
]), ]),
]); ]);
el_modelTypeSelect.selectedIndex = 0; // reset
const comfyUIModelType = (
DownloadTab.modelTypeToComfyUiDirectory(info["details"]["fileType"]) ??
DownloadTab.modelTypeToComfyUiDirectory(info["modelType"]) ??
null
);
if (comfyUIModelType !== undefined && comfyUIModelType !== null) {
const modelTypeOptions = el_modelTypeSelect.children;
for (let i = 0; i < modelTypeOptions.length; i++) {
const option = modelTypeOptions[i];
if (option.value === comfyUIModelType) {
el_modelTypeSelect.selectedIndex = i;
break;
}
}
}
return modelInfo; return modelInfo;
} }
@@ -2369,7 +2342,6 @@ class DownloadTab {
return []; return [];
})(); })();
const modelTypes = Object.keys(modelData.models);
const modelInfosHtml = modelInfos.filter((modelInfo) => { const modelInfosHtml = modelInfos.filter((modelInfo) => {
const filename = modelInfo["fileName"]; const filename = modelInfo["fileName"];
return MODEL_EXTENSIONS.find((ext) => { return MODEL_EXTENSIONS.find((ext) => {
@@ -2378,7 +2350,6 @@ class DownloadTab {
}).map((modelInfo, id) => { }).map((modelInfo, id) => {
return this.#modelInfo( return this.#modelInfo(
modelInfo, modelInfo,
modelTypes,
modelData, modelData,
id, id,
); );
@@ -2502,11 +2473,6 @@ class ModelTab {
this.previousModelFilters[modelType] = value; this.previousModelFilters[modelType] = value;
}; };
const updateDirectoryDropdown = () => {
this.directoryDropdown.update(this.elements.modelTypeSelect.value);
updatePreviousModelFilter();
}
/** /**
* @param {string} searchPath * @param {string} searchPath
*/ */
@@ -2542,10 +2508,10 @@ class ModelTab {
const searchDropdown = new DirectoryDropdown( const searchDropdown = new DirectoryDropdown(
modelData, modelData,
searchInput, searchInput,
updateDirectoryDropdown, false,
() => { return this.elements.modelTypeSelect.value; },
updatePreviousModelFilter, updatePreviousModelFilter,
updateModelGrid, updateModelGrid,
false,
); );
this.directoryDropdown = searchDropdown; this.directoryDropdown = searchDropdown;