mirror of
https://github.com/nextcloud/server.git
synced 2026-06-12 02:00:51 -04:00
feat(files): add selection keyboard shortcuts
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
This commit is contained in:
parent
74b2562e6b
commit
2b330c6f34
2 changed files with 59 additions and 6 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue