Up/Down arrow + enter select in directory suggestion; Escape key escape
This commit is contained in:
@@ -362,7 +362,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.model-manager .search-dropdown > p {
|
.model-manager .search-dropdown > p {
|
||||||
margin-left: 20px;
|
margin: 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-top: 0.85em;
|
||||||
|
padding-bottom: 0.85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-manager .search-dropdown > p.search-dropdown-selected {
|
||||||
|
background-color: var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-manager .button-success {
|
.model-manager .button-success {
|
||||||
|
|||||||
@@ -55,9 +55,8 @@ const modelNodeType = {
|
|||||||
* @param {string} modelType
|
* @param {string} modelType
|
||||||
* @param {string} filter
|
* @param {string} filter
|
||||||
*/
|
*/
|
||||||
function updateDirectorySuggestionDropdown(dropdown, directories, modelType, filter) {
|
function updateDirectorySuggestionDropdown(dropdown, directories, modelType, filter, sep) {
|
||||||
let options = [];
|
let options = [];
|
||||||
const sep = "/";
|
|
||||||
if (filter[0] === sep) {
|
if (filter[0] === sep) {
|
||||||
let cwd = null;
|
let cwd = null;
|
||||||
const root = directories[0];
|
const root = directories[0];
|
||||||
@@ -134,7 +133,9 @@ function updateDirectorySuggestionDropdown(dropdown, directories, modelType, fil
|
|||||||
}
|
}
|
||||||
|
|
||||||
const innerHtml = options.map((text) => {
|
const innerHtml = options.map((text) => {
|
||||||
return $el("p", [text]);
|
const p = $el("p", [text]);
|
||||||
|
//p.onclick = (e) => { console.log(e.target); }; // TODO: Click on dropdown elements when input gets blurred?
|
||||||
|
return p;
|
||||||
});
|
});
|
||||||
dropdown.innerHTML = "";
|
dropdown.innerHTML = "";
|
||||||
dropdown.append.apply(dropdown, innerHtml);
|
dropdown.append.apply(dropdown, innerHtml);
|
||||||
@@ -709,44 +710,46 @@ function $radioGroup(attr) {
|
|||||||
|
|
||||||
class ModelManager extends ComfyDialog {
|
class ModelManager extends ComfyDialog {
|
||||||
#el = {
|
#el = {
|
||||||
loadSourceBtn: null,
|
/** @type {HTMLButtonElement} */ loadSourceBtn: null,
|
||||||
loadSourceFromInput: null,
|
/** @type {HTMLInputElement} */ loadSourceFromInput: null,
|
||||||
sourceInstalledFilter: null,
|
/** @type {HTMLSelectElement} */ sourceInstalledFilter: null,
|
||||||
sourceContentFilter: null,
|
/** @type {HTMLInputElement} */ sourceContentFilter: null,
|
||||||
sourceFilterBtn: null,
|
|
||||||
|
|
||||||
modelGrid: null,
|
/** @type {HTMLDivElement} */ modelGrid: null,
|
||||||
modelTypeSelect: null,
|
/** @type {HTMLSelectElement} */ modelTypeSelect: null,
|
||||||
modelDirectorySearchOptions: null,
|
/** @type {HTMLDivElement} */ modelDirectorySearchOptions: null,
|
||||||
modelContentFilter: null,
|
/** @type {HTMLInputElement} */ modelContentFilter: null,
|
||||||
|
|
||||||
sidebarButtons: null,
|
/** @type {HTMLDivElement} */ sidebarButtons: null,
|
||||||
|
|
||||||
settingsTab: null,
|
/** @type {HTMLDivElement} */ settingsTab: null,
|
||||||
reloadSettingsBtn: null,
|
/** @type {HTMLButtonElement} */ reloadSettingsBtn: null,
|
||||||
saveSettingsBtn: null,
|
/** @type {HTMLButtonElement} */ saveSettingsBtn: null,
|
||||||
settings: {
|
settings: {
|
||||||
"sidebar-default-height": null,
|
//"sidebar-default-height": null,
|
||||||
"sidebar-default-width": null,
|
//"sidebar-default-width": null,
|
||||||
"model-search-always-append": null,
|
/** @type {HTMLTextAreaElement} */ "model-search-always-append": null,
|
||||||
"model-persistent-search": null,
|
/** @type {HTMLInputElement} */ "model-persistent-search": null,
|
||||||
"model-show-label-extensions": null,
|
/** @type {HTMLInputElement} */ "model-show-label-extensions": null,
|
||||||
"model-show-add-button": null,
|
/** @type {HTMLInputElement} */ "model-show-add-button": null,
|
||||||
"model-show-copy-button": null,
|
/** @type {HTMLInputElement} */ "model-show-copy-button": null,
|
||||||
"model-add-embedding-extension": null,
|
/** @type {HTMLInputElement} */ "model-add-embedding-extension": null,
|
||||||
"model-add-drag-strict-on-field": null,
|
/** @type {HTMLInputElement} */ "model-add-drag-strict-on-field": null,
|
||||||
"model-add-offset": null,
|
/** @type {HTMLInputElement} */ "model-add-offset": null,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#data = {
|
#data = {
|
||||||
sources: [],
|
/** @type {Array} */ sources: [],
|
||||||
models: {},
|
/** @type {Object} */ models: {},
|
||||||
modelDirectories: null,
|
/** @type {{name: string, childCount: ?int, childIndex: ?int}[]} */ modelDirectories: null,
|
||||||
prevousModelFilters: [],
|
/** @type {Array} */ prevousModelFilters: [],
|
||||||
prevousModelType: undefined,
|
/** @type {string} */ prevousModelType: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
sep = "/";
|
||||||
|
|
||||||
/** @type {SourceList} */
|
/** @type {SourceList} */
|
||||||
#sourceList = null;
|
#sourceList = null;
|
||||||
|
|
||||||
@@ -830,7 +833,7 @@ class ModelManager extends ComfyDialog {
|
|||||||
$el("input.search-text-area", {
|
$el("input.search-text-area", {
|
||||||
$: (el) => (this.#el.sourceContentFilter = el),
|
$: (el) => (this.#el.sourceContentFilter = el),
|
||||||
placeholder: "example: \"sd_xl\" -vae",
|
placeholder: "example: \"sd_xl\" -vae",
|
||||||
onkeyup: (e) => e.key === "Enter" && this.#filterSourceList(),
|
onkeydown: (e) => e.key === "Enter" && this.#filterSourceList(),
|
||||||
}),
|
}),
|
||||||
$el("select",
|
$el("select",
|
||||||
{
|
{
|
||||||
@@ -938,16 +941,19 @@ class ModelManager extends ComfyDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {HTMLElement}
|
* @returns {HTMLElement[]}
|
||||||
*/
|
*/
|
||||||
#createModelTabHtml() {
|
#createModelTabHtml() {
|
||||||
|
/** @type {HTMLDivElement} */
|
||||||
const modelGrid = $el("div.comfy-grid");
|
const modelGrid = $el("div.comfy-grid");
|
||||||
this.#el.modelGrid = modelGrid;
|
this.#el.modelGrid = modelGrid;
|
||||||
|
|
||||||
|
/** @type {HTMLDivElement} */
|
||||||
const searchDropdown = $el("div.search-dropdown", {
|
const searchDropdown = $el("div.search-dropdown", {
|
||||||
$: (el) => (this.#el.modelDirectorySearchOptions = el),
|
$: (el) => (this.#el.modelDirectorySearchOptions = el),
|
||||||
style: { display: "none" },
|
style: { display: "none" },
|
||||||
});
|
});
|
||||||
|
const dropdownSelectClass = "search-dropdown-selected";
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$el("div.row.tab-header", [
|
$el("div.row.tab-header", [
|
||||||
@@ -968,17 +974,71 @@ class ModelManager extends ComfyDialog {
|
|||||||
$el("input.search-text-area", {
|
$el("input.search-text-area", {
|
||||||
$: (el) => (this.#el.modelContentFilter = el),
|
$: (el) => (this.#el.modelContentFilter = el),
|
||||||
placeholder: "example: /0/1.5/styles/clothing -.pt",
|
placeholder: "example: /0/1.5/styles/clothing -.pt",
|
||||||
onkeyup: (e) => {
|
onkeydown: (e) => {
|
||||||
if (e.key === "Enter") {
|
const children = searchDropdown.children;
|
||||||
|
let iChild;
|
||||||
|
for (iChild = 0; iChild < children.length; iChild++) {
|
||||||
|
const child = children[iChild];
|
||||||
|
if (child.classList.contains(dropdownSelectClass)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (iChild < children.length) {
|
||||||
|
const child = children[iChild];
|
||||||
|
child.classList.remove(dropdownSelectClass);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.target.blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.key === "Enter") {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (iChild < children.length) {
|
||||||
|
const child = children[iChild];
|
||||||
|
child.classList.remove(dropdownSelectClass);
|
||||||
|
const selectedText = child.innerText;
|
||||||
|
const filterText = e.target.value;
|
||||||
|
const iSep = filterText.lastIndexOf(this.sep);
|
||||||
|
const previousPath = filterText.substring(0, iSep + 1);
|
||||||
|
e.target.value = previousPath + selectedText;
|
||||||
|
this.#modelUpdateFilterDropdown();
|
||||||
|
}
|
||||||
this.#modelGridUpdate();
|
this.#modelGridUpdate();
|
||||||
searchDropdown.style.display = "none";
|
searchDropdown.style.display = "none";
|
||||||
e.stopPropagation();
|
|
||||||
}
|
}
|
||||||
},
|
else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
||||||
onkeydown: (e) => {
|
|
||||||
if (e.key === "Escape") {
|
|
||||||
e.target.blur();
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
let iNext = children.length;
|
||||||
|
if (iChild < children.length) {
|
||||||
|
const child = children[iChild];
|
||||||
|
child.classList.remove(dropdownSelectClass);
|
||||||
|
const delta = e.key === "ArrowDown" ? 1 : -1;
|
||||||
|
iNext = iChild + delta;
|
||||||
|
if (0 <= iNext && iNext < children.length) {
|
||||||
|
const nextChild = children[iNext];
|
||||||
|
nextChild.classList.add(dropdownSelectClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (iChild === children.length) {
|
||||||
|
iNext = e.key === "ArrowDown" ? 0 : children.length-1;
|
||||||
|
const nextChild = children[iNext]
|
||||||
|
nextChild.classList.add(dropdownSelectClass);
|
||||||
|
}
|
||||||
|
if (0 <= iNext && iNext < children.length) {
|
||||||
|
let scrollTop = searchDropdown.scrollTop;
|
||||||
|
const dropdownHeight = searchDropdown.offsetHeight;
|
||||||
|
const child = children[iNext];
|
||||||
|
const childHeight = child.offsetHeight;
|
||||||
|
const childTop = child.offsetTop;
|
||||||
|
scrollTop = Math.max(scrollTop, childTop - dropdownHeight + childHeight);
|
||||||
|
scrollTop = Math.min(scrollTop, childTop);
|
||||||
|
searchDropdown.scrollTop = scrollTop;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
searchDropdown.scrollTop = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
oninput: () => this.#modelUpdateFilterDropdown(),
|
oninput: () => this.#modelUpdateFilterDropdown(),
|
||||||
@@ -1055,7 +1115,8 @@ class ModelManager extends ComfyDialog {
|
|||||||
this.#el.modelDirectorySearchOptions,
|
this.#el.modelDirectorySearchOptions,
|
||||||
this.#data.modelDirectories,
|
this.#data.modelDirectories,
|
||||||
modelType,
|
modelType,
|
||||||
filter
|
filter,
|
||||||
|
this.sep
|
||||||
);
|
);
|
||||||
this.#data.prevousModelFilters[modelType] = filter;
|
this.#data.prevousModelFilters[modelType] = filter;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user