From c8e67f77eaa47bbbbaf9c0a42dfd7b42621e7781 Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Thu, 16 Apr 2026 23:02:34 +0200 Subject: [PATCH 1/2] fix(frontent): remove default section to avoid blink when hash in url is not 'file' --- static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.html b/static/index.html index dc5264b6..d0000a75 100644 --- a/static/index.html +++ b/static/index.html @@ -70,7 +70,7 @@
${i18n ? i18n.t('files.file_types.folder') : 'Folder'}
--
${formattedDate}
- - + +
`; @@ -1247,6 +1250,7 @@ const ui = { const fileSize = file.size_formatted || formatFileSize(file.size); const formattedDate = formatDateTime(file.modified_at); const isFav = favorites?.isFavorite(file.id, 'file'); + const isShared = sharedView.isShared(file.id, 'file'); const el = document.createElement('div'); el.className = 'file-item'; @@ -1265,6 +1269,8 @@ const ui = { ${escapeHtml(file.name)} ${isFav ? '' : ''} + ${isShared ? '
' : ''} +
${typeLabel}
${fileSize}
diff --git a/static/js/views/shared/sharedView.js b/static/js/views/shared/sharedView.js index 55ab6911..3b2d9c52 100644 --- a/static/js/views/shared/sharedView.js +++ b/static/js/views/shared/sharedView.js @@ -10,9 +10,17 @@ import { formatDateShort } from '../../core/formatters.js'; import { i18n } from '../../core/i18n.js'; import { fileSharing } from '../../features/sharing/fileSharing.js'; +const TTL = 5 * 60 * 1000; // 5 min + const sharedView = { // State items: [], + + _expires: 0, + + /** @type {Map} key = "file:" | "folder:" */ + _knownItemsId: new Map(), + filteredItems: [], currentItem: null, @@ -23,15 +31,15 @@ const sharedView = { return h; }, - init() { + async init() { console.log('Initializing shared view component (API-backed)'); - this.loadItems(); + await this.loadItems(); }, show() { this.displayUI(); this.attachEventListeners(); - this.loadItems().then(() => this.filterAndSortItems()); + this.filterAndSortItems(); const c = document.getElementById('shared-container'); if (c) c.classList.remove('hidden'); }, @@ -41,8 +49,27 @@ const sharedView = { if (c) c.classList.add('hidden'); }, - // Load shared items from backend API - async loadItems() { + /** + * tells if item_id is shared + * + * @param {string} id the item_id + * @param {string} type folder|file + * @returns {boolean} true if this item is shared + */ + isShared(id, type) { + return this._knownItemsId.has(`${type}:${id}`); + }, + + // Load shared items from backend API, + // TODO cache entries to minimize calls + /** + * load shared items + * + * @param {boolean} force ignore cache + */ + async loadItems(force) { + if (this._expires > Date.now() && !force) return; + try { const res = await fetch('/api/shares?page=1&per_page=1000', { headers: this._headers() @@ -53,11 +80,16 @@ const sharedView = { } else { this.items = []; } + this.filteredItems = { ...this.items }; + this._knownItemsId.clear(); + this.items.forEach((item) => { + this._knownItemsId.set(`${item.item_type}:${item.item_id}`, true); + }); + this._expires = Date.now() + TTL; } catch (err) { console.error('Error loading shared items:', err); this.items = []; } - this.filteredItems = [...this.items]; }, // Create and display the shared view UI @@ -559,7 +591,7 @@ const sharedView = { } this.closeShareDialog(); - await this.loadItems(); + await this.loadItems(true); this.filterAndSortItems(); }, @@ -580,7 +612,7 @@ const sharedView = { } this.closeShareDialog(); - await this.loadItems(); + await this.loadItems(true); this.filterAndSortItems(); }, diff --git a/static/sw.js b/static/sw.js index d7053aab..bad30e9b 100644 --- a/static/sw.js +++ b/static/sw.js @@ -1,5 +1,6 @@ // OxiCloud Service Worker -const CACHE_NAME = 'oxicloud-cache-v17'; +// FIXME: generate cache name according build ? +const CACHE_NAME = 'oxicloud-cache-v19'; // Only cache static assets — NOT HTML files. // HTML files are served network-first so browsers always get the latest