From 43f769b339b519b8141a4778c5f2d68c114390b0 Mon Sep 17 00:00:00 2001 From: Sj-Si Date: Tue, 16 Apr 2024 12:43:30 -0400 Subject: [PATCH] fix bug --- javascript/clusterize.js | 27 +++++++-------- javascript/extraNetworks.js | 47 ++++++++++++++++++--------- javascript/extraNetworksClusterize.js | 25 +++++++++++--- modules/ui_extra_networks.py | 8 ++++- 4 files changed, 69 insertions(+), 38 deletions(-) diff --git a/javascript/clusterize.js b/javascript/clusterize.js index a8fb03b62..9f378a4b7 100644 --- a/javascript/clusterize.js +++ b/javascript/clusterize.js @@ -28,6 +28,7 @@ class Clusterize { show_no_data_row: true, no_data_class: "clusterize-no-data", no_data_text: "No data", + loading_data_text: "Loading...", keep_parity: true, callbacks: {}, }; @@ -124,12 +125,12 @@ class Clusterize { this.setup_has_run = true; } - clear() { + clear(loading) { if (!this.setup_has_run || !this.enabled) { return; } - this.#html(this.#generateEmptyRow().join("")); + this.#html(this.#generateEmptyRow(loading).join("")); } destroy() { @@ -268,7 +269,7 @@ class Clusterize { this.options.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); } if (this.content_elem.children.length <= 1) { - cache.data = this.#html(rows[0] + rows[0] + rows[0]); + cache.data = this.#html(rows[0]); } if (!this.options.tag) { this.options.tag = this.content_elem.children[0].tagName.toLowerCase(); @@ -277,10 +278,6 @@ class Clusterize { } #recalculateDims() { - const prev_item_height = this.options.item_height; - const prev_item_width = this.options.item_width; - const prev_rows_in_block = this.options.rows_in_block; - const prev_cols_in_block = this.options.cols_in_block; const prev_options = JSON.stringify(this.options); this.options.cluster_height = 0; @@ -339,12 +336,6 @@ class Clusterize { this.#max_rows = Math.ceil(this.#max_items / this.options.cols_in_block, 10); return prev_options === JSON.stringify(this.options); - return ( - prev_item_height !== this.options.item_height || - prev_item_width !== this.options.item_width || - prev_rows_in_block !== this.options.rows_in_block || - prev_cols_in_block !== this.options.cols_in_block - ); } #getClusterNum() { @@ -355,13 +346,17 @@ class Clusterize { return Math.min(current_cluster, max_cluster); } - #generateEmptyRow() { - if (!this.options.tag || !this.options.show_no_data_row) { + #generateEmptyRow(loading) { + // If loading==true, then we use the loading text for our element. Defaults to false. + loading = loading === true; + if (!loading && (!this.options.tag || !this.options.show_no_data_row)) { return []; } + const text = loading ? this.options.loading_data_text : this.options.no_data_text; + const empty_row = document.createElement(this.options.tag); - const no_data_content = document.createTextNode(this.options.no_data_text); + const no_data_content = document.createTextNode(text); empty_row.className = this.options.no_data_class; if (this.options.tag === "tr") { const td = document.createElement("td"); diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index d58342779..3d56024de 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -19,6 +19,7 @@ const SEARCH_INPUT_DEBOUNCE_TIME_MS = 250; const EXTRA_NETWORKS_GET_PAGE_READY_MAX_ATTEMPTS = 10; const EXTRA_NETWORKS_REQUEST_GET_TIMEOUT_MS = 1000; +const EXTRA_NETWORKS_REFRESH_INTERNAL_DEBOUNCE_TIMEOUT_MS = 200; const re_extranet = /<([^:^>]+:[^:]+):[\d.]+>(.*)/; const re_extranet_g = /<([^:^>]+:[^:]+):[\d.]+>/g; @@ -29,6 +30,8 @@ var globalPopupInner = null; const storedPopupIds = {}; const extraPageUserMetadataEditors = {}; const extra_networks_tabs = {}; +var extra_networks_refresh_internal_debounce_timer; + /** Boolean flags used along with utils.js::waitForBool(). */ // Set true when we first load the UI options. const initialUiOptionsLoaded = {state: false}; @@ -52,6 +55,7 @@ class ExtraNetworksTab { show_prompt = true; show_neg_prompt = true; compact_prompt_en = false; + refresh_in_progress = false; constructor({tabname, extra_networks_tabname}) { this.tabname = tabname; this.extra_networks_tabname = extra_networks_tabname; @@ -84,8 +88,7 @@ class ExtraNetworksTab { this.controls_elem.id = `${this.tabname_full}_controls`; controls_div.insertBefore(this.controls_elem, null); - await this.setupTreeList(); - await this.setupCardsList(); + await Promise.all([this.setupTreeList(), this.setupCardsList()]); const sort_mode_elem = this.controls_elem.querySelector(".extra-network-control--sort-mode[data-selected='']"); isElementThrowError(sort_mode_elem); @@ -121,6 +124,7 @@ class ExtraNetworksTab { this.txt_prompt_elem = null; this.txt_neg_prompt_elem = null; this.active_prompt_elem = null; + this.refresh_in_progress = false; } async registerPrompt() { @@ -225,7 +229,7 @@ class ExtraNetworksTab { this.controls_elem.classList.add("hidden"); } - async refresh() { + async #refresh() { const btn_dirs_view = this.controls_elem.querySelector(".extra-network-control--dirs-view"); const btn_tree_view = this.controls_elem.querySelector(".extra-network-control--tree-view"); const div_dirs = this.container_elem.querySelector(".extra-network-content--dirs-view"); @@ -240,8 +244,8 @@ class ExtraNetworksTab { div_tree.classList.toggle("hidden", !("selected" in btn_tree_view.dataset)); await Promise.all([this.setupTreeList(), this.setupCardsList()]); - this.tree_list.enable(); - this.cards_list.enable(); + this.tree_list.enable(true); + this.cards_list.enable(true); await Promise.all([this.tree_list.load(true), this.cards_list.load(true)]); // apply the previous sort/filter options this.setSortMode(this.sort_mode_str); @@ -249,6 +253,15 @@ class ExtraNetworksTab { this.setFilterStr(this.filter_str); } + async refresh() { + if (this.refresh_in_progress) { + return; + } + this.refresh_in_progress = true; + await this.#refresh(); + this.refresh_in_progress = false; + } + async load(show_prompt, show_neg_prompt) { this.movePrompt(show_prompt, show_neg_prompt); this.showControls(); @@ -639,9 +652,9 @@ function extraNetworksRefreshSingleCard(tabname, extra_networks_tabname, name) { tab.refreshSingleCard(name); } -async function extraNetworksRefreshTab(tabname_full) { +function extraNetworksRefreshTab(tabname_full) { /** called from python when user clicks the extra networks refresh tab button */ - await extra_networks_tabs[tabname_full].refresh(); + extra_networks_tabs[tabname_full].refresh(); } // ==== EVENT HANDLING ==== @@ -832,15 +845,17 @@ function extraNetworksControlRefreshOnClick(event, tabname_full) { * event handler that refreshes the page. So what this function here does * is it manually raises a `click` event on that button. */ - // We want to reset all tabs lists on refresh click so that the viewing area - // shows that it is loading new data. - for (const tab of Object.values(extra_networks_tabs)) { - tab.tree_list.destroy(); - tab.cards_list.destroy(); - } - - // Fire an event for this button click. - gradioApp().getElementById(`${tabname_full}_extra_refresh_internal`).dispatchEvent(new Event("click")); + clearTimeout(extra_networks_refresh_internal_debounce_timer); + extra_networks_refresh_internal_debounce_timer = setTimeout(() => { + // We want to reset all tabs lists on refresh click so that the viewing area + // shows that it is loading new data. + for (const tab of Object.values(extra_networks_tabs)) { + tab.tree_list.clear(); + tab.cards_list.clear(); + } + // Fire an event for this button click. + gradioApp().getElementById(`${tabname_full}_extra_refresh_internal`).dispatchEvent(new Event("click")); + }, EXTRA_NETWORKS_REFRESH_INTERNAL_DEBOUNCE_TIMEOUT_MS); } function extraNetworksCardOnClick(event, tabname_full) { diff --git a/javascript/extraNetworksClusterize.js b/javascript/extraNetworksClusterize.js index 66c6fac6e..e7ea46f78 100644 --- a/javascript/extraNetworksClusterize.js +++ b/javascript/extraNetworksClusterize.js @@ -86,20 +86,22 @@ class ExtraNetworksClusterize extends Clusterize { } destroy() { + this.data_obj = {}; + this.data_obj_keys_sorted = []; if (this.lru instanceof LRUCache) { this.lru.destroy(); this.lru = null; } - this.data_obj = {}; - this.data_obj_keys_sorted = []; super.destroy(); } clear() { this.data_obj = {}; this.data_obj_keys_sorted = []; - this.lru.clear(); - super.clear(); + if (this.lru instanceof LRUCache) { + this.lru.clear(); + } + super.clear(true); } async load(force_init_data) { @@ -170,6 +172,9 @@ class ExtraNetworksClusterize extends Clusterize { if (isNullOrUndefinedLogError(this.lru)) { return []; } + if (Object.keys(this.data_obj).length === 0) { + return []; + } const lru_keys = Array.from(this.lru.cache.keys()); const cached_div_ids = div_ids.filter(x => lru_keys.includes(x)); const missing_div_ids = div_ids.filter(x => !lru_keys.includes(x)); @@ -185,6 +190,9 @@ class ExtraNetworksClusterize extends Clusterize { // Now load any cached IDs from the LRU Cache for (const div_id of cached_div_ids) { + if (!keyExistsLogError(this.data_obj, div_id)) { + continue; + } if (this.data_obj[div_id].visible) { data[div_id] = this.lru.get(div_id); } @@ -222,7 +230,7 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize { clear() { this.selected_div_id = null; - super.clear(); + super.clear(true); } getBoxShadow(depth) { @@ -363,6 +371,10 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize { return []; } + if (Object.keys(this.data_obj).length === 0) { + return []; + } + const data = await this.fetchDivIds(this.idxRangeToDivIds(idx_start, idx_end)); const data_ids_sorted = Object.keys(data).sort((a, b) => { return this.data_obj_keys_sorted.indexOf(a) - this.data_obj_keys_sorted.indexOf(b); @@ -375,6 +387,9 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize { const res = []; for (const div_id of data_ids_sorted) { + if (!keyExistsLogError(this.data_obj, div_id)) { + continue; + } const html_str = data[div_id]; const parsed_html = isElement(html_str) ? html_str : htmlStringToElement(html_str); const depth = Number(parsed_html.dataset.depth); diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 80e0c38d2..498cb2a51 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -1080,7 +1080,13 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname): return ui.pages_contents button_refresh = gr.Button("Refresh", elem_id=f"{tabname}_{page.extra_networks_tabname}_extra_refresh_internal", visible=False) - button_refresh.click(fn=refresh, inputs=[], outputs=ui.pages,).then(fn=lambda: None, _js="setupAllResizeHandles").then( + button_refresh.click( + fn=refresh, + inputs=[], + outputs=ui.pages, + ).then( + fn=lambda: None, _js="setupAllResizeHandles" + ).then( fn=lambda: None, _js=f"function(){{extraNetworksRefreshTab('{tabname}_{page.extra_networks_tabname}');}}", )