feat(files): add selection keyboard shortcuts

Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
This commit is contained in:
skjnldsv 2024-12-13 12:08:34 +01:00
parent 74b2562e6b
commit 2b330c6f34
2 changed files with 59 additions and 6 deletions

View file

@ -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>

View file

@ -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()
},