aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorskjnldsv <skjnldsv@protonmail.com>2025-06-03 13:31:54 +0200
committernextcloud-command <nextcloud-command@users.noreply.github.com>2025-06-04 06:37:14 +0000
commitb8591e6b825d210d431a6c01d773948318d315b6 (patch)
treef362f785d9cdcb9b806481daadcfad242acab903
parenta2358fba5cf8c5a644ac5ed81666717efe6c99c0 (diff)
downloadnextcloud-server-b8591e6b825d210d431a6c01d773948318d315b6.tar.gz
nextcloud-server-b8591e6b825d210d431a6c01d773948318d315b6.zip
fix(files): highlight previous folder on history up
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
-rw-r--r--apps/files/src/router/router.ts62
-rw-r--r--cypress/e2e/files/files-navigation.cy.ts55
2 files changed, 117 insertions, 0 deletions
diff --git a/apps/files/src/router/router.ts b/apps/files/src/router/router.ts
index 13e74c26451..00f08c38d31 100644
--- a/apps/files/src/router/router.ts
+++ b/apps/files/src/router/router.ts
@@ -3,10 +3,16 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { RawLocation, Route } from 'vue-router'
+
import { generateUrl } from '@nextcloud/router'
+import { relative } from 'path'
import queryString from 'query-string'
import Router, { isNavigationFailure, NavigationFailureType } from 'vue-router'
import Vue from 'vue'
+
+import { useFilesStore } from '../store/files'
+import { useNavigation } from '../composables/useNavigation'
+import { usePathsStore } from '../store/paths'
import logger from '../logger'
Vue.use(Router)
@@ -68,4 +74,60 @@ const router = new Router({
},
})
+// If navigating back from a folder to a parent folder,
+// we need to keep the current dir fileid so it's highlighted
+// and scrolled into view.
+router.beforeEach((to, from, next) => {
+ if (to.params?.parentIntercept) {
+ delete to.params.parentIntercept
+ next()
+ return
+ }
+
+ const fromDir = (from.query?.dir || '/') as string
+ const toDir = (to.query?.dir || '/') as string
+
+ // We are going back to a parent directory
+ if (relative(fromDir, toDir) === '..') {
+ const { currentView } = useNavigation()
+ const { getNode } = useFilesStore()
+ const { getPath } = usePathsStore()
+
+ if (!currentView.value?.id) {
+ logger.error('No current view id found, cannot navigate to parent directory', { fromDir, toDir })
+ return next()
+ }
+
+ // Get the previous parent's file id
+ const fromSource = getPath(currentView.value?.id, fromDir)
+ if (!fromSource) {
+ logger.error('No source found for the parent directory', { fromDir, toDir })
+ return next()
+ }
+
+ const fileId = getNode(fromSource)?.fileid
+ if (!fileId) {
+ logger.error('No fileid found for the parent directory', { fromDir, toDir, fromSource })
+ return next()
+ }
+
+ logger.debug('Navigating back to parent directory', { fromDir, toDir, fileId })
+ next({
+ name: 'filelist',
+ query: to.query,
+ params: {
+ ...to.params,
+ fileid: String(fileId),
+ // Prevents the beforeEach from being called again
+ parentIntercept: 'true',
+ },
+ // Replace the current history entry
+ replace: true,
+ })
+ }
+
+ // else, we just continue
+ next()
+})
+
export default router
diff --git a/cypress/e2e/files/files-navigation.cy.ts b/cypress/e2e/files/files-navigation.cy.ts
new file mode 100644
index 00000000000..4cc56990caf
--- /dev/null
+++ b/cypress/e2e/files/files-navigation.cy.ts
@@ -0,0 +1,55 @@
+/*!
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import type { User } from '@nextcloud/cypress'
+import { getRowForFile, navigateToFolder } from './FilesUtils.ts'
+
+describe('files: Navigate through folders and observe behavior', () => {
+ let user: User
+
+ before(() => {
+ cy.createRandomUser().then(($user) => {
+ user = $user
+ cy.mkdir(user, '/foo')
+ cy.mkdir(user, '/foo/bar')
+ cy.mkdir(user, '/foo/bar/baz')
+ })
+ })
+
+ it('Shows root folder and we can navigate to the last folder', () => {
+ cy.login(user)
+ cy.visit('/apps/files/')
+
+ getRowForFile('foo').should('be.visible')
+ navigateToFolder('/foo/bar/baz')
+
+ // Last folder is empty
+ cy.get('[data-cy-files-list-row-fileid]').should('not.exist')
+ })
+
+ it('Highlight the previous folder when navigating back', () => {
+ cy.go('back')
+ getRowForFile('baz').should('be.visible')
+ .invoke('attr', 'class').should('contain', 'active')
+
+ cy.go('back')
+ getRowForFile('bar').should('be.visible')
+ .invoke('attr', 'class').should('contain', 'active')
+
+ cy.go('back')
+ getRowForFile('foo').should('be.visible')
+ .invoke('attr', 'class').should('contain', 'active')
+ })
+
+ it('Can navigate forward again', () => {
+ cy.go('forward')
+ getRowForFile('bar').should('be.visible')
+ .invoke('attr', 'class').should('contain', 'active')
+
+ cy.go('forward')
+ getRowForFile('baz').should('be.visible')
+ .invoke('attr', 'class').should('contain', 'active')
+ })
+})