Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/files/src/actions/favoriteAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import StarSvg from '@mdi/svg/svg/star.svg?raw'
import axios from '@nextcloud/axios'
import { emit } from '@nextcloud/event-bus'
import { FileAction, Permission } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import { t } from '@nextcloud/l10n'
import { encodePath } from '@nextcloud/paths'
import { generateUrl } from '@nextcloud/router'
import { isPublicShare } from '@nextcloud/sharing/public'
Expand Down
5 changes: 5 additions & 0 deletions apps/files/src/actions/sidebarAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@ export const action = new FileAction({
},

order: -50,

hotkey: {
key: 'D',
description: t('files', 'Open the details sidebar'),
},
})
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ function hotkeyToString(hotkey: IHotkeyConfig): string {
if (hotkey.shift) {
parts.push('Shift')
}
parts.push(hotkey.key)
if (hotkey.key.match(/^[a-z]$/)) {
parts.push(hotkey.key.toUpperCase())
} else {
parts.push(hotkey.key)
}
return parts.join(' ')
}
</script>
Expand Down Expand Up @@ -71,7 +75,6 @@ function hotkeyToString(hotkey: IHotkeyConfig): string {

<NcHotkeyList :label="t('files', 'View')">
<NcHotkey :label="t('files', 'Toggle grid view')" hotkey="V" />
<NcHotkey :label="t('files', 'Open file sidebar')" hotkey="D" />
<NcHotkey :label="t('files', 'Show those shortcuts')" hotkey="?" />
</NcHotkeyList>
</NcAppSettingsShortcutsSection>
Expand Down
53 changes: 33 additions & 20 deletions apps/files/src/components/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,11 @@ export default defineComponent({
}

if (this.fileId) {
this.scrollToFile(this.fileId, false)
const node = this.nodes.find((node) => node.fileid === this.fileId)
if (node) {
this.activeStore.activeNode = node
this.scrollToFile(this.fileId, false)
}
}
},

Expand Down Expand Up @@ -342,13 +346,7 @@ export default defineComponent({
delete query.openfile
delete query.opendetails

this.activeStore.activeNode = undefined
window.OCP.Files.Router.goToRoute(
null,
{ ...this.$route.params, fileid: String(this.currentFolder.fileid ?? '') },
query,
true,
)
this.activeStore.activeNode = this.currentFolder
},

/**
Expand Down Expand Up @@ -396,7 +394,7 @@ export default defineComponent({
logger.debug('Ignore `openfile` query and replacing with `opendetails` for ' + node.path, { node })
window.OCP.Files.Router.goToRoute(
null,
this.$route.params,
window.OCP.Files.Router.params,
{ ...this.$route.query, openfile: undefined, opendetails: '' },
true, // silent update of the URL
)
Expand Down Expand Up @@ -431,10 +429,29 @@ export default defineComponent({
},

onKeyDown(event: KeyboardEvent) {
if (this.isEmpty) {
return
}

if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown'
&& (!this.userConfig.grid_view || (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight'))
) {
// not an arrow key we handle
return
}

if (!this.fileId || this.fileId === this.currentFolder.fileid) {
// no active node so use either first or last node
const index = event.key === 'ArrowUp' || event.key === 'ArrowLeft'
? this.nodes.length - 1
: 0
this.setActiveNode(this.nodes[index] as NcNode & { fileid: number })
}

const index = this.nodes.findIndex((node) => node.fileid === this.fileId) ?? 0
// Up and down arrow keys
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
const columnCount = this.$refs.table?.columnCount ?? 1
const index = this.nodes.findIndex((node) => node.fileid === this.fileId) ?? 0
const nextIndex = event.key === 'ArrowUp' ? index - columnCount : index + columnCount
if (nextIndex < 0 || nextIndex >= this.nodes.length) {
return
Expand All @@ -450,7 +467,6 @@ export default defineComponent({

// if grid mode, left and right arrow keys
if (this.userConfig.grid_view && (event.key === 'ArrowLeft' || event.key === 'ArrowRight')) {
const index = this.nodes.findIndex((node) => node.fileid === this.fileId) ?? 0
const nextIndex = event.key === 'ArrowLeft' ? index - 1 : index + 1
if (nextIndex < 0 || nextIndex >= this.nodes.length) {
return
Expand All @@ -465,24 +481,21 @@ export default defineComponent({
}
},

setActiveNode(node: NcNode & { fileid: number }) {
async setActiveNode(node: NcNode & { fileid: number }) {
logger.debug('Navigating to file ' + node.path, { node, fileid: node.fileid })
this.scrollToFile(node.fileid)

// Remove openfile and opendetails from the URL
const query = { ...this.$route.query }
delete query.openfile
delete query.opendetails
await this.$router.replace({
...this.$route,
query,
})

// set the new file as active
this.activeStore.activeNode = node

// Silent update of the URL
window.OCP.Files.Router.goToRoute(
null,
{ ...this.$route.params, fileid: String(node.fileid) },
query,
true,
)
},
},
})
Expand Down
47 changes: 20 additions & 27 deletions apps/files/src/composables/useHotKeys.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
/**
/*!
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { getFileActions } from '@nextcloud/files'
import { useHotKey } from '@nextcloud/vue/composables/useHotKey'
import { dirname } from 'path'
import { useRoute, useRouter } from 'vue-router/composables'
import { action as deleteAction } from '../actions/deleteAction.ts'
import { action as favoriteAction } from '../actions/favoriteAction.ts'
import { action as renameAction } from '../actions/renameAction.ts'
import { action as sidebarAction } from '../actions/sidebarAction.ts'
import logger from '../logger.ts'
import { useUserConfigStore } from '../store/userconfig.ts'
import { executeAction } from '../utils/actionUtils.ts'
Expand All @@ -25,29 +23,24 @@ export function useHotKeys(): void {
const router = useRouter()
const route = useRoute()

// d opens the sidebar
useHotKey('d', () => executeAction(sidebarAction), {
stop: true,
prevent: true,
})

// F2 renames the file
useHotKey('F2', () => executeAction(renameAction), {
stop: true,
prevent: true,
})
const actions = getFileActions()
for (const action of actions) {
if (!action.hotkey) {
continue
}
const key = action.hotkey.key.match(/^[a-z]$/)
? action.hotkey.key.toUpperCase()
: action.hotkey.key

// s toggle favorite
useHotKey('s', () => executeAction(favoriteAction), {
stop: true,
prevent: true,
})

// Delete deletes the file
useHotKey('Delete', () => executeAction(deleteAction), {
stop: true,
prevent: true,
})
logger.debug(`Register hotkey for action "${action.id}"`)
useHotKey(key, () => executeAction(action), {
stop: true,
prevent: true,
alt: action.hotkey.alt,
ctrl: action.hotkey.ctrl,
shift: action.hotkey.shift,
})
}

// alt+up go to parent directory
useHotKey('ArrowUp', goToParentDir, {
Expand Down
20 changes: 16 additions & 4 deletions apps/files/src/store/active.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { FileAction, IFolder, INode, IView } from '@nextcloud/files'
import { subscribe } from '@nextcloud/event-bus'
import { getNavigation } from '@nextcloud/files'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { ref, watch } from 'vue'
import logger from '../logger.ts'

export const useActiveStore = defineStore('active', () => {
Expand All @@ -32,6 +32,20 @@ export const useActiveStore = defineStore('active', () => {
*/
const activeView = ref<IView>()

// Set the active node on the router params
watch(activeNode, () => {
if (!activeNode.value?.fileid || activeNode.value.fileid === activeFolder.value?.fileid) {
return
}

window.OCP.Files.Router.goToRoute(
null,
{ ...window.OCP.Files.Router.params, fileid: String(activeNode.value.fileid) },
{ ...window.OCP.Files.Router.query },
true,
)
})

initialize()

/**
Expand Down Expand Up @@ -62,12 +76,10 @@ export const useActiveStore = defineStore('active', () => {
*/
function initialize() {
const navigation = getNavigation()
onChangedView(navigation.active)

// Make sure we only register the listeners once
subscribe('files:node:deleted', onDeletedNode)

onChangedView(navigation.active)

// Or you can react to changes of the current active view
navigation.addEventListener('updateActive', (event) => {
onChangedView(event.detail)
Expand Down
20 changes: 13 additions & 7 deletions apps/systemtags/src/files_actions/bulkSystemTagsAction.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
/*!
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import type { INode } from '@nextcloud/files'
import type { ActionContext, ActionContextSingle } from '@nextcloud/files'

import TagMultipleSvg from '@mdi/svg/svg/tag-multiple-outline.svg?raw'
import { FileAction, Permission } from '@nextcloud/files'
Expand All @@ -15,10 +15,10 @@ import { defineAsyncComponent } from 'vue'
/**
* Spawn a dialog to add or remove tags from multiple nodes.
*
* @param nodes Nodes to modify tags for
* @param nodes.nodes
* @param context - The action context
* @param context.nodes - Nodes to modify tags for
*/
async function execBatch({ nodes }: { nodes: INode[] }): Promise<(null | boolean)[]> {
async function execBatch({ nodes }: ActionContext | ActionContextSingle): Promise<(null | boolean)[]> {
const response = await new Promise<null | boolean>((resolve) => {
spawnDialog(defineAsyncComponent(() => import('../components/SystemTagPicker.vue')), {
nodes,
Expand Down Expand Up @@ -53,9 +53,15 @@ export const action = new FileAction({
return !nodes.some((node) => (node.permissions & Permission.UPDATE) === 0)
},

async exec({ nodes }) {
return execBatch({ nodes })[0]
async exec(context: ActionContextSingle) {
const [result] = await execBatch(context)
return result
},

execBatch,

hotkey: {
description: t('systemtags', 'Manage tags'),
key: 't',
},
})
21 changes: 9 additions & 12 deletions apps/systemtags/src/files_actions/inlineSystemTagsAction.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
/*!
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import type { Node } from '@nextcloud/files'
import type { INode } from '@nextcloud/files'
import type { TagWithId } from '../types.ts'

import { subscribe } from '@nextcloud/event-bus'
Expand Down Expand Up @@ -44,11 +44,6 @@ export const action = new FileAction({
},

order: 0,

hotkey: {
description: t('files', 'Manage tags'),
key: 'T',
},
})

// Subscribe to the events
Expand All @@ -62,7 +57,7 @@ subscribe('systemtags:tag:updated', updateTag)
*
* @param node - The updated node
*/
function updateSystemTagsHtml(node: Node) {
function updateSystemTagsHtml(node: INode) {
renderInline(node).then((systemTagsHtml) => {
document.querySelectorAll(`[data-systemtags-fileid="${node.fileid}"]`).forEach((element) => {
element.replaceWith(systemTagsHtml)
Expand Down Expand Up @@ -113,9 +108,10 @@ function updateSystemTagsColorAttribute(tag: TagWithId) {
}

/**
* Render a single tag element
*
* @param tag
* @param isMore
* @param tag - The tag to render
* @param isMore - Whether this is a "more" tag
*/
function renderTag(tag: string, isMore = false): HTMLElement {
const tagElement = document.createElement('li')
Expand Down Expand Up @@ -143,10 +139,11 @@ function renderTag(tag: string, isMore = false): HTMLElement {
}

/**
* Render the inline system tags for a node
*
* @param node
* @param node - The node to render the tags for
*/
async function renderInline(node: Node): Promise<HTMLElement> {
async function renderInline(node: INode): Promise<HTMLElement> {
// Ensure we have the system tags as an array
const tags = getNodeSystemTags(node)

Expand Down
5 changes: 0 additions & 5 deletions apps/systemtags/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { registerFileSidebarAction } from './files_actions/filesSidebarAction.ts
import { action as inlineSystemTagsAction } from './files_actions/inlineSystemTagsAction.ts'
import { action as openInFilesAction } from './files_actions/openInFilesAction.ts'
import { registerSystemTagsView } from './files_views/systemtagsView.ts'
import { registerHotkeys } from './services/HotKeysService.ts'

registerDavProperty('nc:system-tags')
registerFileAction(bulkSystemTagsAction)
Expand All @@ -19,7 +18,3 @@ registerFileAction(openInFilesAction)

registerSystemTagsView()
registerFileSidebarAction()

document.addEventListener('DOMContentLoaded', () => {
registerHotkeys()
})
Loading
Loading