Fix functionality of buttons in tabs. add more functions.
This commit is contained in:
parent
fbefe7f4fe
commit
128829817c
|
@ -103,8 +103,6 @@ class ExtraNetworksTab {
|
|||
sort_mode_str = "";
|
||||
sort_dir_str = "";
|
||||
filter_str = "";
|
||||
directory_filter_str = "";
|
||||
directory_filter_recurse = false;
|
||||
show_prompt = true;
|
||||
show_neg_prompt = true;
|
||||
compact_prompt_en = false;
|
||||
|
@ -113,6 +111,8 @@ class ExtraNetworksTab {
|
|||
tree_view_en = false;
|
||||
cards_list_splash_state = null;
|
||||
tree_list_splash_state = null;
|
||||
directory_filters = {};
|
||||
list_button_states = {};
|
||||
constructor({tabname, extra_networks_tabname}) {
|
||||
this.tabname = tabname;
|
||||
this.extra_networks_tabname = extra_networks_tabname;
|
||||
|
@ -188,7 +188,7 @@ class ExtraNetworksTab {
|
|||
|
||||
this.setSortMode(sort_mode_elem.dataset.sortMode);
|
||||
this.setSortDir(sort_dir_elem.dataset.sortDir);
|
||||
this.applyDirectoryFilter();
|
||||
this.applyDirectoryFilters();
|
||||
this.applyFilter();
|
||||
|
||||
this.registerPrompt();
|
||||
|
@ -219,6 +219,8 @@ class ExtraNetworksTab {
|
|||
this.refresh_in_progress = false;
|
||||
this.tree_view_en = false;
|
||||
this.dirs_view_en = false;
|
||||
this.directory_filters = {};
|
||||
this.list_button_states = {};
|
||||
}
|
||||
|
||||
async registerPrompt() {
|
||||
|
@ -285,12 +287,6 @@ class ExtraNetworksTab {
|
|||
this.cards_list.setFilterStr(this.filter_str);
|
||||
}
|
||||
|
||||
setDirectoryFilterStr(filter_str, recurse) {
|
||||
this.directory_filter_str = filter_str;
|
||||
this.directory_filter_recurse = recurse;
|
||||
this.cards_list.setDirectoryFilterStr(this.directory_filter_str, this.directory_filter_recurse);
|
||||
}
|
||||
|
||||
movePrompt(show_prompt = true, show_neg_prompt = true) {
|
||||
// This function only applies when compact prompt mode is enabled.
|
||||
if (!this.compact_prompt_en) {
|
||||
|
@ -402,10 +398,12 @@ class ExtraNetworksTab {
|
|||
this.tree_list.enable(this.tree_view_en);
|
||||
this.cards_list.enable(true);
|
||||
await Promise.all([this.tree_list.load(true), this.cards_list.load(true)]);
|
||||
|
||||
// apply the previous sort/filter options
|
||||
await this.applyListButtonStates();
|
||||
this.setSortMode(this.sort_mode_str);
|
||||
this.setSortDir(this.sort_dir_str);
|
||||
this.applyDirectoryFilter(this.directory_filter_str, this.directory_filter_recurse);
|
||||
this.applyDirectoryFilters();
|
||||
this.applyFilter(this.filter_str);
|
||||
}
|
||||
|
||||
|
@ -437,10 +435,43 @@ class ExtraNetworksTab {
|
|||
this.cards_list.enable(false);
|
||||
}
|
||||
|
||||
applyDirectoryFilter(filter_str, recurse) {
|
||||
addDirectoryFilter(div_id, filter_str, recurse) {
|
||||
filter_str = isString(filter_str) ? filter_str : "";
|
||||
recurse = recurse === true || recurse === false ? recurse : false;
|
||||
this.setDirectoryFilterStr(filter_str, recurse);
|
||||
if (this.cards_list.addDirectoryFilter(div_id, filter_str, recurse)) {
|
||||
this.directory_filters[div_id] = {filter_str: filter_str, recurse: recurse};
|
||||
}
|
||||
}
|
||||
|
||||
removeDirectoryFilter(div_id) {
|
||||
this.cards_list.removeDirectoryFilter(div_id);
|
||||
delete this.directory_filters[div_id];
|
||||
}
|
||||
|
||||
clearDirectoryFilters({excluded_div_ids} = {}) {
|
||||
if (isNumber(excluded_div_ids)) {
|
||||
excluded_div_ids = [excluded_div_ids];
|
||||
}
|
||||
|
||||
if (!Array.isArray(excluded_div_ids)) {
|
||||
excluded_div_ids = [];
|
||||
}
|
||||
|
||||
this.cards_list.clearDirectoryFilters({excluded_div_ids: excluded_div_ids});
|
||||
for (const div_id of Object.keys(this.directory_filters)) {
|
||||
if (excluded_div_ids.includes(div_id)) {
|
||||
continue;
|
||||
}
|
||||
delete this.directory_filters[div_id];
|
||||
}
|
||||
}
|
||||
|
||||
setDirectoryFilters() {
|
||||
this.cards_list.setDirectoryFilters(this.directory_filters);
|
||||
}
|
||||
|
||||
applyDirectoryFilters() {
|
||||
this.cards_list.filterData();
|
||||
}
|
||||
|
||||
applyFilter(filter_str) {
|
||||
|
@ -645,143 +676,150 @@ class ExtraNetworksTab {
|
|||
row.style.gridTemplateColumns = `${max_width}px ${pad}px 1fr`;
|
||||
}
|
||||
|
||||
async setDirectoryButtons({source_elem, source_selector, source_class, reset_all} = {}) {
|
||||
// At least one argument must be specified.
|
||||
if (isNullOrUndefined(source_elem) &&
|
||||
isNullOrUndefined(source_selector) &&
|
||||
isNullOrUndefined(source_class) &&
|
||||
isNullOrUndefined(reset_all)) {
|
||||
console.error("At least one argument must be specified.");
|
||||
return;
|
||||
async clearSelectedButtons({excluded_div_ids} = {}) {
|
||||
/** excluded_elems can be an element or an array of elements. */
|
||||
if (isNumber(excluded_div_ids)) {
|
||||
excluded_div_ids = [excluded_div_ids];
|
||||
}
|
||||
|
||||
// Checks if an element exists and is visible on the page.
|
||||
const _exists = (elem) => {
|
||||
return isElement(elem) && !isNullOrUndefined(elem.offsetParent);
|
||||
};
|
||||
|
||||
// source_elem is specified but invalid.
|
||||
if (!isNullOrUndefined(source_elem) && !_exists(source_elem)) {
|
||||
return;
|
||||
if (!Array.isArray(excluded_div_ids)) {
|
||||
excluded_div_ids = [];
|
||||
}
|
||||
|
||||
// Removes `data-selected` attribute from all tree/dirs buttons.
|
||||
const _reset_all_buttons = async({excluded_elems} = {}) => {
|
||||
const elems = this.container_elem.querySelectorAll(
|
||||
".extra-network-dirs-view-button, .tree-list-item"
|
||||
);
|
||||
for (const elem of elems) {
|
||||
if (Array.isArray(excluded_elems) && excluded_elems.includes(elem)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const prev = elem.outerHTML;
|
||||
delete elem.dataset.selected;
|
||||
delete elem.dataset.recurse;
|
||||
elem.classList.remove("short-pressed");
|
||||
elem.classList.remove("long-pressed");
|
||||
if (prev !== elem.outerHTML) {
|
||||
this.tree_list.updateHtml(elem);
|
||||
}
|
||||
for (const div_id of Object.keys(this.list_button_states)) {
|
||||
if (excluded_div_ids.includes(div_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.tree_list.content_elem.querySelectorAll(
|
||||
".tree-list-item-indent [data-selected]"
|
||||
).forEach(elem => {
|
||||
delete elem.dataset.selected;
|
||||
});
|
||||
};
|
||||
_reset_all_buttons.bind(this);
|
||||
|
||||
const _set_recursion_depth = (parent_id, state) => {
|
||||
this.tree_list.content_elem.querySelectorAll(
|
||||
`.tree-list-item-indent [data-parent-id="${parent_id}"]`
|
||||
).forEach(elem => {
|
||||
elem.toggleAttribute("data-selected", state);
|
||||
});
|
||||
};
|
||||
_set_recursion_depth.bind(this);
|
||||
|
||||
if (reset_all === true) {
|
||||
_reset_all_buttons();
|
||||
await this.tree_list.onRowSelected(); // no args deselects all.
|
||||
this.applyDirectoryFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_exists(source_elem) && isString(source_selector)) {
|
||||
source_elem = this.container_elem.querySelector(source_selector);
|
||||
}
|
||||
|
||||
if (!_exists(source_elem) && isString(source_class)) {
|
||||
source_elem = this.container_elem.querySelector(`${source_class}[data-selected]`);
|
||||
}
|
||||
|
||||
// try to find any selected buttons to use as a source.
|
||||
if (!_exists(source_elem)) {
|
||||
source_elem = this.container_elem.querySelector("[data-selected]");
|
||||
}
|
||||
|
||||
// If we got here with no source elem, then we will take this to mean that
|
||||
// we are deselecting all.
|
||||
if (!_exists(source_elem)) {
|
||||
_reset_all_buttons();
|
||||
await this.tree_list.onRowSelected(); // no args deselects all.
|
||||
this.applyDirectoryFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
const source_is_tree = source_elem.classList.contains("tree-list-item");
|
||||
const other_selector = source_is_tree ? ".extra-network-dirs-view-button" : ".tree-list-item";
|
||||
// NOTE: We only use this escaped path in selectors since html handles these chars
|
||||
// different from JS. We don't need to escape the path for any internal operations.
|
||||
const data_path = String.raw`${source_elem.dataset.path.replaceAll("\\", "\\\\")}`;
|
||||
const other_elem = document.querySelector(`${other_selector}[data-path="${data_path}"]`);
|
||||
if (!_exists(other_elem)) {
|
||||
// Can't reflect attributes since no matching element exists.
|
||||
// This can happen when tree/dirs view is disabled or tree is collapsed.
|
||||
_reset_all_buttons({excluded_elems: [source_elem]});
|
||||
if (source_is_tree) {
|
||||
await this.tree_list.onRowSelected(source_elem);
|
||||
_set_recursion_depth(source_elem.dataset.divId, "recurse" in source_elem.dataset);
|
||||
} else {
|
||||
await this.tree_list.onRowSelected();
|
||||
const tree_btn = this.tree_list.content_elem.querySelector(`.tree-list-item[data-div-id="${div_id}"]`);
|
||||
const tree_btn_exists = isElement(tree_btn) && !isNullOrUndefined(tree_btn.offsetParent);
|
||||
if (tree_btn_exists) {
|
||||
await this.deselectTreeListRow(tree_btn);
|
||||
}
|
||||
// Don't use escaped path here since this is pure javascript beyond this point.
|
||||
let directory_filter = source_elem.dataset.path;
|
||||
if ("directoryFilterOverride" in source_elem.dataset) {
|
||||
directory_filter = source_elem.dataset.directoryFilterOverride;
|
||||
|
||||
const dirs_btn = this.container_elem.querySelector(`.extra-network-dirs-view-button[data-div-id="${div_id}"]`);
|
||||
const dirs_btn_exists = isElement(dirs_btn) && !isNullOrUndefined(dirs_btn.offsetParent);
|
||||
if (dirs_btn_exists) {
|
||||
this.deselectDirsViewButton(dirs_btn);
|
||||
}
|
||||
this.applyDirectoryFilter(
|
||||
"selected" in source_elem.dataset ? directory_filter : null,
|
||||
"recurse" in source_elem.dataset,
|
||||
);
|
||||
return;
|
||||
|
||||
delete this.list_button_states[div_id];
|
||||
}
|
||||
|
||||
const data_selected = "selected" in source_elem.dataset;
|
||||
const data_recurse = "recurse" in source_elem.dataset;
|
||||
const short_pressed = source_elem.classList.contains("short-pressed");
|
||||
const long_pressed = source_elem.classList.contains("long-pressed");
|
||||
this.tree_list.clearSelectedRows({excluded_div_ids: excluded_div_ids});
|
||||
this.clearDirectoryFilters({excluded_div_ids: excluded_div_ids});
|
||||
await this.tree_list.update();
|
||||
}
|
||||
|
||||
_reset_all_buttons({excluded_elems: [source_elem, other_elem]});
|
||||
other_elem.toggleAttribute("data-selected", data_selected);
|
||||
other_elem.toggleAttribute("data-recurse", data_recurse);
|
||||
other_elem.classList.toggle("short-pressed", short_pressed);
|
||||
other_elem.classList.toggle("long-pressed", long_pressed);
|
||||
|
||||
await this.tree_list.onRowSelected(source_is_tree ? source_elem : other_elem);
|
||||
const div_id = source_is_tree ? source_elem.dataset.divId : other_elem.dataset.divId;
|
||||
_set_recursion_depth(div_id, data_recurse);
|
||||
// Don't use escaped path here since this is pure javascript beyond this point.
|
||||
let directory_filter = source_elem.dataset.path;
|
||||
if ("directoryFilterOverride" in source_elem.dataset) {
|
||||
directory_filter = source_elem.dataset.directoryFilterOverride;
|
||||
}
|
||||
this.applyDirectoryFilter(
|
||||
"selected" in source_elem.dataset ? directory_filter : null,
|
||||
"recurse" in source_elem.dataset,
|
||||
setTreeListRecursionDepth(parent_id, state) {
|
||||
const elems = this.tree_list.content_elem.querySelectorAll(
|
||||
`.tree-list-item-indent [data-parent-id="${parent_id}"]`
|
||||
);
|
||||
for (const elem of elems) {
|
||||
elem.toggleAttribute("data-selected", state);
|
||||
this.tree_list.updateHtml(elem.closest(".tree-list-item"));
|
||||
}
|
||||
}
|
||||
|
||||
async selectTreeListRow(elem) {
|
||||
elem.dataset.selected = "";
|
||||
this.tree_list.setRowSelected(elem);
|
||||
let directory_filter = elem.dataset.path;
|
||||
if ("directoryFilterOverride" in elem.dataset) {
|
||||
directory_filter = elem.dataset.directoryFilterOverride;
|
||||
}
|
||||
|
||||
const recurse = elem.classList.contains("short-pressed") && !elem.classList.contains("long-pressed");
|
||||
this.setTreeListRecursionDepth(elem.dataset.divId, recurse);
|
||||
this.addDirectoryFilter(elem.dataset.divId, directory_filter, recurse);
|
||||
await this.tree_list.update();
|
||||
|
||||
this.list_button_states[elem.dataset.divId] = {
|
||||
short_pressed: elem.classList.contains("short-pressed"),
|
||||
long_pressed: elem.classList.contains("long-pressed"),
|
||||
};
|
||||
}
|
||||
|
||||
async deselectTreeListRow(elem) {
|
||||
delete elem.dataset.selected;
|
||||
elem.classList.remove("short-pressed");
|
||||
elem.classList.remove("long-pressed");
|
||||
this.tree_list.setRowDeselected(elem);
|
||||
this.setTreeListRecursionDepth(elem.dataset.divId, false);
|
||||
this.removeDirectoryFilter(elem.dataset.divId);
|
||||
await this.tree_list.update();
|
||||
|
||||
delete this.list_button_states[elem.dataset.divId];
|
||||
}
|
||||
|
||||
selectDirsViewButton(elem) {
|
||||
elem.dataset.selected = "";
|
||||
let directory_filter = elem.dataset.path;
|
||||
if ("directoryFilterOverride" in elem.dataset) {
|
||||
directory_filter = elem.dataset.directoryFilterOverride;
|
||||
}
|
||||
|
||||
const recurse = elem.classList.contains("short-pressed") && !elem.classList.contains("long-pressed");
|
||||
this.addDirectoryFilter(elem.dataset.divId, directory_filter, recurse);
|
||||
|
||||
this.list_button_states[elem.dataset.divId] = {
|
||||
short_pressed: elem.classList.contains("short-pressed"),
|
||||
long_pressed: elem.classList.contains("long-pressed"),
|
||||
};
|
||||
}
|
||||
|
||||
deselectDirsViewButton(elem) {
|
||||
delete elem.dataset.selected;
|
||||
elem.classList.remove("short-pressed");
|
||||
elem.classList.remove("long-pressed");
|
||||
delete this.list_button_states[elem.dataset.divId];
|
||||
}
|
||||
|
||||
async applyListButtonStates() {
|
||||
const selected_tree_rows = this.tree_list.content_elem.querySelectorAll(".tree-list-item[data-selected]");
|
||||
for (const elem of selected_tree_rows) {
|
||||
if (!Object.keys(this.list_button_states).includes(elem.dataset.divId)) {
|
||||
await this.deselectTreeListRow(elem);
|
||||
}
|
||||
}
|
||||
|
||||
const selected_dirs_buttons = this.container_elem.querySelectorAll(".extra-network-dirs-view-button[data-selected]");
|
||||
for (const elem of selected_dirs_buttons) {
|
||||
if (!Object.keys(this.list_button_states).includes(elem.dataset.divId)) {
|
||||
this.deselectDirsViewButton(elem);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [div_id, state] of Object.entries(this.list_button_states)) {
|
||||
const tree_btn = this.tree_list.content_elem.querySelector(`.tree-list-item[data-div-id="${div_id}"]`);
|
||||
const tree_btn_exists = isElement(tree_btn) && !isNullOrUndefined(tree_btn.offsetParent);
|
||||
if (tree_btn_exists) {
|
||||
tree_btn.classList.toggle("short-pressed", state.short_pressed);
|
||||
tree_btn.classList.toggle("long-pressed", state.long_pressed);
|
||||
if (state.short_pressed || state.long_pressed) {
|
||||
await this.selectTreeListRow(tree_btn);
|
||||
} else {
|
||||
await this.deselectTreeListRow(tree_btn);
|
||||
}
|
||||
}
|
||||
|
||||
const dirs_btn = this.container_elem.querySelector(`.extra-network-dirs-view-button[data-div-id="${div_id}"]`);
|
||||
const dirs_btn_exists = isElement(dirs_btn) && !isNullOrUndefined(dirs_btn.offsetParent);
|
||||
if (dirs_btn_exists) {
|
||||
dirs_btn.classList.toggle("short-pressed", state.short_pressed);
|
||||
dirs_btn.classList.toggle("long-pressed", state.long_pressed);
|
||||
if (state.short_pressed || state.long_pressed) {
|
||||
this.selectDirsViewButton(dirs_btn);
|
||||
} else {
|
||||
this.deselectDirsViewButton(dirs_btn);
|
||||
}
|
||||
}
|
||||
|
||||
if (!tree_btn_exists && !dirs_btn_exists) {
|
||||
this.removeDirectoryFilter(div_id);
|
||||
}
|
||||
}
|
||||
this.applyDirectoryFilters();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1029,23 +1067,6 @@ async function extraNetworksTabSelected(tabname_full, show_prompt, show_neg_prom
|
|||
}
|
||||
}
|
||||
|
||||
function extraNetworksBtnDirsViewItemOnLongPress(event) {
|
||||
const btn = event.target.closest(".extra-network-dirs-view-button");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
|
||||
tab.setDirectoryButtons({source_elem: btn});
|
||||
}
|
||||
|
||||
function extraNetworksBtnDirsViewItemOnClick(event) {
|
||||
/** Handles `onclick` events for buttons in the directory view. */
|
||||
const btn = event.target.closest(".extra-network-dirs-view-button");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
|
||||
tab.setDirectoryButtons({source_elem: btn});
|
||||
}
|
||||
|
||||
function extraNetworksControlSearchClearOnClick(event) {
|
||||
/** Dispatches custom event when the `clear` button in a search input is clicked. */
|
||||
const btn = event.target.closest(".extra-network-control--search-clear");
|
||||
|
@ -1065,7 +1086,6 @@ function extraNetworksControlSortModeOnClick(event) {
|
|||
const tab = extra_networks_tabs[controls.dataset.tabnameFull];
|
||||
tab.controls_elem.querySelectorAll(".extra-network-control--sort-mode").forEach(elem => {
|
||||
delete elem.dataset.selected;
|
||||
delete elem.dataset.recurse;
|
||||
});
|
||||
|
||||
btn.dataset.selected = "";
|
||||
|
@ -1109,17 +1129,6 @@ async function extraNetworksControlTreeViewOnClick(event) {
|
|||
btn.toggleAttribute("data-selected");
|
||||
tab.tree_view_en = "selected" in btn.dataset;
|
||||
|
||||
// If hiding, clear the tree list selections before hiding it.
|
||||
if (!tab.tree_view_en) {
|
||||
await tab.tree_list.onRowSelected();
|
||||
tab.tree_list.content_elem.querySelectorAll(
|
||||
".tree-list-item[data-selected]"
|
||||
).forEach(elem => {
|
||||
delete elem.dataset.selected;
|
||||
delete elem.dataset.recurse;
|
||||
});
|
||||
}
|
||||
|
||||
tab.tree_list.scroll_elem.parentElement.classList.toggle("hidden", !tab.tree_view_en);
|
||||
tab.tree_list.enable(tab.tree_view_en);
|
||||
|
||||
|
@ -1137,13 +1146,7 @@ async function extraNetworksControlTreeViewOnClick(event) {
|
|||
await tab.tree_list.load();
|
||||
}
|
||||
|
||||
if ((tab.tree_view_en && tab.dirs_view_en) || (!tab.tree_view_en && tab.dirs_view_en)) {
|
||||
tab.setDirectoryButtons({source_class: ".extra-network-dirs-view-button"});
|
||||
} else if (tab.tree_view_en) {
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
} else {
|
||||
tab.setDirectoryButtons({reset_all: true});
|
||||
}
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
function extraNetworksControlDirsViewOnClick(event) {
|
||||
|
@ -1157,27 +1160,11 @@ function extraNetworksControlDirsViewOnClick(event) {
|
|||
btn.toggleAttribute("data-selected");
|
||||
tab.dirs_view_en = "selected" in btn.dataset;
|
||||
|
||||
if (!tab.dirs_view_en) {
|
||||
// If hiding, we want to deselect all buttons prior to hiding.
|
||||
tab.container_elem.querySelectorAll(
|
||||
".extra-network-dirs-view-button[data-selected]"
|
||||
).forEach(elem => {
|
||||
delete elem.dataset.selected;
|
||||
delete elem.dataset.recurse;
|
||||
});
|
||||
}
|
||||
|
||||
tab.container_elem.querySelector(
|
||||
".extra-network-content--dirs-view"
|
||||
).classList.toggle("hidden", !tab.dirs_view_en);
|
||||
|
||||
if ((tab.tree_view_en && tab.dirs_view_en) || (tab.tree_view_en && !tab.dirs_view_en)) {
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
} else if (tab.dirs_view_en) {
|
||||
tab.setDirectoryButtons({source_class: ".extra-network-dirs-view-button"});
|
||||
} else {
|
||||
tab.setDirectoryButtons({reset_all: true});
|
||||
}
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
function extraNetworksControlRefreshOnClick(event) {
|
||||
|
@ -1277,68 +1264,128 @@ function extraNetworksTreeFileOnClick(event) {
|
|||
});
|
||||
}
|
||||
|
||||
async function extraNetworksTreeDirectoryOnLongPress(event) {
|
||||
// Do not select the row if its child button-row is the target of the event.
|
||||
if (event.target.closest(".tree-list-item-action")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ==== TREE VIEW DIRECTORY ROW CLICK EVENTS ====
|
||||
async function extraNetworksTreeDirectoryRowClickHandler({event, deselect_others} = {}) {
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
if (deselect_others === true) {
|
||||
await tab.clearSelectedButtons({excluded_div_ids: [btn.dataset.divId]});
|
||||
}
|
||||
if ("selected" in btn.dataset) {
|
||||
await tab.selectTreeListRow(btn);
|
||||
} else {
|
||||
await tab.deselectTreeListRow(btn);
|
||||
}
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
tab.setDirectoryButtons({source_elem: btn});
|
||||
function extraNetworksTreeDirectoryOnClick(event) {
|
||||
/** Selects the clicked row and applies a recursive filter for the directory.
|
||||
* Deselects all other rows.
|
||||
*/
|
||||
extraNetworksTreeDirectoryRowClickHandler({event: event, deselect_others: true});
|
||||
}
|
||||
|
||||
function extraNetworksTreeDirectoryOnCtrlClick(event) {
|
||||
/** Selects the clicked row. Does not deselect other rows. */
|
||||
extraNetworksTreeDirectoryRowClickHandler({event: event, deselect_others: false});
|
||||
}
|
||||
|
||||
function extraNetworksTreeDirectoryOnLongPress(event) {
|
||||
/** Selects the clicked row. Deselects all other rows. */
|
||||
extraNetworksTreeDirectoryRowClickHandler({event: event, deselect_others: true});
|
||||
}
|
||||
|
||||
function extraNetworksTreeDirectoryOnLongCtrlPress(event) {
|
||||
/** Selects the clicked row and applies a recursive filter for the directory.
|
||||
* Does not deselect other rows.
|
||||
*/
|
||||
extraNetworksTreeDirectoryRowClickHandler({event: event, deselect_others: false});
|
||||
}
|
||||
|
||||
async function extraNetworksTreeDirectoryOnDblClick(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
await tab.tree_list.toggleRowExpanded(div_id);
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
}
|
||||
|
||||
async function extraNetworksTreeDirectoryOnClick(event) {
|
||||
// Do not select the row if its child button-row is the target of the event.
|
||||
if (event.target.closest(".tree-list-item-action")) {
|
||||
return;
|
||||
}
|
||||
/** Expands the selected directory. */
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
tab.setDirectoryButtons({source_elem: btn});
|
||||
}
|
||||
|
||||
async function extraNetworksTreeDirectoryChevronOnLongPress(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const chevron = event.target.closest(".tree-list-item-action--chevron");
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
if ("expanded" in btn.dataset) {
|
||||
await tab.tree_list.collapseAllRows(div_id);
|
||||
} else {
|
||||
await tab.tree_list.expandAllRows(div_id);
|
||||
}
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
|
||||
await tab.tree_list.toggleRowExpanded(btn.dataset.divId);
|
||||
|
||||
await tab.clearSelectedButtons();
|
||||
}
|
||||
|
||||
// ==== TREE VIEW DIRECTORY ROW CHEVRON CLICK EVENTS ====
|
||||
async function extraNetworksBtnTreeViewChevronOnClick(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
await tab.tree_list.toggleRowExpanded(div_id);
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
|
||||
await tab.tree_list.toggleRowExpanded(btn.dataset.divId);
|
||||
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
async function extraNetworksBtnTreeViewChevronOnCtrlClick(event) {
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
await tab.tree_list.expandAllRows(btn.dataset.divId);
|
||||
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
async function extraNetworksBtnTreeViewChevronOnShiftClick(event) {
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
await tab.tree_list.collapseAllRows(btn.dataset.divId);
|
||||
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
// ==== DIRS VIEW BUTTON CLICK EVENTS ====
|
||||
async function extraNetworksBtnDirsViewItemClickHandler({event, deselect_others} = {}) {
|
||||
const btn = event.target.closest(".extra-network-dirs-view-button");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
if (deselect_others === true) {
|
||||
await tab.clearSelectedButtons({excluded_div_ids: [btn.dataset.divId]});
|
||||
}
|
||||
if ("selected" in btn.dataset) {
|
||||
tab.selectDirsViewButton(btn);
|
||||
} else {
|
||||
tab.deselectDirsViewButton(btn);
|
||||
}
|
||||
tab.applyListButtonStates();
|
||||
}
|
||||
|
||||
function extraNetworksBtnDirsViewItemOnClick(event) {
|
||||
/** Selects the clicked button. Deselects all other buttons. */
|
||||
extraNetworksBtnDirsViewItemClickHandler({event: event, deselect_others: true});
|
||||
}
|
||||
|
||||
function extraNetworksBtnDirsViewItemOnCtrlClick(event) {
|
||||
/** Selects the clicked button. Does not deselect other buttons. */
|
||||
extraNetworksBtnDirsViewItemClickHandler({event: event, deselect_others: false});
|
||||
}
|
||||
|
||||
function extraNetworksBtnDirsViewItemOnLongPress(event) {
|
||||
/** Selects the clicked button and applies a recursive filter for the directory.
|
||||
* Deselects all other buttons.
|
||||
*/
|
||||
extraNetworksBtnDirsViewItemClickHandler({event: event, deselect_others: true});
|
||||
}
|
||||
|
||||
function extraNetworksBtnDirsViewItemOnLongCtrlPress(event) {
|
||||
/** Selects the clicked button and applies a recursive filter for the directory.
|
||||
* Does not deselect other buttons.
|
||||
*/
|
||||
extraNetworksBtnDirsViewItemClickHandler({event: event, deselect_others: false});
|
||||
}
|
||||
|
||||
|
||||
// ==== OTHER BUTTON HANDLERS ====
|
||||
function extraNetworksBtnShowMetadataOnClick(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
|
@ -1469,11 +1516,32 @@ function extraNetworksSetupEventDelegators() {
|
|||
},
|
||||
];
|
||||
|
||||
const long_press_event_map = [
|
||||
const short_ctrl_press_event_map = [
|
||||
{
|
||||
selector: ".tree-list-item-action--chevron",
|
||||
handler: extraNetworksTreeDirectoryChevronOnLongPress,
|
||||
handler: extraNetworksBtnTreeViewChevronOnCtrlClick,
|
||||
},
|
||||
{
|
||||
selector: ".tree-list-item--dir",
|
||||
negative: ".tree-list-item-action",
|
||||
handler: extraNetworksTreeDirectoryOnCtrlClick,
|
||||
},
|
||||
{
|
||||
selector: ".extra-network-dirs-view-button",
|
||||
handler: extraNetworksBtnDirsViewItemOnCtrlClick,
|
||||
},
|
||||
];
|
||||
|
||||
const short_shift_press_event_map = [
|
||||
{
|
||||
selector: ".tree-list-item-action--chevron",
|
||||
handler: extraNetworksBtnTreeViewChevronOnShiftClick,
|
||||
},
|
||||
];
|
||||
|
||||
const short_ctrl_shift_press_event_map = [];
|
||||
|
||||
const long_press_event_map = [
|
||||
{
|
||||
selector: ".tree-list-item--dir",
|
||||
negative: ".tree-list-item-action",
|
||||
|
@ -1485,6 +1553,21 @@ function extraNetworksSetupEventDelegators() {
|
|||
},
|
||||
];
|
||||
|
||||
const long_ctrl_press_event_map = [
|
||||
{
|
||||
selector: ".tree-list-item--dir",
|
||||
negative: ".tree-list-item-action",
|
||||
handler: extraNetworksTreeDirectoryOnLongCtrlPress,
|
||||
},
|
||||
{
|
||||
selector: ".extra-network-dirs-view-button",
|
||||
handler: extraNetworksBtnDirsViewItemOnLongCtrlPress,
|
||||
},
|
||||
];
|
||||
|
||||
const long_shift_press_event_map = [];
|
||||
const long_ctrl_shift_press_event_map = [];
|
||||
|
||||
const dbl_press_event_map = [
|
||||
{
|
||||
selector: ".tree-list-item--dir",
|
||||
|
@ -1500,8 +1583,8 @@ function extraNetworksSetupEventDelegators() {
|
|||
// Toggle
|
||||
if (elem.classList.contains("long-pressed")) {
|
||||
elem.classList.remove("long-pressed");
|
||||
elem.classList.remove("short-pressed");
|
||||
delete elem.dataset.selected;
|
||||
delete elem.dataset.recurse;
|
||||
} else {
|
||||
elem.classList.toggle("short-pressed");
|
||||
elem.toggleAttribute("data-selected");
|
||||
|
@ -1519,7 +1602,6 @@ function extraNetworksSetupEventDelegators() {
|
|||
// Else we set as long pressed.
|
||||
if (elem.classList.contains("long-pressed")) {
|
||||
elem.classList.remove("long-pressed");
|
||||
delete elem.dataset.recurse;
|
||||
// Don't want to remove selected state if btn was previously short-pressed.
|
||||
if (!elem.classList.contains("short-pressed")) {
|
||||
delete elem.dataset.selected;
|
||||
|
@ -1527,7 +1609,6 @@ function extraNetworksSetupEventDelegators() {
|
|||
} else {
|
||||
elem.classList.toggle("long-pressed");
|
||||
elem.dataset.selected = "";
|
||||
elem.dataset.recurse = "";
|
||||
}
|
||||
|
||||
elem.dispatchEvent(new Event("longpress", event));
|
||||
|
@ -1544,18 +1625,41 @@ function extraNetworksSetupEventDelegators() {
|
|||
let press_timer;
|
||||
let press_time_ms = 800;
|
||||
|
||||
let curr_elem;
|
||||
|
||||
window.addEventListener("mousedown", event => {
|
||||
for (const obj of short_press_event_map) {
|
||||
if (event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
let event_map = short_press_event_map;
|
||||
if (event.ctrlKey && event.shiftKey) {
|
||||
event_map = short_ctrl_shift_press_event_map;
|
||||
} else if (event.ctrlKey) {
|
||||
event_map = short_ctrl_press_event_map;
|
||||
} else if (event.shiftKey) {
|
||||
event_map = short_shift_press_event_map;
|
||||
}
|
||||
for (const obj of event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
elem.classList.add("pressed");
|
||||
curr_elem = elem;
|
||||
}
|
||||
}
|
||||
|
||||
for (const obj of long_press_event_map) {
|
||||
event_map = long_press_event_map;
|
||||
if (event.ctrlKey && event.shiftKey) {
|
||||
event_map = long_ctrl_shift_press_event_map;
|
||||
} else if (event.ctrlKey) {
|
||||
event_map = long_ctrl_press_event_map;
|
||||
} else if (event.shiftKey) {
|
||||
event_map = long_shift_press_event_map;
|
||||
}
|
||||
|
||||
for (const obj of event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
|
@ -1581,20 +1685,32 @@ function extraNetworksSetupEventDelegators() {
|
|||
});
|
||||
|
||||
window.addEventListener("mouseup", event => {
|
||||
for (const obj of short_press_event_map) {
|
||||
if (event.button !== 0) {
|
||||
clearTimeout(press_timer);
|
||||
return;
|
||||
}
|
||||
let event_map = short_press_event_map;
|
||||
if (event.ctrlKey && event.shiftKey) {
|
||||
event_map = short_ctrl_shift_press_event_map;
|
||||
} else if (event.ctrlKey) {
|
||||
event_map = short_ctrl_press_event_map;
|
||||
} else if (event.shiftKey) {
|
||||
event_map = short_shift_press_event_map;
|
||||
}
|
||||
for (const obj of event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
clearTimeout(press_timer);
|
||||
if (isElement(curr_elem) && curr_elem !== elem) {
|
||||
curr_elem.classList.remove("pressed");
|
||||
return;
|
||||
}
|
||||
if (elem.classList.contains("pressed")) {
|
||||
if (event.detail === 1 ||
|
||||
!dbl_press_event_map.map(x => x.selector).includes(obj.selector)
|
||||
) {
|
||||
elem.classList.remove("pressed");
|
||||
on_short_press(event, elem, obj.handler);
|
||||
}
|
||||
elem.classList.remove("pressed");
|
||||
on_short_press(event, elem, obj.handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1607,13 +1723,21 @@ function extraNetworksSetupEventDelegators() {
|
|||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
clearTimeout(press_timer);
|
||||
if (elem.classList.contains("pressed")) {
|
||||
elem.classList.remove("pressed");
|
||||
on_dbl_press(event, elem, obj.handler);
|
||||
if (isElement(curr_elem) && curr_elem !== elem) {
|
||||
curr_elem.classList.remove("pressed");
|
||||
return;
|
||||
}
|
||||
elem.classList.remove("pressed");
|
||||
on_dbl_press(event, elem, obj.handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isElement(curr_elem) && curr_elem !== event.target) {
|
||||
clearTimeout(press_timer);
|
||||
curr_elem.classList.remove("pressed");
|
||||
return;
|
||||
}
|
||||
// NOTE: long_press_event_map is handled by the timer setup in "mousedown" handlers.
|
||||
});
|
||||
}
|
||||
|
@ -1651,5 +1775,37 @@ async function extraNetworksSetup() {
|
|||
extraNetworksSetupEventDelegators();
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", (event) => {
|
||||
if (event.repeat) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.ctrlKey) {
|
||||
document.body.classList.add("ctrl-pressed");
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
document.body.classList.add("shift-pressed");
|
||||
}
|
||||
if (event.altKey) {
|
||||
document.body.classList.add("alt-pressed");
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("keyup", (event) => {
|
||||
if (event.repeat) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event.ctrlKey) {
|
||||
document.body.classList.remove("ctrl-pressed");
|
||||
}
|
||||
if (!event.shiftKey) {
|
||||
document.body.classList.remove("shift-pressed");
|
||||
}
|
||||
if (!event.altKey) {
|
||||
document.body.classList.remove("alt-pressed");
|
||||
}
|
||||
});
|
||||
|
||||
onUiLoaded(extraNetworksSetup);
|
||||
onOptionsChanged(() => initialUiOptionsLoaded.state = true);
|
||||
|
|
|
@ -45,13 +45,10 @@ class ExtraNetworksClusterize extends Clusterize {
|
|||
default_sort_mode_str = "divId";
|
||||
default_sort_dir_str = "ascending";
|
||||
default_filter_str = "";
|
||||
default_directory_filter_str = "";
|
||||
default_directory_filter_recurse = false;
|
||||
sort_mode_str = this.default_sort_mode_str;
|
||||
sort_dir_str = this.default_sort_dir_str;
|
||||
filter_str = this.default_filter_str;
|
||||
directory_filter_str = this.default_directory_filter_str;
|
||||
directory_filter_recurse = this.default_directory_filter_recurse;
|
||||
directory_filters = {};
|
||||
|
||||
constructor(args) {
|
||||
super(args);
|
||||
|
@ -157,21 +154,41 @@ class ExtraNetworksClusterize extends Clusterize {
|
|||
this.filterData();
|
||||
}
|
||||
|
||||
setDirectoryFilterStr(filter_str, recurse) {
|
||||
recurse = recurse === true;
|
||||
if (isString(filter_str) && this.directory_filter_str !== filter_str) {
|
||||
this.directory_filter_str = filter_str;
|
||||
} else if (isNullOrUndefined(filter_str)) {
|
||||
this.directory_filter_str = this.default_directory_filter_str;
|
||||
setDirectoryFilters(filters) {
|
||||
if (isNullOrUndefined(filters)) {
|
||||
this.directory_filters = {};
|
||||
return;
|
||||
}
|
||||
this.directory_filters = JSON.parse(JSON.stringify(filters));
|
||||
}
|
||||
|
||||
addDirectoryFilter(div_id, filter_str, recurse) {
|
||||
this.directory_filters[div_id] = {filter_str: filter_str, recurse: recurse};
|
||||
}
|
||||
|
||||
removeDirectoryFilter(div_id) {
|
||||
delete this.directory_filters[div_id];
|
||||
}
|
||||
|
||||
clearDirectoryFilters({excluded_div_ids} = {}) {
|
||||
if (isString(excluded_div_ids)) {
|
||||
excluded_div_ids = [excluded_div_ids];
|
||||
}
|
||||
|
||||
if (!isNullOrUndefined(recurse) && this.directory_filter_recurse !== recurse) {
|
||||
this.directory_filter_recurse = recurse;
|
||||
} else if (isNullOrUndefined(recurse)) {
|
||||
this.directory_filter_recurse = this.default_directory_filter_recurse;
|
||||
if (!Array.isArray(excluded_div_ids)) {
|
||||
excluded_div_ids = [];
|
||||
}
|
||||
|
||||
this.filterData();
|
||||
for (const div_id of Object.keys(this.directory_filters)) {
|
||||
if (excluded_div_ids.includes(div_id)) {
|
||||
continue;
|
||||
}
|
||||
delete this.directory_filters[div_id];
|
||||
}
|
||||
}
|
||||
|
||||
getDirectoryFilters() {
|
||||
return this.directory_filters;
|
||||
}
|
||||
|
||||
async initDataDefaultCallback() {
|
||||
|
@ -259,52 +276,55 @@ class ExtraNetworksClusterize extends Clusterize {
|
|||
}
|
||||
|
||||
class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
||||
selected_div_id = null;
|
||||
prev_selected_div_id = null;
|
||||
|
||||
constructor(args) {
|
||||
super({...args});
|
||||
this.selected_div_ids = new Set();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.selected_div_id = null;
|
||||
this.prev_selected_div_id = null;
|
||||
this.selected_div_ids.clear();
|
||||
super.clear();
|
||||
}
|
||||
|
||||
async onRowSelected(elem) {
|
||||
/** Selects a row and deselects all others.
|
||||
*
|
||||
* If `elem` is null/undefined, then we deselect all rows.
|
||||
*/
|
||||
if (isNullOrUndefined(elem)) {
|
||||
if (!isNullOrUndefined(this.selected_div_id) &&
|
||||
keyExistsLogError(this.data_obj, this.selected_div_id)) {
|
||||
this.selected_div_id = null;
|
||||
}
|
||||
setRowSelected(elem) {
|
||||
if (!isElement(elem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isElementLogError(elem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const div_id = elem.dataset.divId;
|
||||
this.updateHtml(elem);
|
||||
this.selected_div_ids.add(elem.dataset.divId);
|
||||
this.prev_selected_div_id = elem.dataset.divId;
|
||||
}
|
||||
|
||||
if (!keyExistsLogError(this.data_obj, div_id)) {
|
||||
setRowDeselected(elem) {
|
||||
if (!isElement(elem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isNullOrUndefined(this.selected_div_id) && div_id !== this.selected_div_id) {
|
||||
const prev_elem = this.content_elem.querySelector(
|
||||
`[data-div-id="${this.selected_div_id}"]`
|
||||
);
|
||||
// deselect current selection if exists on page
|
||||
if (isElement(prev_elem)) {
|
||||
this.selected_div_id = null;
|
||||
}
|
||||
this.updateHtml(elem);
|
||||
this.selected_div_ids.delete(elem.dataset.divId);
|
||||
this.prev_selected_div_id = null;
|
||||
}
|
||||
|
||||
clearSelectedRows({excluded_div_ids} = {}) {
|
||||
if (isString(excluded_div_ids)) {
|
||||
excluded_div_ids = [excluded_div_ids];
|
||||
}
|
||||
|
||||
if (!Array.isArray(excluded_div_ids)) {
|
||||
excluded_div_ids = [];
|
||||
}
|
||||
|
||||
this.selected_div_ids.clear();
|
||||
for (const div_id of excluded_div_ids) {
|
||||
this.selected_div_ids.add(div_id);
|
||||
}
|
||||
if (!excluded_div_ids.includes(this.prev_selected_div_id)) {
|
||||
this.prev_selected_div_id = null;
|
||||
}
|
||||
this.selected_div_id = "selected" in elem.dataset ? div_id : null;
|
||||
await this.update();
|
||||
}
|
||||
|
||||
getMaxRowWidth() {
|
||||
|
@ -390,17 +410,29 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
|||
}
|
||||
|
||||
// Deselect current selected div id if it was just hidden.
|
||||
if (!isNullOrUndefined(this.selected_div_id) && !this.data_obj[this.selected_div_id].visible) {
|
||||
this.selected_div_id = null;
|
||||
if (this.selected_div_ids.has(div_id) && !this.data_obj[div_id].visible) {
|
||||
this.selected_div_ids.delete(div_id);
|
||||
if (this.prev_selected_div_id === div_id) {
|
||||
this.prev_selected_div_id = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const new_len = Object.values(this.data_obj).filter(v => v.visible).length;
|
||||
await this.setMaxItems(new_len);
|
||||
await this.refresh(true);
|
||||
await this.sortData();
|
||||
}
|
||||
|
||||
getChildrenDivIds(div_id, {recurse} = {}) {
|
||||
const res = JSON.parse(JSON.stringify(this.data_obj[div_id].children));
|
||||
if (recurse === true) {
|
||||
for (const child_id of this.data_obj[div_id].children) {
|
||||
res.push(...this.getChildrenDivIds(child_id, {recurse: recurse}));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async toggleRowExpanded(div_id) {
|
||||
/** Toggles a row between expanded and collapses states. */
|
||||
if (!keyExistsLogError(this.data_obj, div_id)) {
|
||||
|
@ -423,8 +455,11 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
|||
}
|
||||
|
||||
// Deselect current selected div id if it was just hidden.
|
||||
if (!isNullOrUndefined(this.selected_div_id) && !this.data_obj[this.selected_div_id].visible) {
|
||||
this.selected_div_id = null;
|
||||
if (this.selected_div_ids.has(div_id) && !this.data_obj[div_id].visible) {
|
||||
this.selected_div_ids.delete(div_id);
|
||||
if (this.prev_selected_div_id === div_id) {
|
||||
this.prev_selected_div_id = null;
|
||||
}
|
||||
}
|
||||
|
||||
const new_len = Object.values(this.data_obj).filter(v => v.visible).length;
|
||||
|
@ -473,9 +508,8 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
|||
elem.dataset.expanded = "";
|
||||
}
|
||||
|
||||
// Only allow one item to have `data-selected`.
|
||||
delete elem.dataset.selected;
|
||||
if (div_id === this.selected_div_id) {
|
||||
if (this.selected_div_ids.has(div_id)) {
|
||||
elem.dataset.selected = "";
|
||||
}
|
||||
|
||||
|
@ -579,6 +613,22 @@ class ExtraNetworksClusterizeCardsList extends ExtraNetworksClusterize {
|
|||
for (const [div_id, v] of Object.entries(this.data_obj)) {
|
||||
let visible = true;
|
||||
|
||||
// Apply the directory filters.
|
||||
if (!Object.keys(this.directory_filters).length) {
|
||||
v.visible = true;
|
||||
} else {
|
||||
v.visible = Object.values(this.directory_filters).some((filter) => {
|
||||
if (filter.recurse) {
|
||||
return v.rel_parent_dir.startsWith(filter.filter_str);
|
||||
} else {
|
||||
return v.rel_parent_dir === filter.filter_str;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!v.visible) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if (this.directory_filter_str && this.directory_filter_recurse) {
|
||||
// Filter as directory with recurse shows all nested children.
|
||||
// Case sensitive comparison against the relative directory of each object.
|
||||
|
@ -594,10 +644,11 @@ class ExtraNetworksClusterizeCardsList extends ExtraNetworksClusterize {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// Narrow the filtered items based on the search string.
|
||||
// Custom filter for items marked search_only=true.
|
||||
if (v.search_only) {
|
||||
// Custom filter for items marked search_only=true.
|
||||
if (this.directory_filter_str || this.filter_str.length >= 4) {
|
||||
if (Object.keys(this.directory_filters).length || this.filter_str.length >= 4) {
|
||||
visible = v.search_terms.toLowerCase().indexOf(this.filter_str.toLowerCase()) !== -1;
|
||||
} else {
|
||||
visible = false;
|
||||
|
|
|
@ -740,7 +740,10 @@ class ExtraNetworksPage:
|
|||
parts = [x for x in node.relpath.split(os.sep) if x]
|
||||
label = os.path.join(*parts[1:])
|
||||
|
||||
data_attributes = {"data-path": f'"{node.relpath}"'}
|
||||
data_attributes = {
|
||||
"data-div-id": f'"{node.id}"',
|
||||
"data-path": f'"{node.relpath}"',
|
||||
}
|
||||
|
||||
if node.is_hidden:
|
||||
data_attributes["data-directory-filter-override"] = f'"{node.rel_from_hidden}"'
|
||||
|
|
38
style.css
38
style.css
|
@ -1531,8 +1531,7 @@ body.resizing .resize-handle {
|
|||
-ms-transform: rotate(45deg);
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
transition: transform 0.2s;
|
||||
transition-delay: 0.3s;
|
||||
transition: transform 0.1s ease;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
|
@ -1542,18 +1541,18 @@ body.resizing .resize-handle {
|
|||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.tree-list-item[data-expanded] .tree-list-item-action--chevron.pressed {
|
||||
-ms-transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.tree-list-item:not([data-expanded]) .tree-list-item-action--chevron.pressed {
|
||||
.ctrl-pressed:not(.shift-pressed) .tree-list-item-action--chevron:hover {
|
||||
-ms-transform: rotate(135deg);
|
||||
-webkit-transform: rotate(135deg);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.shift-pressed:not(.ctrl-pressed) .tree-list-item-action--chevron:hover {
|
||||
-ms-transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.tree-list-item-action--chevron .chevron-icon-single,
|
||||
.tree-list-item-action--chevron .chevron-icon-double {
|
||||
position: absolute;
|
||||
|
@ -1562,26 +1561,23 @@ body.resizing .resize-handle {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all 0.1s ease;
|
||||
transition-delay: 0.3s;
|
||||
}
|
||||
|
||||
.tree-list-item-action--chevron:not(.pressed) .chevron-icon-single {
|
||||
.tree-list-item-action--chevron .chevron-icon-single {
|
||||
opacity: 1;
|
||||
stroke: var(--input-placeholder-color);
|
||||
}
|
||||
|
||||
.tree-list-item-action--chevron.pressed .chevron-icon-double {
|
||||
:is(.ctrl-pressed:not(.shift-pressed), .shift-pressed:not(.ctrl-pressed)) .tree-list-item-action--chevron:hover .chevron-icon-double {
|
||||
opacity: 1;
|
||||
stroke: var(--button-primary-border-color);
|
||||
}
|
||||
|
||||
.tree-list-item-action--chevron.pressed .chevron-icon-single,
|
||||
.tree-list-item-action--chevron:not(.pressed) .chevron-icon-double {
|
||||
:is(.ctrl-pressed:not(.shift-pressed), .shift-pressed:not(.ctrl-pressed)) .tree-list-item-action--chevron:hover .chevron-icon-single,
|
||||
:not(.ctrl-pressed:not(.shift-pressed), .shift-pressed:not(.ctrl-pressed)) .tree-list-item-action--chevron .chevron-icon-double {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Text for button. */
|
||||
.tree-list-item-label {
|
||||
position: relative;
|
||||
|
@ -1710,12 +1706,12 @@ body.resizing .resize-handle {
|
|||
background: var(--button-secondary-background-fill-hover);
|
||||
}
|
||||
|
||||
.extra-network-dirs-view-button[data-recurse] {
|
||||
.extra-network-dirs-view-button.short-pressed:not(.long-pressed) {
|
||||
background: var(--button-primary-background-fill);
|
||||
border-color: var(--button-primary-border-color);
|
||||
}
|
||||
|
||||
.extra-network-dirs-view-button[data-recurse]:not(.pressed):hover {
|
||||
.extra-network-dirs-view-button.short-pressed:not(.long-pressed,.pressed):hover {
|
||||
-webkit-transition: all 0.05s ease-in-out;
|
||||
transition: all 0.05s ease-in-out;
|
||||
background: var(--button-primary-background-fill-hover);
|
||||
|
@ -1732,11 +1728,11 @@ body.resizing .resize-handle {
|
|||
z-index: -1;
|
||||
}
|
||||
|
||||
.extra-network-dirs-view-button:not([data-recurse])::after {
|
||||
.extra-network-dirs-view-button:not(.short-pressed:not(.long-pressed))::after {
|
||||
background: var(--button-secondary-background-fill-hover);
|
||||
}
|
||||
|
||||
.extra-network-dirs-view-button[data-recurse]::after {
|
||||
.extra-network-dirs-view-button.short-pressed:not(.long-pressed)::after {
|
||||
background: var(--button-primary-background-fill-hover);
|
||||
}
|
||||
|
||||
|
@ -1790,7 +1786,7 @@ body.resizing .resize-handle {
|
|||
transition: all 0.8s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
}
|
||||
|
||||
.tree-list-item[data-recurse] .tree-list-item-action--chevron .chevron-icon-single {
|
||||
.tree-list-item.short-pressed:not(.long-pressed) .tree-list-item-action--chevron .chevron-icon-single {
|
||||
stroke: var(--button-primary-border-color);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue