From 2a75e837525021e69b612c0e3413ac081ff68d40 Mon Sep 17 00:00:00 2001 From: Jared Wolff Date: Wed, 4 Mar 2026 21:44:02 -0500 Subject: [PATCH] fix(thumbnails): display thumbnails in file grid/list and fix WOPI intercepting all file opens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wopiEditor.canEdit() is async but was called without await, so the returned Promise was always truthy — routing every file click to the WOPI editor (which 404'd). Made openFile() async and added await in both ui.js and inlineViewer.js. Added thumbnail elements to _createFileCard() and _createFileItem() for image files, loading from /api/files/{id}/thumbnail/icon with lazy loading and error fallback. --- static/css/components/cards.css | 11 +++++++++++ static/css/components/fileList.css | 3 +++ static/js/app/ui.js | 6 ++++-- static/js/features/files/inlineViewer.js | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/static/css/components/cards.css b/static/css/components/cards.css index 681d1acd..45761d14 100644 --- a/static/css/components/cards.css +++ b/static/css/components/cards.css @@ -322,6 +322,17 @@ button.favorite-star { overflow: hidden; } +/* Thumbnail image inside file-icon (grid and list views) */ +.file-icon .file-thumb { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + z-index: 1; +} + .file-icon.image-icon::before { content: ""; position: absolute; diff --git a/static/css/components/fileList.css b/static/css/components/fileList.css index 88b6548a..4dfb4ceb 100644 --- a/static/css/components/fileList.css +++ b/static/css/components/fileList.css @@ -145,6 +145,9 @@ .file-item .file-icon.image-icon { background-color: #e0f2fe; + position: relative; + overflow: hidden; + border-radius: 4px; } .file-item .file-icon.image-icon i, diff --git a/static/js/app/ui.js b/static/js/app/ui.js index a649e56a..24501261 100644 --- a/static/js/app/ui.js +++ b/static/js/app/ui.js @@ -747,13 +747,13 @@ const ui = { return null; }; - const openFile = (file) => { + const openFile = async (file) => { if (!file) return; if (window.recent) { document.dispatchEvent(new CustomEvent('file-accessed', { detail: { file } })); } // WOPI editor intercept: open Office documents in the WOPI editor - if (window.wopiEditor && window.wopiEditor.canEdit(file.name)) { + if (window.wopiEditor && await window.wopiEditor.canEdit(file.name)) { window.wopiEditor.openInModal(file.id, file.name, 'edit'); return; } @@ -1139,6 +1139,7 @@ const ui = {
+ ${iconSpecialClass === 'image-icon' ? `` : ''}
${escapeHtml(file.name)}
@@ -1176,6 +1177,7 @@ const ui = {
+ ${iconSpecialClass === 'image-icon' ? `` : ''}
${escapeHtml(file.name)} diff --git a/static/js/features/files/inlineViewer.js b/static/js/features/files/inlineViewer.js index 610f7af6..b792f888 100644 --- a/static/js/features/files/inlineViewer.js +++ b/static/js/features/files/inlineViewer.js @@ -88,11 +88,11 @@ class InlineViewer { console.log('Inline viewer initialized'); } - openFile(file) { + async openFile(file) { console.log('Opening file:', file); // WOPI editor intercept: open Office documents in the WOPI editor - if (window.wopiEditor && window.wopiEditor.canEdit(file.name)) { + if (window.wopiEditor && await window.wopiEditor.canEdit(file.name)) { window.wopiEditor.openInModal(file.id, file.name, 'edit'); return; }