diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2024-12-13 12:08:34 +0100 |
---|---|---|
committer | skjnldsv <skjnldsv@protonmail.com> | 2024-12-17 09:59:57 +0100 |
commit | 2b330c6f347208370f70ca7c668c99968426c86f (patch) | |
tree | b3a283e4b74fe4ea6eb8210d5f1cfc253c9b7659 /apps | |
parent | 74b2562e6b40a9339943bfa83d323ea11203f401 (diff) | |
download | nextcloud-server-2b330c6f347208370f70ca7c668c99968426c86f.tar.gz nextcloud-server-2b330c6f347208370f70ca7c668c99968426c86f.zip |
feat(files): add selection keyboard shortcuts
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/src/components/FileEntry/FileEntryCheckbox.vue | 37 | ||||
-rw-r--r-- | apps/files/src/components/FilesListTableHeader.vue | 28 |
2 files changed, 59 insertions, 6 deletions
diff --git a/apps/files/src/components/FileEntry/FileEntryCheckbox.vue b/apps/files/src/components/FileEntry/FileEntryCheckbox.vue index 9caa08cfe22..1b6112373f4 100644 --- a/apps/files/src/components/FileEntry/FileEntryCheckbox.vue +++ b/apps/files/src/components/FileEntry/FileEntryCheckbox.vue @@ -23,9 +23,11 @@ import { FileType } from '@nextcloud/files' import { translate as t } from '@nextcloud/l10n' import { defineComponent } from 'vue' +import { useHotKey } from '@nextcloud/vue/dist/Composables/useHotKey.js' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' +import { useActiveStore } from '../../store/active.ts' import { useKeyboardStore } from '../../store/keyboard.ts' import { useSelectionStore } from '../../store/selection.ts' import logger from '../../logger.ts' @@ -60,13 +62,21 @@ export default defineComponent({ setup() { const selectionStore = useSelectionStore() const keyboardStore = useKeyboardStore() + const activeStore = useActiveStore() + return { + activeStore, keyboardStore, selectionStore, + t, } }, computed: { + isActive() { + return this.activeStore.activeNode?.source === this.source.source + }, + selectedFiles() { return this.selectionStore.selected }, @@ -91,6 +101,23 @@ export default defineComponent({ }, }, + created() { + // ctrl+space toggle selection + useHotKey(' ', this.onToggleSelect, { + stop: true, + prevent: true, + ctrl: true, + }) + + // ctrl+shift+space toggle range selection + useHotKey(' ', this.onToggleSelect, { + stop: true, + prevent: true, + ctrl: true, + shift: true, + }) + }, + methods: { onSelectionChange(selected: boolean) { const newSelectedIndex = this.index @@ -132,7 +159,15 @@ export default defineComponent({ this.selectionStore.reset() }, - t, + onToggleSelect() { + // Don't react if the node is not active + if (!this.isActive) { + return + } + + logger.debug('Toggling selection for file', { source: this.source }) + this.onSelectionChange(!this.isSelected) + }, }, }) </script> diff --git a/apps/files/src/components/FilesListTableHeader.vue b/apps/files/src/components/FilesListTableHeader.vue index c8334abda5e..b7818a9a40f 100644 --- a/apps/files/src/components/FilesListTableHeader.vue +++ b/apps/files/src/components/FilesListTableHeader.vue @@ -58,15 +58,15 @@ import type { Node } from '@nextcloud/files' import type { PropType } from 'vue' import type { FileSource } from '../types.ts' -import { translate as t } from '@nextcloud/l10n' import { defineComponent } from 'vue' - +import { translate as t } from '@nextcloud/l10n' +import { useHotKey } from '@nextcloud/vue/dist/Composables/useHotKey.js' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' -import FilesListTableHeaderButton from './FilesListTableHeaderButton.vue' -import { useNavigation } from '../composables/useNavigation' import { useFilesStore } from '../store/files.ts' +import { useNavigation } from '../composables/useNavigation' import { useSelectionStore } from '../store/selection.ts' +import FilesListTableHeaderButton from './FilesListTableHeaderButton.vue' import filesSortingMixin from '../mixins/filesSorting.ts' import logger from '../logger.ts' @@ -155,6 +155,21 @@ export default defineComponent({ }, }, + created() { + // ctrl+a selects all + useHotKey('a', this.onToggleAll, { + ctrl: true, + stop: true, + prevent: true, + }) + + // Escape key cancels selection + useHotKey('Escape', this.resetSelection, { + stop: true, + prevent: true, + }) + }, + methods: { ariaSortForMode(mode: string): ARIAMixin['ariaSort'] { if (this.sortingMode === mode) { @@ -172,7 +187,7 @@ export default defineComponent({ } }, - onToggleAll(selected) { + onToggleAll(selected = true) { if (selected) { const selection = this.nodes.map(node => node.source).filter(Boolean) as FileSource[] logger.debug('Added all nodes to selection', { selection }) @@ -185,6 +200,9 @@ export default defineComponent({ }, resetSelection() { + if (this.isNoneSelected) { + return + } this.selectionStore.reset() }, |