Unified data cache into single utility class
This commit is contained in:
@@ -34,9 +34,6 @@ import { CollectionType } from "../models/collection.js";
|
|||||||
* @property {SharingFeatures} [sharing]
|
* @property {SharingFeatures} [sharing]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @type {ServerFeatures} */
|
|
||||||
export let server_features = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
@@ -95,7 +92,7 @@ function call_sharing_api(
|
|||||||
/**
|
/**
|
||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {function():void} callback
|
* @param {function(import("../api/sharing.js").ServerFeatures, ?string):void} callback
|
||||||
*/
|
*/
|
||||||
export function discover_server_features(user, password, callback) {
|
export function discover_server_features(user, password, callback) {
|
||||||
call_sharing_api(
|
call_sharing_api(
|
||||||
@@ -104,16 +101,19 @@ export function discover_server_features(user, password, callback) {
|
|||||||
"all/info",
|
"all/info",
|
||||||
{},
|
{},
|
||||||
function (response) {
|
function (response) {
|
||||||
server_features["sharing"] = JSON.parse(response);
|
try {
|
||||||
callback();
|
let features = { "sharing": JSON.parse(response) };
|
||||||
|
callback(features, null);
|
||||||
|
} catch (e) {
|
||||||
|
callback({}, e.message);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
// sharing is disabled on the server
|
// sharing is disabled on the server
|
||||||
server_features["sharing"] = {};
|
callback({ "sharing": {} }, null);
|
||||||
callback();
|
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.error("Failed to discover sharing features: " + error);
|
callback({}, error);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ export class Share {
|
|||||||
*/
|
*/
|
||||||
export function reload_sharing_list(user, password, collection, callback) {
|
export function reload_sharing_list(user, password, collection, callback) {
|
||||||
let body = collection ? { PathMapped: collection.href } : {};
|
let body = collection ? { PathMapped: collection.href } : {};
|
||||||
call_sharing_api(
|
return call_sharing_api(
|
||||||
user,
|
user,
|
||||||
password,
|
password,
|
||||||
"all/list",
|
"all/list",
|
||||||
@@ -160,7 +160,7 @@ export function reload_sharing_list(user, password, collection, callback) {
|
|||||||
null, // on_not_found
|
null, // on_not_found
|
||||||
function (error) {
|
function (error) {
|
||||||
callback([], error);
|
callback([], error);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,17 +19,14 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { get_collections } from "../api/api.js";
|
|
||||||
import { discover_server_features } from "../api/sharing.js";
|
|
||||||
|
|
||||||
import { SERVER } from "../constants.js";
|
import { SERVER } from "../constants.js";
|
||||||
import { Collection, CollectionType } from "../models/collection.js";
|
import { Collection, CollectionType } from "../models/collection.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { bytesToHumanReadable } from "../utils/misc.js";
|
import { bytesToHumanReadable } from "../utils/misc.js";
|
||||||
import { CreateEditCollectionScene } from "./CreateEditCollectionScene.js";
|
import { CreateEditCollectionScene } from "./CreateEditCollectionScene.js";
|
||||||
import { DeleteCollectionScene } from "./DeleteCollectionScene.js";
|
import { DeleteCollectionScene } from "./DeleteCollectionScene.js";
|
||||||
import { IncomingSharingScene } from "./IncomingSharingScene.js";
|
import { IncomingSharingScene } from "./IncomingSharingScene.js";
|
||||||
import { LoadingScene } from "./LoadingScene.js";
|
import { Scene, push_scene } from "./scene_manager.js";
|
||||||
import { Scene, is_current_scene, pop_scene, push_scene } from "./scene_manager.js";
|
|
||||||
import { ShareCollectionScene, maybe_enable_sharing_options } from "./ShareCollectionScene.js";
|
import { ShareCollectionScene, maybe_enable_sharing_options } from "./ShareCollectionScene.js";
|
||||||
import { UploadCollectionScene } from "./UploadCollectionScene.js";
|
import { UploadCollectionScene } from "./UploadCollectionScene.js";
|
||||||
|
|
||||||
@@ -51,8 +48,6 @@ export class CollectionsScene {
|
|||||||
/** @type {HTMLElement} */ let upload_btn = html_scene.querySelector("[data-name=upload]");
|
/** @type {HTMLElement} */ let upload_btn = html_scene.querySelector("[data-name=upload]");
|
||||||
/** @type {HTMLElement} */ let incomingshares_btn = html_scene.querySelector("[data-name=incomingshares]");
|
/** @type {HTMLElement} */ let incomingshares_btn = html_scene.querySelector("[data-name=incomingshares]");
|
||||||
|
|
||||||
/** @type {?XMLHttpRequest} */ let collections_req = null;
|
|
||||||
/** @type {?Array<Collection>} */ let child_collections = null;
|
|
||||||
/** @type {Array<HTMLElement>} */ let nodes = [];
|
/** @type {Array<HTMLElement>} */ let nodes = [];
|
||||||
|
|
||||||
function onnew() {
|
function onnew() {
|
||||||
@@ -132,6 +127,13 @@ export class CollectionsScene {
|
|||||||
let heightOfNavBar = navBar.offsetHeight + "px";
|
let heightOfNavBar = navBar.offsetHeight + "px";
|
||||||
html_scene.style.marginTop = heightOfNavBar;
|
html_scene.style.marginTop = heightOfNavBar;
|
||||||
html_scene.style.height = "calc(100vh - " + heightOfNavBar + ")";
|
html_scene.style.height = "calc(100vh - " + heightOfNavBar + ")";
|
||||||
|
|
||||||
|
// Clear old nodes
|
||||||
|
nodes.forEach(function (node) {
|
||||||
|
node.parentNode.removeChild(node);
|
||||||
|
});
|
||||||
|
nodes = [];
|
||||||
|
|
||||||
collections.forEach(function (/** @type {Collection} */ collection) {
|
collections.forEach(function (/** @type {Collection} */ collection) {
|
||||||
/** @type {HTMLElement} */ let node = /** @type {HTMLElement} */(template.cloneNode(true));
|
/** @type {HTMLElement} */ let node = /** @type {HTMLElement} */(template.cloneNode(true));
|
||||||
node.classList.remove("hidden");
|
node.classList.remove("hidden");
|
||||||
@@ -192,43 +194,20 @@ export class CollectionsScene {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
|
||||||
let loading_scene = new LoadingScene();
|
|
||||||
push_scene(loading_scene);
|
|
||||||
collections_req = get_collections(user, password, principal_collection, function (child_collections_, error) {
|
|
||||||
if (!is_current_scene(loading_scene)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
collections_req = null;
|
|
||||||
if (error) {
|
|
||||||
onerror(error);
|
|
||||||
pop_scene();
|
|
||||||
} else {
|
|
||||||
child_collections = child_collections_;
|
|
||||||
pop_scene();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.show = function () {
|
this.show = function () {
|
||||||
html_scene.classList.remove("hidden");
|
html_scene.classList.remove("hidden");
|
||||||
new_btn.onclick = onnew;
|
new_btn.onclick = onnew;
|
||||||
upload_btn.onclick = onupload;
|
upload_btn.onclick = onupload;
|
||||||
incomingshares_btn.onclick = onincomingshares;
|
incomingshares_btn.onclick = onincomingshares;
|
||||||
if (child_collections === null) {
|
collectionsCache.getChildCollections(user, password, principal_collection, onerror, show_collections);
|
||||||
update();
|
collectionsCache.getServerFeatures(user, password, null, maybe_enable_sharing_options);
|
||||||
discover_server_features(user, password, maybe_enable_sharing_options);
|
|
||||||
} else {
|
|
||||||
// from update loading scene
|
|
||||||
show_collections(child_collections);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this.hide = function () {
|
this.hide = function () {
|
||||||
html_scene.classList.add("hidden");
|
html_scene.classList.add("hidden");
|
||||||
new_btn.onclick = null;
|
new_btn.onclick = null;
|
||||||
upload_btn.onclick = null;
|
upload_btn.onclick = null;
|
||||||
incomingshares_btn.onclick = null;
|
incomingshares_btn.onclick = null;
|
||||||
child_collections = null;
|
|
||||||
// remove collection
|
// remove collection
|
||||||
nodes.forEach(function (node) {
|
nodes.forEach(function (node) {
|
||||||
node.parentNode.removeChild(node);
|
node.parentNode.removeChild(node);
|
||||||
@@ -236,11 +215,6 @@ export class CollectionsScene {
|
|||||||
nodes = [];
|
nodes = [];
|
||||||
};
|
};
|
||||||
this.release = function () {
|
this.release = function () {
|
||||||
if (collections_req !== null) {
|
|
||||||
collections_req.abort();
|
|
||||||
collections_req = null;
|
|
||||||
}
|
|
||||||
child_collections = null;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
import { create_collection, edit_collection } from "../api/api.js";
|
import { create_collection, edit_collection } from "../api/api.js";
|
||||||
import { COLOR_RE } from "../constants.js";
|
import { COLOR_RE } from "../constants.js";
|
||||||
import { Collection, CollectionType } from "../models/collection.js";
|
import { Collection, CollectionType } from "../models/collection.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { ErrorHandler } from "../utils/error.js";
|
import { ErrorHandler } from "../utils/error.js";
|
||||||
import { FormValidator, validate_color, validate_href } from "../utils/form_validator.js";
|
import { FormValidator, validate_color, validate_href } from "../utils/form_validator.js";
|
||||||
import { cleanHREFinput, onCleanHREFinput, random_hex, random_uuid } from "../utils/misc.js";
|
import { cleanHREFinput, onCleanHREFinput, random_hex, random_uuid } from "../utils/misc.js";
|
||||||
@@ -140,6 +141,7 @@ export class CreateEditCollectionScene {
|
|||||||
errorHandler.setError(error1);
|
errorHandler.setError(error1);
|
||||||
pop_scene();
|
pop_scene();
|
||||||
} else {
|
} else {
|
||||||
|
collectionsCache.invalidate();
|
||||||
pop_to_parent();
|
pop_to_parent();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
import { delete_collection } from "../api/api.js";
|
import { delete_collection } from "../api/api.js";
|
||||||
import { DELETE_CONFIRMATION_TEXT } from "../constants.js";
|
import { DELETE_CONFIRMATION_TEXT } from "../constants.js";
|
||||||
import { Collection } from "../models/collection.js";
|
import { Collection } from "../models/collection.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { ErrorHandler } from "../utils/error.js";
|
import { ErrorHandler } from "../utils/error.js";
|
||||||
import { FormValidator, validate_equals } from "../utils/form_validator.js";
|
import { FormValidator, validate_equals } from "../utils/form_validator.js";
|
||||||
import { LoadingScene } from "./LoadingScene.js";
|
import { LoadingScene } from "./LoadingScene.js";
|
||||||
@@ -72,6 +73,7 @@ export class DeleteCollectionScene {
|
|||||||
errorHandler.setError(error1);
|
errorHandler.setError(error1);
|
||||||
pop_scene();
|
pop_scene();
|
||||||
} else {
|
} else {
|
||||||
|
collectionsCache.invalidate();
|
||||||
pop_to_parent();
|
pop_to_parent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,11 +19,11 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Share, reload_sharing_list, update_incoming_share } from "../api/sharing.js";
|
import { update_incoming_share } from "../api/sharing.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { ErrorHandler } from "../utils/error.js";
|
import { ErrorHandler } from "../utils/error.js";
|
||||||
import { displayPermissions } from "../utils/permissions.js";
|
import { displayPermissions } from "../utils/permissions.js";
|
||||||
import { LoadingScene } from "./LoadingScene.js";
|
import { Scene, pop_scene } from "./scene_manager.js";
|
||||||
import { Scene, is_current_scene, pop_scene, push_scene } from "./scene_manager.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements {Scene}
|
* @implements {Scene}
|
||||||
@@ -45,14 +45,13 @@ export class IncomingSharingScene {
|
|||||||
let error_handler = new ErrorHandler(error_element);
|
let error_handler = new ErrorHandler(error_element);
|
||||||
|
|
||||||
/** @type {Array<HTMLElement>} */ let nodes = [];
|
/** @type {Array<HTMLElement>} */ let nodes = [];
|
||||||
/** @type {?Array<Object>} */ let shares_cache = null;
|
|
||||||
|
|
||||||
function on_cancel() {
|
function on_cancel() {
|
||||||
pop_scene();
|
pop_scene();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Share} share
|
* @param {import("../api/sharing.js").Share} share
|
||||||
* @param {HTMLElement} node
|
* @param {HTMLElement} node
|
||||||
*/
|
*/
|
||||||
function toggle_share(share, node) {
|
function toggle_share(share, node) {
|
||||||
@@ -79,12 +78,14 @@ export class IncomingSharingScene {
|
|||||||
enabled_cb.checked = old_enabled;
|
enabled_cb.checked = old_enabled;
|
||||||
shown_cb.checked = !old_hidden;
|
shown_cb.checked = !old_hidden;
|
||||||
shown_cb.disabled = !old_enabled;
|
shown_cb.disabled = !old_enabled;
|
||||||
|
} else {
|
||||||
|
collectionsCache.invalidate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Share[]} shares
|
* @param {import("../api/sharing.js").Share[]} shares
|
||||||
*/
|
*/
|
||||||
function render_shares(shares) {
|
function render_shares(shares) {
|
||||||
// clear old nodes
|
// clear old nodes
|
||||||
@@ -138,34 +139,11 @@ export class IncomingSharingScene {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
|
||||||
let loading_scene = new LoadingScene();
|
|
||||||
push_scene(loading_scene);
|
|
||||||
|
|
||||||
error_handler.clearError();
|
|
||||||
|
|
||||||
reload_sharing_list(user, password, null, function (shares, error) {
|
|
||||||
if (!is_current_scene(loading_scene)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
error_handler.setError(error);
|
|
||||||
pop_scene();
|
|
||||||
} else {
|
|
||||||
shares_cache = shares;
|
|
||||||
pop_scene();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.show = function () {
|
this.show = function () {
|
||||||
html_scene.classList.remove("hidden");
|
html_scene.classList.remove("hidden");
|
||||||
cancel_btn.onclick = on_cancel;
|
cancel_btn.onclick = on_cancel;
|
||||||
if (shares_cache === null) {
|
error_handler.clearError();
|
||||||
update();
|
collectionsCache.getIncomingShares(user, password, error_handler.setError, render_shares);
|
||||||
} else {
|
|
||||||
render_shares(shares_cache);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hide = function () {
|
this.hide = function () {
|
||||||
@@ -182,7 +160,6 @@ export class IncomingSharingScene {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
nodes = [];
|
nodes = [];
|
||||||
shares_cache = null;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { get_principal } from "../api/api.js";
|
import { get_principal } from "../api/api.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { ErrorHandler } from "../utils/error.js";
|
import { ErrorHandler } from "../utils/error.js";
|
||||||
import { FormValidator, validate_non_empty } from "../utils/form_validator.js";
|
import { FormValidator, validate_non_empty } from "../utils/form_validator.js";
|
||||||
import { CollectionsScene } from "./CollectionsScene.js";
|
import { CollectionsScene } from "./CollectionsScene.js";
|
||||||
@@ -58,6 +59,7 @@ export class LoginScene {
|
|||||||
|
|
||||||
function onlogin() {
|
function onlogin() {
|
||||||
try {
|
try {
|
||||||
|
collectionsCache.invalidate();
|
||||||
read_form();
|
read_form();
|
||||||
let password = password_form.value;
|
let password = password_form.value;
|
||||||
if (!validator.validate()) {
|
if (!validator.validate()) {
|
||||||
@@ -99,6 +101,7 @@ export class LoginScene {
|
|||||||
|
|
||||||
let onlogout = function () {
|
let onlogout = function () {
|
||||||
try {
|
try {
|
||||||
|
collectionsCache.invalidate();
|
||||||
user = "";
|
user = "";
|
||||||
pop_to_root();
|
pop_to_root();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -118,6 +121,7 @@ export class LoginScene {
|
|||||||
function refresh() {
|
function refresh() {
|
||||||
// The easiest way to refresh is to push a LoadingScene onto the stack and then pop it
|
// The easiest way to refresh is to push a LoadingScene onto the stack and then pop it
|
||||||
// forcing the scene below it, the Collections Scene to refresh itself.
|
// forcing the scene below it, the Collections Scene to refresh itself.
|
||||||
|
collectionsCache.invalidate();
|
||||||
push_scene(new LoadingScene());
|
push_scene(new LoadingScene());
|
||||||
pop_scene();
|
pop_scene();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ import {
|
|||||||
delete_share_by_map,
|
delete_share_by_map,
|
||||||
delete_share_by_token,
|
delete_share_by_token,
|
||||||
reload_sharing_list,
|
reload_sharing_list,
|
||||||
server_features,
|
|
||||||
} from "../api/sharing.js";
|
} from "../api/sharing.js";
|
||||||
import { Collection } from "../models/collection.js";
|
import { Collection } from "../models/collection.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { ErrorHandler } from "../utils/error.js";
|
import { ErrorHandler } from "../utils/error.js";
|
||||||
import { displayPermissions } from "../utils/permissions.js";
|
import { displayPermissions } from "../utils/permissions.js";
|
||||||
import { CreateEditShareScene } from "./CreateEditShareScene.js";
|
import { CreateEditShareScene } from "./CreateEditShareScene.js";
|
||||||
@@ -86,35 +86,38 @@ export class ShareCollectionScene {
|
|||||||
this.release();
|
this.release();
|
||||||
html_scene.classList.remove("hidden");
|
html_scene.classList.remove("hidden");
|
||||||
cancel_btn.onclick = oncancel;
|
cancel_btn.onclick = oncancel;
|
||||||
if (server_features.sharing && server_features.sharing.PermittedCreateCollectionByToken) {
|
|
||||||
if (share_by_token_btn) {
|
collectionsCache.getServerFeatures(user, password, errorHandler.setError, (features) => {
|
||||||
share_by_token_btn.classList.remove("hidden");
|
if (features.sharing && features.sharing.PermittedCreateCollectionByToken) {
|
||||||
share_by_token_btn.onclick = onsharebytoken;
|
if (share_by_token_btn) {
|
||||||
|
share_by_token_btn.classList.remove("hidden");
|
||||||
|
share_by_token_btn.onclick = onsharebytoken;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (share_by_token_btn) share_by_token_btn.classList.add("hidden");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (share_by_token_btn) share_by_token_btn.classList.add("hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server_features.sharing && server_features.sharing.FeatureEnabledCollectionByToken) {
|
if (features.sharing && features.sharing.FeatureEnabledCollectionByToken) {
|
||||||
if (share_by_token_div) share_by_token_div.classList.remove("hidden");
|
if (share_by_token_div) share_by_token_div.classList.remove("hidden");
|
||||||
} else {
|
} else {
|
||||||
if (share_by_token_div) share_by_token_div.classList.add("hidden");
|
if (share_by_token_div) share_by_token_div.classList.add("hidden");
|
||||||
}
|
|
||||||
|
|
||||||
if (server_features.sharing && server_features.sharing.PermittedCreateCollectionByMap) {
|
|
||||||
if (share_by_map_btn) {
|
|
||||||
share_by_map_btn.classList.remove("hidden");
|
|
||||||
share_by_map_btn.onclick = onsharebymap;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (share_by_map_btn) share_by_map_btn.classList.add("hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server_features.sharing && server_features.sharing.FeatureEnabledCollectionByMap) {
|
if (features.sharing && features.sharing.PermittedCreateCollectionByMap) {
|
||||||
if (share_by_map_div) share_by_map_div.classList.remove("hidden");
|
if (share_by_map_btn) {
|
||||||
} else {
|
share_by_map_btn.classList.remove("hidden");
|
||||||
if (share_by_map_div) share_by_map_div.classList.add("hidden");
|
share_by_map_btn.onclick = onsharebymap;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (share_by_map_btn) share_by_map_btn.classList.add("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (features.sharing && features.sharing.FeatureEnabledCollectionByMap) {
|
||||||
|
if (share_by_map_div) share_by_map_div.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
if (share_by_map_div) share_by_map_div.classList.add("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
title.textContent = collection.displayname || collection.href;
|
title.textContent = collection.displayname || collection.href;
|
||||||
update_share_list(user, password, collection, errorHandler);
|
update_share_list(user, password, collection, errorHandler);
|
||||||
@@ -231,10 +234,13 @@ function add_share_rows(user, password, collection, shares, errorHandler) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function maybe_enable_sharing_options() {
|
/**
|
||||||
if (!server_features.sharing) return;
|
* @param {import('../api/sharing.js').ServerFeatures} features
|
||||||
let map_is_enabled = server_features.sharing.FeatureEnabledCollectionByMap || false;
|
*/
|
||||||
let token_is_enabled = server_features.sharing.FeatureEnabledCollectionByToken || false;
|
export function maybe_enable_sharing_options(features) {
|
||||||
|
if (!features || !features.sharing) return;
|
||||||
|
let map_is_enabled = features.sharing.FeatureEnabledCollectionByMap || false;
|
||||||
|
let token_is_enabled = features.sharing.FeatureEnabledCollectionByToken || false;
|
||||||
if (map_is_enabled || token_is_enabled) {
|
if (map_is_enabled || token_is_enabled) {
|
||||||
let share_options = document.querySelectorAll("[data-name=shareoption]");
|
let share_options = document.querySelectorAll("[data-name=shareoption]");
|
||||||
for (let i = 0; i < share_options.length; i++) {
|
for (let i = 0; i < share_options.length; i++) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import { upload_collection } from "../api/api.js";
|
import { upload_collection } from "../api/api.js";
|
||||||
import { Collection } from "../models/collection.js";
|
import { Collection } from "../models/collection.js";
|
||||||
|
import { collectionsCache } from "../utils/collections_cache.js";
|
||||||
import { ErrorHandler } from "../utils/error.js";
|
import { ErrorHandler } from "../utils/error.js";
|
||||||
import { FormValidator, validate_files, validate_href } from "../utils/form_validator.js";
|
import { FormValidator, validate_files, validate_href } from "../utils/form_validator.js";
|
||||||
import { cleanHREFinput, onCleanHREFinput, random_uuid } from "../utils/misc.js";
|
import { cleanHREFinput, onCleanHREFinput, random_uuid } from "../utils/misc.js";
|
||||||
@@ -127,6 +128,9 @@ export class UploadCollectionScene {
|
|||||||
|
|
||||||
function onclose() {
|
function onclose() {
|
||||||
try {
|
try {
|
||||||
|
if (results.length > 0) {
|
||||||
|
collectionsCache.invalidate();
|
||||||
|
}
|
||||||
pop_scene();
|
pop_scene();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
154
radicale/web/internal_data/js/utils/collections_cache.js
Normal file
154
radicale/web/internal_data/js/utils/collections_cache.js
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of Radicale Server - Calendar Server
|
||||||
|
* Copyright © 2017-2024 Unrud <unrud@outlook.com>
|
||||||
|
* Copyright © 2023-2024 Matthew Hana <matthew.hana@gmail.com>
|
||||||
|
* Copyright © 2024-2025 Peter Bieringer <pb@bieringer.de>
|
||||||
|
* Copyright © 2026-2026 Max Berger <max@berger.name>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { get_collections } from "../api/api.js";
|
||||||
|
import { discover_server_features, reload_sharing_list } from "../api/sharing.js";
|
||||||
|
import { LoadingScene } from "../scenes/LoadingScene.js";
|
||||||
|
import { is_current_scene, pop_scene, push_scene } from "../scenes/scene_manager.js";
|
||||||
|
|
||||||
|
class CollectionsCache {
|
||||||
|
constructor() {
|
||||||
|
this.child_collections = null;
|
||||||
|
/** @type {?Array<import("../api/sharing.js").Share>} */ this.incoming_shares = null;
|
||||||
|
this.server_features = null;
|
||||||
|
/** @type {?XMLHttpRequest} */ this.collections_req = null;
|
||||||
|
/** @type {?XMLHttpRequest} */ this.shares_req = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate() {
|
||||||
|
this.child_collections = null;
|
||||||
|
this.incoming_shares = null;
|
||||||
|
this.server_features = null;
|
||||||
|
if (this.collections_req) {
|
||||||
|
this.collections_req.abort();
|
||||||
|
this.collections_req = null;
|
||||||
|
}
|
||||||
|
if (this.shares_req) {
|
||||||
|
this.shares_req.abort();
|
||||||
|
this.shares_req = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} user
|
||||||
|
* @param {string} password
|
||||||
|
* @param {import("../models/collection.js").Collection} principal_collection
|
||||||
|
* @param {function(string):void} onerror
|
||||||
|
* @param {function(Array<import("../models/collection.js").Collection>, Array<import("../api/sharing.js").Share>):void} displayData
|
||||||
|
*/
|
||||||
|
getChildCollections(user, password, principal_collection, onerror, displayData) {
|
||||||
|
if (this.child_collections !== null && this.incoming_shares !== null) {
|
||||||
|
displayData(this.child_collections, this.incoming_shares);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let loading_scene = new LoadingScene();
|
||||||
|
push_scene(loading_scene);
|
||||||
|
|
||||||
|
let collections = null;
|
||||||
|
let shares = null;
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
let check_if_completed = () => {
|
||||||
|
if (!is_current_scene(loading_scene)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
onerror(error);
|
||||||
|
pop_scene();
|
||||||
|
} else if (collections !== null && shares !== null) {
|
||||||
|
this.child_collections = collections;
|
||||||
|
this.incoming_shares = shares;
|
||||||
|
displayData(this.child_collections, this.incoming_shares);
|
||||||
|
pop_scene();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.collections_req = get_collections(user, password, principal_collection, (c, e) => {
|
||||||
|
this.collections_req = null;
|
||||||
|
if (e) error = e;
|
||||||
|
collections = c || [];
|
||||||
|
check_if_completed();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shares_req = reload_sharing_list(user, password, null, (s, e) => {
|
||||||
|
this.shares_req = null;
|
||||||
|
if (e) error = e;
|
||||||
|
shares = s || [];
|
||||||
|
check_if_completed();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} user
|
||||||
|
* @param {string} password
|
||||||
|
* @param {function(string):void} onerror
|
||||||
|
* @param {function(Array<import("../api/sharing.js").Share>):void} displayData
|
||||||
|
*/
|
||||||
|
getIncomingShares(user, password, onerror, displayData) {
|
||||||
|
if (this.incoming_shares !== null) {
|
||||||
|
displayData(this.incoming_shares);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let loading_scene = new LoadingScene();
|
||||||
|
push_scene(loading_scene);
|
||||||
|
|
||||||
|
this.shares_req = reload_sharing_list(user, password, null, (shares, error) => {
|
||||||
|
if (!is_current_scene(loading_scene)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.shares_req = null;
|
||||||
|
if (error) {
|
||||||
|
onerror(error);
|
||||||
|
pop_scene();
|
||||||
|
} else {
|
||||||
|
this.incoming_shares = shares;
|
||||||
|
displayData(this.incoming_shares);
|
||||||
|
pop_scene();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} user
|
||||||
|
* @param {string} password
|
||||||
|
* @param {function(string):void} onerror
|
||||||
|
* @param {function(import("../api/sharing.js").ServerFeatures):void} displayData
|
||||||
|
*/
|
||||||
|
getServerFeatures(user, password, onerror, displayData) {
|
||||||
|
if (this.server_features !== null) {
|
||||||
|
displayData(this.server_features);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
discover_server_features(user, password, (features, error) => {
|
||||||
|
if (error) {
|
||||||
|
if (onerror) onerror(error);
|
||||||
|
} else {
|
||||||
|
this.server_features = features;
|
||||||
|
displayData(this.server_features);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const collectionsCache = new CollectionsCache();
|
||||||
Reference in New Issue
Block a user