UI: Re-use sharing cache for individual shares

This should reduce network usage in some situations.
This commit is contained in:
Max Berger
2026-04-30 13:23:36 +02:00
parent 802da14519
commit 7eafbe943b
4 changed files with 29 additions and 30 deletions

View File

@@ -204,11 +204,7 @@ export class CreateEditShareScene {
if (error) { if (error) {
this._errorHandler.setError(error); this._errorHandler.setError(error);
} else { } else {
// On any share-to-self (currently only bday conversion), invalidate the collectionsCache.invalidate();
// collections cache so the virtual calendar appears immediately.
if (this._shareuser_input.value === this._user) {
collectionsCache.invalidate();
}
pop_scene(); pop_scene();
} }
}; };

View File

@@ -146,7 +146,7 @@ export class IncomingSharingScene {
this._html_scene.classList.remove("hidden"); this._html_scene.classList.remove("hidden");
this._close_btn.onclick = () => pop_scene(); this._close_btn.onclick = () => pop_scene();
this._error_handler.clearError(); 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() { hide() {

View File

@@ -22,8 +22,8 @@
import { import {
delete_share_by_map, delete_share_by_map,
delete_share_by_token, delete_share_by_token,
reload_sharing_list,
} from "../api/sharing.js"; } from "../api/sharing.js";
import { collectionsCache } from "../utils/collections_cache.js";
import { Collection, Permission } from "../models/collection.js"; import { Collection, Permission } from "../models/collection.js";
import { extract_title } from "../utils/collection_utils.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) { collectionsCache.getSharingList(user, password, (error) => {
if (error) { errorHandler.setError(error);
errorHandler.setError(error); }, function (shares) {
} else { add_share_rows(user, password, collection, shares);
add_share_rows(user, password, collection, shares, errorHandler);
}
}); });
} }
@@ -172,10 +170,9 @@ function update_share_list(user, password, collection, errorHandler) {
* @param {HTMLElement} template * @param {HTMLElement} template
* @param {string} delete_label * @param {string} delete_label
* @param {function(string, string, import('../api/sharing.js').Share, function(?string):void):void} delete_action * @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. * @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 pathortoken = share["PathOrToken"] || "";
let node = /** @type {HTMLElement} */ (template.cloneNode(true)); let node = /** @type {HTMLElement} */ (template.cloneNode(true));
node.classList.remove("hidden"); 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, user, password, "Delete Share", share, delete_label + " " + pathortoken, delete_action, false,
function () { function () {
if (onDeleteSuccess) onDeleteSuccess(); if (onDeleteSuccess) onDeleteSuccess();
collectionsCache.invalidate();
pop_scene(); pop_scene();
update_share_list(user, password, collection, errorHandler);
} }
); );
push_scene(delete_collection_scene); push_scene(delete_collection_scene);
@@ -218,9 +215,8 @@ function add_share_row_node(user, password, collection, share, template, delete_
* @param {?string} password * @param {?string} password
* @param {Collection} collection * @param {Collection} collection
* @param {Array<import('../api/sharing.js').Share>} shares * @param {Array<import('../api/sharing.js').Share>} 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 token_template = get_element(document, "[data-name=sharetokenrowtemplate]");
/** @type {HTMLElement} */ let map_template = get_element(document, "[data-name=sharemaprowtemplate]"); /** @type {HTMLElement} */ let map_template = get_element(document, "[data-name=sharemaprowtemplate]");
shares.forEach(function (share) { shares.forEach(function (share) {
@@ -235,10 +231,10 @@ function add_share_rows(user, password, collection, shares, errorHandler) {
decodedHref.includes(decodedPathOrToken) decodedHref.includes(decodedPathOrToken)
) { ) {
if (share["ShareType"] === "token") { 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") { 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);
} }
} }
}); });

View File

@@ -31,6 +31,8 @@ class CollectionsCache {
this.server_features = null; this.server_features = null;
/** @type {?XMLHttpRequest} */ this.collections_req = null; /** @type {?XMLHttpRequest} */ this.collections_req = null;
/** @type {?XMLHttpRequest} */ this.shares_req = null; /** @type {?XMLHttpRequest} */ this.shares_req = null;
/** @type {?Array<{ onerror: function(string):void, displayData: function(Array<import("../api/sharing.js").Share>):void }>} */
this._sharing_callbacks = null;
} }
invalidate() { invalidate() {
@@ -45,6 +47,7 @@ class CollectionsCache {
this.shares_req.abort(); this.shares_req.abort();
this.shares_req = null; this.shares_req = null;
} }
this._sharing_callbacks = null;
} }
/** /**
@@ -105,27 +108,31 @@ class CollectionsCache {
* @param {function(string):void} onerror * @param {function(string):void} onerror
* @param {function(Array<import("../api/sharing.js").Share>):void} displayData * @param {function(Array<import("../api/sharing.js").Share>):void} displayData
*/ */
getIncomingShares(user, password, onerror, displayData) { getSharingList(user, password, onerror, displayData) {
if (this.incoming_shares !== null) { if (this.incoming_shares !== null) {
displayData(this.incoming_shares); displayData(this.incoming_shares);
return; return;
} }
let loading_scene = new LoadingScene(); if (!this._sharing_callbacks) {
push_scene(loading_scene); 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) => { this.shares_req = reload_sharing_list(user, password, null, (shares, error) => {
if (!is_current_scene(loading_scene)) {
return;
}
this.shares_req = null; this.shares_req = null;
let callbacks = this._sharing_callbacks || [];
this._sharing_callbacks = null;
if (error) { if (error) {
onerror(error); callbacks.forEach(cb => cb.onerror(error));
pop_scene();
} else { } else {
this.incoming_shares = shares; this.incoming_shares = shares;
displayData(this.incoming_shares); callbacks.forEach(cb => cb.displayData(shares));
pop_scene();
} }
}); });
} }