diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index 4af696bca49..93f567f25a4 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -70,13 +70,12 @@ import { useHotKey } from '@nextcloud/vue/composables/useHotKey' import { defineComponent } from 'vue' import { action as sidebarAction } from '../actions/sidebarAction.ts' +import { useActiveStore } from '../store/active.ts' import { useFileListHeaders } from '../composables/useFileListHeaders.ts' import { useFileListWidth } from '../composables/useFileListWidth.ts' import { useRouteParameters } from '../composables/useRouteParameters.ts' -import { useActiveStore } from '../store/active.ts' import { useSelectionStore } from '../store/selection.js' import { useUserConfigStore } from '../store/userconfig.ts' -import { getSummaryFor } from '../utils/fileUtils.ts' import FileEntry from './FileEntry.vue' import FileEntryGrid from './FileEntryGrid.vue' @@ -113,6 +112,10 @@ export default defineComponent({ type: Array as PropType, required: true, }, + summary: { + type: String, + required: true, + }, }, setup() { @@ -152,10 +155,6 @@ export default defineComponent({ return this.userConfigStore.userConfig }, - summary() { - return getSummaryFor(this.nodes) - }, - isMtimeAvailable() { // Hide mtime column on narrow screens if (this.fileListWidth < 768) { diff --git a/apps/files/src/utils/fileUtils.ts b/apps/files/src/utils/fileUtils.ts index 255c106740d..421b7d02376 100644 --- a/apps/files/src/utils/fileUtils.ts +++ b/apps/files/src/utils/fileUtils.ts @@ -21,25 +21,31 @@ export const extractFilePaths = function(path) { /** * Generate a translated summary of an array of nodes * @param {Node[]} nodes the nodes to summarize + * @param {number} hidden the number of hidden nodes * @return {string} */ -export const getSummaryFor = (nodes: Node[]): string => { +export const getSummaryFor = (nodes: Node[], hidden = 0): string => { const fileCount = nodes.filter(node => node.type === FileType.File).length const folderCount = nodes.filter(node => node.type === FileType.Folder).length + let summary = '' + if (fileCount === 0) { - return n('files', '{folderCount} folder', '{folderCount} folders', folderCount, { folderCount }) + summary = n('files', '{folderCount} folder', '{folderCount} folders', folderCount, { folderCount }) } else if (folderCount === 0) { - return n('files', '{fileCount} file', '{fileCount} files', fileCount, { fileCount }) + summary = n('files', '{fileCount} file', '{fileCount} files', fileCount, { fileCount }) + } else if (fileCount === 1) { + summary = n('files', '1 file and {folderCount} folder', '1 file and {folderCount} folders', folderCount, { folderCount }) + } else if (folderCount === 1) { + summary = n('files', '{fileCount} file and 1 folder', '{fileCount} files and 1 folder', fileCount, { fileCount }) + } else { + summary = t('files', '{fileCount} files and {folderCount} folders', { fileCount, folderCount }) } - if (fileCount === 1) { - return n('files', '1 file and {folderCount} folder', '1 file and {folderCount} folders', folderCount, { folderCount }) + if (hidden > 0) { + // TRANSLATORS: This is a summary of files and folders, where {hiddenFilesAndFolders} is the number of hidden files and folders + summary += ' ' + n('files', '(%n hidden)', ' (%n hidden)', hidden) } - if (folderCount === 1) { - return n('files', '{fileCount} file and 1 folder', '{fileCount} files and 1 folder', fileCount, { fileCount }) - } - - return t('files', '{fileCount} files and {folderCount} folders', { fileCount, folderCount }) + return summary } diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue index c582bdf4cfa..0aa3da144c2 100644 --- a/apps/files/src/views/FilesList.vue +++ b/apps/files/src/views/FilesList.vue @@ -138,7 +138,8 @@ ref="filesListVirtual" :current-folder="currentFolder" :current-view="currentView" - :nodes="dirContentsSorted" /> + :nodes="dirContentsSorted" + :summary="summary" /> @@ -161,10 +162,6 @@ import { UploadPicker, UploadStatus } from '@nextcloud/upload' import { loadState } from '@nextcloud/initial-state' import { defineComponent } from 'vue' -import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue' -import IconReload from 'vue-material-design-icons/Reload.vue' -import LinkIcon from 'vue-material-design-icons/Link.vue' -import ListViewIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue' import NcAppContent from '@nextcloud/vue/components/NcAppContent' import NcActions from '@nextcloud/vue/components/NcActions' import NcActionButton from '@nextcloud/vue/components/NcActionButton' @@ -172,28 +169,34 @@ import NcButton from '@nextcloud/vue/components/NcButton' import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent' import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper' import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon' + import AccountPlusIcon from 'vue-material-design-icons/AccountPlus.vue' +import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue' +import IconReload from 'vue-material-design-icons/Reload.vue' +import LinkIcon from 'vue-material-design-icons/Link.vue' +import ListViewIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue' import ViewGridIcon from 'vue-material-design-icons/ViewGrid.vue' import { action as sidebarAction } from '../actions/sidebarAction.ts' -import { useNavigation } from '../composables/useNavigation.ts' +import { getSummaryFor } from '../utils/fileUtils.ts' +import { humanizeWebDAVError } from '../utils/davUtils.ts' import { useFileListHeaders } from '../composables/useFileListHeaders.ts' import { useFileListWidth } from '../composables/useFileListWidth.ts' -import { useRouteParameters } from '../composables/useRouteParameters.ts' import { useFilesStore } from '../store/files.ts' import { useFiltersStore } from '../store/filters.ts' +import { useNavigation } from '../composables/useNavigation.ts' import { usePathsStore } from '../store/paths.ts' +import { useRouteParameters } from '../composables/useRouteParameters.ts' import { useSelectionStore } from '../store/selection.ts' import { useUploaderStore } from '../store/uploader.ts' import { useUserConfigStore } from '../store/userconfig.ts' import { useViewConfigStore } from '../store/viewConfig.ts' -import { humanizeWebDAVError } from '../utils/davUtils.ts' import BreadCrumbs from '../components/BreadCrumbs.vue' +import DragAndDropNotice from '../components/DragAndDropNotice.vue' import FilesListHeader from '../components/FilesListHeader.vue' import FilesListVirtual from '../components/FilesListVirtual.vue' import filesSortingMixin from '../mixins/filesSorting.ts' import logger from '../logger.ts' -import DragAndDropNotice from '../components/DragAndDropNotice.vue' const isSharingEnabled = (getCapabilities() as { files_sharing?: boolean })?.files_sharing !== undefined @@ -468,6 +471,14 @@ export default defineComponent({ .toSorted((a, b) => a.order - b.order) return enabledActions }, + + /** + * Using the filtered content if filters are active + */ + summary() { + const hidden = this.dirContents.length - this.dirContentsFiltered.length + return getSummaryFor(this.dirContentsFiltered, hidden) + }, }, watch: {