diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue index 53620cf2f6d96..b0f1a47a6640e 100644 --- a/apps/files/src/views/FilesList.vue +++ b/apps/files/src/views/FilesList.vue @@ -476,7 +476,7 @@ export default defineComponent({ } // Fetch the current dir contents - this.promise = currentView.getContents(dir) as Promise + this.promise = currentView.getContents(dir, this.fetchContent) as Promise try { const { folder, contents } = await this.promise logger.debug('Fetched contents', { dir, folder, contents }) diff --git a/apps/files/src/views/recent.ts b/apps/files/src/views/recent.ts index bb536674ec19a..7af9049407222 100644 --- a/apps/files/src/views/recent.ts +++ b/apps/files/src/views/recent.ts @@ -19,13 +19,27 @@ * along with this program. If not, see . * */ +import { subscribe } from '@nextcloud/event-bus' +import { View, getNavigation } from '@nextcloud/files' +import { loadState } from '@nextcloud/initial-state' import { translate as t } from '@nextcloud/l10n' import HistorySvg from '@mdi/svg/svg/history.svg?raw' import { getContents } from '../services/Recent' -import { View, getNavigation } from '@nextcloud/files' export default () => { + // Callback to use to trigger reload + let reloadCallback = () => {} + // Current state of user config for hidden files + let { show_hidden: showHiddenFiles } = loadState<{ show_hidden: boolean }>('files', 'config') + // When the user config changes and the hidden files setting is changed we need to reload the directory content + subscribe('files:config:updated', ({ key, value }: { key: string, value: boolean}) => { + if (key === 'show_hidden') { + showHiddenFiles = value + reloadCallback() + } + }) + const Navigation = getNavigation() Navigation.register(new View({ id: 'recent', @@ -40,6 +54,16 @@ export default () => { defaultSortKey: 'mtime', - getContents, + getContents: async (path = '/', callback: () => void) => { + // Only use the real reload callback on the root directory + // as otherwise the files app will handle it correctly and we would cause a doubled WebDAV request + reloadCallback = path === '/' ? callback : () => {} + const content = await getContents(path) + if (path === '/' && !showHiddenFiles) { + // We need to hide files from hidden directories in the root if not configured + content.contents = content.contents.filter((node) => node.dirname.split('/').some((dir) => dir.startsWith('.'))) + } + return content + }, })) } diff --git a/cypress/e2e/files/files-settings.cy.ts b/cypress/e2e/files/files-settings.cy.ts new file mode 100644 index 0000000000000..fe07c37320017 --- /dev/null +++ b/cypress/e2e/files/files-settings.cy.ts @@ -0,0 +1,81 @@ +import type { User } from '@nextcloud/cypress' +import { getRowForFile } from './FilesUtils' + +const showHiddenFiles = () => { + // Open the files settings + cy.get('[data-cy-files-navigation-settings-button] a').click({ force: true }) + // Toggle the hidden files setting + cy.get('[data-cy-files-settings-setting="show_hidden"]').within(() => { + cy.get('input').should('not.be.checked') + cy.get('input').check({ force: true }) + }) + // Close the dialog + cy.get('[data-cy-files-navigation-settings] button[aria-label="Close"]').click() +} + +describe('files: Hide or show hidden files', { testIsolation: true }, () => { + let user: User + + beforeEach(() => { + cy.createRandomUser().then(($user) => { + user = $user + + cy.uploadContent(user, new Blob([]), 'text/plain', '/.file') + cy.mkdir(user, '/.folder') + cy.login(user) + }) + }) + + context('view: All files', { testIsolation: false }, () => { + it('hides dot-files by default', () => { + cy.visit('/apps/files') + + getRowForFile('.file').should('not.exist') + getRowForFile('.folder').should('not.exist') + }) + + it('can show hidden files', () => { + showHiddenFiles() + // Now the files should be visible + getRowForFile('.file').should('be.visible') + getRowForFile('.folder').should('be.visible') + }) + }) + + context('view: Personal files', { testIsolation: false }, () => { + it('hides dot-files by default', () => { + cy.visit('/apps/files/personal') + + getRowForFile('.file').should('not.exist') + getRowForFile('.folder').should('not.exist') + }) + + it('can show hidden files', () => { + showHiddenFiles() + // Now the files should be visible + getRowForFile('.file').should('be.visible') + getRowForFile('.folder').should('be.visible') + }) + }) + + context('view: Recent files', { testIsolation: false }, () => { + it('hides dot-files by default', () => { + // also add hidden file in hidden folder + cy.uploadContent(user, new Blob([]), 'text/plain', '/.folder/other-file') + cy.login(user) + cy.visit('/apps/files/recent') + + getRowForFile('.file').should('not.exist') + getRowForFile('.folder').should('not.exist') + getRowForFile('other-file').should('not.exist') + }) + + it('can show hidden files', () => { + showHiddenFiles() + // Now the files should be visible + getRowForFile('.file').should('be.visible') + getRowForFile('.folder').should('be.visible') + getRowForFile('other-file').should('be.visible') + }) + }) +})