diff --git a/radicale/web/internal_data/js/scenes/CreateEditShareScene.js b/radicale/web/internal_data/js/scenes/CreateEditShareScene.js index e18b39f7..27c09cc6 100644 --- a/radicale/web/internal_data/js/scenes/CreateEditShareScene.js +++ b/radicale/web/internal_data/js/scenes/CreateEditShareScene.js @@ -204,11 +204,7 @@ export class CreateEditShareScene { if (error) { this._errorHandler.setError(error); } else { - // On any share-to-self (currently only bday conversion), invalidate the - // collections cache so the virtual calendar appears immediately. - if (this._shareuser_input.value === this._user) { - collectionsCache.invalidate(); - } + collectionsCache.invalidate(); pop_scene(); } }; diff --git a/radicale/web/internal_data/js/scenes/IncomingSharingScene.js b/radicale/web/internal_data/js/scenes/IncomingSharingScene.js index 0404a35d..47da802b 100644 --- a/radicale/web/internal_data/js/scenes/IncomingSharingScene.js +++ b/radicale/web/internal_data/js/scenes/IncomingSharingScene.js @@ -146,7 +146,7 @@ export class IncomingSharingScene { this._html_scene.classList.remove("hidden"); this._close_btn.onclick = () => pop_scene(); this._error_handler.clearError(); - collectionsCache.getIncomingShares(this._user, this._password, this._error_handler.setError, (shares) => this._render_shares(shares)); + collectionsCache.getSharingList(this._user, this._password, this._error_handler.setError, (shares) => this._render_shares(shares)); } hide() { diff --git a/radicale/web/internal_data/js/scenes/ShareCollectionScene.js b/radicale/web/internal_data/js/scenes/ShareCollectionScene.js index f2c6a392..09683cf4 100644 --- a/radicale/web/internal_data/js/scenes/ShareCollectionScene.js +++ b/radicale/web/internal_data/js/scenes/ShareCollectionScene.js @@ -22,8 +22,8 @@ import { delete_share_by_map, delete_share_by_token, - reload_sharing_list, } from "../api/sharing.js"; +import { collectionsCache } from "../utils/collections_cache.js"; import { Collection, Permission } from "../models/collection.js"; import { extract_title } from "../utils/collection_utils.js"; @@ -154,12 +154,10 @@ function update_share_list(user, password, collection, errorHandler) { } }); - reload_sharing_list(user, password, collection, function (shares, error) { - if (error) { - errorHandler.setError(error); - } else { - add_share_rows(user, password, collection, shares, errorHandler); - } + collectionsCache.getSharingList(user, password, (error) => { + errorHandler.setError(error); + }, function (shares) { + add_share_rows(user, password, collection, shares); }); } @@ -172,10 +170,9 @@ function update_share_list(user, password, collection, errorHandler) { * @param {HTMLElement} template * @param {string} delete_label * @param {function(string, string, import('../api/sharing.js').Share, function(?string):void):void} delete_action - * @param {ErrorHandler} errorHandler * @param {function():void} [onDeleteSuccess] Optional extra callback after a successful delete. */ -function add_share_row_node(user, password, collection, share, template, delete_label, delete_action, errorHandler, onDeleteSuccess) { +function add_share_row_node(user, password, collection, share, template, delete_label, delete_action, onDeleteSuccess) { let pathortoken = share["PathOrToken"] || ""; let node = /** @type {HTMLElement} */ (template.cloneNode(true)); node.classList.remove("hidden"); @@ -201,8 +198,8 @@ function add_share_row_node(user, password, collection, share, template, delete_ user, password, "Delete Share", share, delete_label + " " + pathortoken, delete_action, false, function () { if (onDeleteSuccess) onDeleteSuccess(); + collectionsCache.invalidate(); pop_scene(); - update_share_list(user, password, collection, errorHandler); } ); push_scene(delete_collection_scene); @@ -218,9 +215,8 @@ function add_share_row_node(user, password, collection, share, template, delete_ * @param {?string} password * @param {Collection} collection * @param {Array} shares - * @param {ErrorHandler} errorHandler */ -function add_share_rows(user, password, collection, shares, errorHandler) { +function add_share_rows(user, password, collection, shares) { /** @type {HTMLElement} */ let token_template = get_element(document, "[data-name=sharetokenrowtemplate]"); /** @type {HTMLElement} */ let map_template = get_element(document, "[data-name=sharemaprowtemplate]"); shares.forEach(function (share) { @@ -235,10 +231,10 @@ function add_share_rows(user, password, collection, shares, errorHandler) { decodedHref.includes(decodedPathOrToken) ) { if (share["ShareType"] === "token") { - add_share_row_node(user, password, collection, share, token_template, "share", delete_share_by_token, errorHandler); + add_share_row_node(user, password, collection, share, token_template, "share", delete_share_by_token); } else if (share["ShareType"] === "map") { - add_share_row_node(user, password, collection, share, map_template, "map", delete_share_by_map, errorHandler); + add_share_row_node(user, password, collection, share, map_template, "map", delete_share_by_map); } } }); diff --git a/radicale/web/internal_data/js/utils/collections_cache.js b/radicale/web/internal_data/js/utils/collections_cache.js index 719a3c56..d0b6e7cc 100644 --- a/radicale/web/internal_data/js/utils/collections_cache.js +++ b/radicale/web/internal_data/js/utils/collections_cache.js @@ -31,6 +31,8 @@ class CollectionsCache { this.server_features = null; /** @type {?XMLHttpRequest} */ this.collections_req = null; /** @type {?XMLHttpRequest} */ this.shares_req = null; + /** @type {?Array<{ onerror: function(string):void, displayData: function(Array):void }>} */ + this._sharing_callbacks = null; } invalidate() { @@ -45,6 +47,7 @@ class CollectionsCache { this.shares_req.abort(); this.shares_req = null; } + this._sharing_callbacks = null; } /** @@ -105,27 +108,31 @@ class CollectionsCache { * @param {function(string):void} onerror * @param {function(Array):void} displayData */ - getIncomingShares(user, password, onerror, displayData) { + getSharingList(user, password, onerror, displayData) { if (this.incoming_shares !== null) { displayData(this.incoming_shares); return; } - let loading_scene = new LoadingScene(); - push_scene(loading_scene); + if (!this._sharing_callbacks) { + this._sharing_callbacks = []; + } + this._sharing_callbacks.push({ onerror, displayData }); + + if (this.shares_req) { + return; + } this.shares_req = reload_sharing_list(user, password, null, (shares, error) => { - if (!is_current_scene(loading_scene)) { - return; - } this.shares_req = null; + let callbacks = this._sharing_callbacks || []; + this._sharing_callbacks = null; + if (error) { - onerror(error); - pop_scene(); + callbacks.forEach(cb => cb.onerror(error)); } else { this.incoming_shares = shares; - displayData(this.incoming_shares); - pop_scene(); + callbacks.forEach(cb => cb.displayData(shares)); } }); }