From 000159dfbbb9b22cdf7ad9c1a8e6a182e2655df3 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Tue, 11 Aug 2026 19:04:11 +0200 Subject: [PATCH 01/10] fix(files): update loading behavior when changing location Signed-off-by: Luka Trovic --- apps/files/src/components/FilesListVirtual.vue | 5 +++++ apps/files/src/components/VirtualList.vue | 8 +++++++- apps/files/src/views/FilesList.vue | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index 813e014b04254..63b6fcb6cfacf 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -118,6 +118,11 @@ export default defineComponent({ type: String, required: true, }, + + loading: { + type: Boolean, + default: false, + }, }, setup(props) { diff --git a/apps/files/src/components/VirtualList.vue b/apps/files/src/components/VirtualList.vue index 9121f55e105e1..f09cccc714019 100644 --- a/apps/files/src/components/VirtualList.vue +++ b/apps/files/src/components/VirtualList.vue @@ -18,12 +18,13 @@
| null, @@ -410,6 +411,7 @@ export default defineComponent({ return this.currentFolder !== undefined && !this.isEmptyDir && this.loading + && !this.changingLocation }, /** @@ -476,12 +478,14 @@ export default defineComponent({ } logger.debug('View changed', { newView, oldView }) + this.changingLocation = true this.selectionStore.reset() this.fetchContent() }, directory(newDir, oldDir) { logger.debug('Directory changed', { newDir, oldDir }) + this.changingLocation = true // TODO: preserve selection on browsing? this.selectionStore.reset() this.sidebar.close() @@ -608,6 +612,7 @@ export default defineComponent({ this.error = humanizeWebDAVError(error) } finally { this.loading = false + this.changingLocation = false } }, From 151ee54d3bcb3b7291b9ce26e46f93ca1624b66a Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Mon, 24 Aug 2026 09:43:32 +0200 Subject: [PATCH 02/10] test(files): add test case for loading indicator during folder navigation Signed-off-by: Luka Trovic --- apps/files/src/views/FilesList.vue | 1 + .../e2e/files/files-navigation.spec.ts | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue index a32a8538e911a..f1568aad00f18 100644 --- a/apps/files/src/views/FilesList.vue +++ b/apps/files/src/views/FilesList.vue @@ -98,6 +98,7 @@ diff --git a/tests/playwright/e2e/files/files-navigation.spec.ts b/tests/playwright/e2e/files/files-navigation.spec.ts index b2114d00cd728..bf653e016e977 100644 --- a/tests/playwright/e2e/files/files-navigation.spec.ts +++ b/tests/playwright/e2e/files/files-navigation.spec.ts @@ -48,4 +48,46 @@ test.describe('Files: Navigation', () => { await expect(filesListPage.getRowForFile('baz')).toBeVisible() await expect(filesListPage.getRowForFile('baz')).toBeActiveRow() }) + + test('show loading indicator when navigating', async ({ page, filesListPage }) => { + await filesListPage.navigateToFolder('foo/bar/baz') + await expect(page.locator('[data-cy-files-list-row-fileid]')).toHaveCount(0) + + // Block the PROPFIND request to simulate a slow network and show the loading indicator + let releaseNavigation!: () => void + const navigationBlocked = new Promise((resolve) => { + releaseNavigation = resolve + }) + let blockedNavigationRequest = false + await page.route(/remote\.php\/dav\/files\//, async (route) => { + const request = route.request() + if (!blockedNavigationRequest && request.method() === 'PROPFIND' && request.url().includes('/foo/bar')) { + blockedNavigationRequest = true + await navigationBlocked + } + + await route.continue() + }) + + // Navigate back to the parent folder — the PROPFIND request will be blocked + const navigationResponse = page.waitForResponse((response) => response.url().includes('/remote.php/dav/files/') + && response.request().method() === 'PROPFIND' + && response.url().includes('/foo/bar')) + + await page.goBack() + + await expect.poll(() => new URL(page.url()).searchParams.get('dir')).toBe('/foo/bar') + await expect(page.locator('[data-cy-files-loading]')).toBeVisible() + expect(blockedNavigationRequest).toBe(true) + + // Release the blocked navigation request and wait for it to complete + releaseNavigation() + await navigationResponse + await page.unroute(/remote\.php\/dav\/files\//) + + // Wait for the loading indicator to disappear and the folder to be rendered + await expect(page.locator('[data-cy-files-loading]')).not.toBeVisible() + await expect(filesListPage.getRowForFile('baz')).toBeVisible() + await expect(filesListPage.getRowForFile('baz')).toBeActiveRow() + }) }) From 30e146c42798f1000bbccdd09d83580b33467b28 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Tue, 1 Sep 2026 10:38:45 +0200 Subject: [PATCH 03/10] fix(files): update loading indicator behavior during folder navigation Signed-off-by: Luka Trovic --- apps/files/src/components/VirtualList.vue | 15 +++++-- apps/files/src/views/FilesList.vue | 6 --- .../e2e/files/files-navigation.spec.ts | 42 ------------------- 3 files changed, 12 insertions(+), 51 deletions(-) diff --git a/apps/files/src/components/VirtualList.vue b/apps/files/src/components/VirtualList.vue index f09cccc714019..9287f0d181ff8 100644 --- a/apps/files/src/components/VirtualList.vue +++ b/apps/files/src/components/VirtualList.vue @@ -5,7 +5,10 @@ + + + @@ -637,12 +625,12 @@ export default defineComponent({ border-radius: 4px; background: linear-gradient( 90deg, - var(--color-background-hover), - var(--color-main-background), - var(--color-background-hover) + var(--color-placeholder-light), + var(--color-placeholder-dark), + var(--color-placeholder-light) ); background-size: 200% 100%; - animation: skeleton-loading 1.5s infinite; + animation: skeleton-loading 3.5s infinite; flex-shrink: 0; } @@ -652,12 +640,12 @@ export default defineComponent({ border-radius: 4px; background: linear-gradient( 90deg, - var(--color-background-hover), - var(--color-main-background), - var(--color-background-hover) + var(--color-placeholder-light), + var(--color-placeholder-dark), + var(--color-placeholder-light) ); background-size: 200% 100%; - animation: skeleton-loading 1.5s infinite; + animation: skeleton-loading 3.5s infinite; flex-shrink: 0; } @@ -667,30 +655,15 @@ export default defineComponent({ border-radius: 4px; background: linear-gradient( 90deg, - var(--color-background-hover), - var(--color-main-background), - var(--color-background-hover) + var(--color-placeholder-light), + var(--color-placeholder-dark), + var(--color-placeholder-light) ); background-size: 200% 100%; - animation: skeleton-loading 1.5s infinite; + animation: skeleton-loading 3.5s infinite; min-width: 100px; } - .files-list__skeleton-column { - width: calc(var(--row-height) * 1.5); - height: 20px; - border-radius: 4px; - background: linear-gradient( - 90deg, - var(--color-background-hover), - var(--color-main-background), - var(--color-background-hover) - ); - background-size: 200% 100%; - animation: skeleton-loading 1.5s infinite; - flex-shrink: 0; - } - @keyframes skeleton-loading { 0% { background-position: 200% 0; diff --git a/apps/files/src/components/VirtualList.vue b/apps/files/src/components/VirtualList.vue index 2e863f5c0d060..64d68d57bc601 100644 --- a/apps/files/src/components/VirtualList.vue +++ b/apps/files/src/components/VirtualList.vue @@ -18,23 +18,17 @@
- -
- -
@@ -62,12 +57,19 @@
@@ -48,6 +42,7 @@
+ +
+ +
From 1e64b654e03eb5e24d471d586c88d942b8af1d5a Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Wed, 4 Nov 2026 09:35:45 +0100 Subject: [PATCH 08/10] feat(files): adjust loading skeleton during navigation Signed-off-by: Luka Trovic --- .../files/src/components/FilesListVirtual.vue | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index bd903f157dcdd..18bdc8f0c5aea 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -61,6 +61,9 @@
+ +
+
@@ -620,8 +623,9 @@ export default defineComponent({ } .files-list__skeleton-checkbox { - width: var(--checkbox-size); - height: var(--checkbox-size); + width: 18px; + height: 18px; + margin: 6px; border-radius: 4px; background: linear-gradient( 90deg, @@ -664,6 +668,21 @@ export default defineComponent({ min-width: 100px; } + .files-list__skeleton-column { + width: calc(var(--row-height) * 2.5); + height: 20px; + border-radius: 4px; + background: linear-gradient( + 90deg, + var(--color-placeholder-light), + var(--color-placeholder-dark), + var(--color-placeholder-light) + ); + background-size: 200% 100%; + animation: skeleton-loading 1.5s infinite; + flex-shrink: 0; + } + @keyframes skeleton-loading { 0% { background-position: 200% 0; From 719c58a67c36a99e89335d4a8a24ec065fac4710 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Thu, 12 Nov 2026 16:05:26 +0100 Subject: [PATCH 09/10] fix: test coverage issue Signed-off-by: Luka Trovic [skip ci] --- apps/files/src/components/FilesListVirtual.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index 18bdc8f0c5aea..001456a90e0da 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -669,7 +669,7 @@ export default defineComponent({ } .files-list__skeleton-column { - width: calc(var(--row-height) * 2.5); + width: calc(var(--clickable-area-large) * 2.3); height: 20px; border-radius: 4px; background: linear-gradient( From 797857280533b13e65974dcd3aa0d1a8a9222efd Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Fri, 13 Nov 2026 15:17:12 +0100 Subject: [PATCH 10/10] fix: add missing fix Signed-off-by: Luka Trovic --- apps/files/src/components/FilesListVirtual.vue | 3 ++- apps/files/src/views/FilesList.vue | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index 001456a90e0da..4e6ab25d2ac22 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -8,6 +8,7 @@ :data-component="userConfig.grid_view ? FileEntryGrid : FileEntry" data-key="source" :data-sources="nodes" + :navigating="navigating" :grid-mode="userConfig.grid_view" :extra-props="{ isMimeAvailable, @@ -103,9 +104,9 @@ import { useEnabledFileActions } from '../composables/useFileActions.ts' import { useFileListHeaders } from '../composables/useFileListHeaders.ts' import { useFileListWidth } from '../composables/useFileListWidth.ts' import { useRouteParameters } from '../composables/useRouteParameters.ts' +import logger from '../logger.ts' import { useActiveStore } from '../store/active.ts' import { useUserConfigStore } from '../store/userconfig.ts' -import { logger } from '../utils/logger.ts' export default defineComponent({ name: 'FilesListVirtual', diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue index a4c4d23aef7c8..25fbf858a5834 100644 --- a/apps/files/src/views/FilesList.vue +++ b/apps/files/src/views/FilesList.vue @@ -90,6 +90,7 @@