feat(navigation) add browser history: permits url bookmarking on current folder

This commit is contained in:
Edouard Vanbelle
2026-03-22 22:55:42 +01:00
parent 128dd8a76a
commit fdf1184601
5 changed files with 345 additions and 51 deletions
+121 -2
View File
@@ -1,8 +1,115 @@
// @ts-check
// TODO move to features/files/fileOperations.js ?
/**
* Files view loading logic
* @typedef {Object} FolderInfo
* @property {string} category
* @property {number} created_at - timestamp
* @property {string} icon_class
* @property {string} icon_special_class
* @property {string} id the uniq id of the folder
* @property {boolean} is_root
* @property {number} modified_at
* @property {string} name
* @property {string} owner_id
* @property {string|null} parent_id the folder parent (null if is_root)
* @property {string} path the full path
*/
async function loadFiles(options = {}) {
/**
* getFolder information
* @param {string} id the id of the folder
* @returns {Promise<FolderInfo>}
*/
async function getFolder( id) {
/** @type {HeadersInit} */
const headers = {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache'
};
/** @type {RequestInit} */
const requestOptions = {
headers,
credentials: 'same-origin',
cache: 'no-store'
};
let folderInformations = await fetch( `/api/folders/${id}`, requestOptions);
if (folderInformations.ok) {
return folderInformations.json()
}
else {
console.warn(`Error fetching folder ${id}`);
return Promise.reject(null);
}
}
/**
* rebuild breadcrumb from selected folder (iterate up to root)
*/
async function rebuildBreadCrumb() {
const app = window.app;
/**
* Store the leaf (this is the current displayed folder)
* @type {FolderInfo | null}
*/
let currentFolderInfo = null;
// rebuild full breadcrumb,
// TODO: to optimize, data may already be known / or ETAG could be interesting to reduce load
app.breadcrumbPath = [];
/** @type {string | null} */
let id = app.currentPath;
// recurse from selected folder to root
while (id !== null) {
console.log(`fetching folder information for folder ${id}`);
try {
let folderInfo = await getFolder(id);
// store the Leaf which is the current folder
if (currentFolderInfo === null) {
currentFolderInfo = folderInfo;
}
// XXX do not enter root into bread crumb updateBreadcrumb() method always display it
if(!folderInfo.is_root) {
app.breadcrumbPath.unshift( {id: folderInfo.id, name: folderInfo.name});
}
// iterate to parent folder
id = folderInfo.parent_id;
}
catch( e) {
console.log(`Error loading information from folder ${app.currentPath}, falling back to ${app.userHomeFolderId}`);
// fallback of root
window.uiNotifications.show(
'error: folder not found or permission denied',
'the given folder is not available or you do not have sufficient rights'
);
app.breadcrumbPath = [];
id = app.userHomeFolderId;
app.currentPath = id;
}
}
// store informations on the current folder
app.currentFolderInfo = currentFolderInfo;
}
/**
* Files view loading logic
*
* @param {Object} options
* @param {boolean} [options.insertHistory] add browser history (default true)
* @param {boolean} [options.forceRefresh] force refresh of content
*/
async function loadFiles(options = { insertHistory: true}) {
const app = window.app;
const elements = window.appElements;
@@ -30,6 +137,14 @@ async function loadFiles(options = {}) {
}
const timestamp = new Date().getTime();
await rebuildBreadCrumb();
// request a breadcrumb paint
window.ui.updateBreadcrumb();
window.updateHistory( options.insertHistory || false);
let url;
if (!app.currentPath || app.currentPath === '') {
@@ -48,10 +163,13 @@ async function loadFiles(options = {}) {
console.log(`Loading subfolder content: ${app.currentPath}`);
}
/** @type {HeadersInit} */
const headers = {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache'
};
/** @type {RequestInit} */
const requestOptions = {
headers,
credentials: 'same-origin',
@@ -60,6 +178,7 @@ async function loadFiles(options = {}) {
if (forceRefresh) {
url += `&force_refresh=true`;
// @ts-ignore
requestOptions.headers['X-Force-Refresh'] = 'true';
console.log('Forcing complete refresh ignoring cache');
}