diff options
-rw-r--r-- | apps/files/src/FilesApp.vue | 6 | ||||
-rw-r--r-- | apps/files/src/composables/useHotKeys.spec.ts (renamed from apps/files/src/services/HotKeysService.spec.ts) | 70 | ||||
-rw-r--r-- | apps/files/src/composables/useHotKeys.ts (renamed from apps/files/src/services/HotKeysService.ts) | 46 | ||||
-rw-r--r-- | apps/files/src/main.ts | 4 |
4 files changed, 77 insertions, 49 deletions
diff --git a/apps/files/src/FilesApp.vue b/apps/files/src/FilesApp.vue index 54821a03457..6fc02113162 100644 --- a/apps/files/src/FilesApp.vue +++ b/apps/files/src/FilesApp.vue @@ -12,11 +12,10 @@ <script lang="ts"> import { isPublicShare } from '@nextcloud/sharing/public' import { defineComponent } from 'vue' - import NcContent from '@nextcloud/vue/components/NcContent' - import Navigation from './views/Navigation.vue' import FilesList from './views/FilesList.vue' +import { useHotKeys } from './composables/useHotKeys' export default defineComponent({ name: 'FilesApp', @@ -28,6 +27,9 @@ export default defineComponent({ }, setup() { + // Register global hotkeys + useHotKeys() + const isPublic = isPublicShare() return { diff --git a/apps/files/src/services/HotKeysService.spec.ts b/apps/files/src/composables/useHotKeys.spec.ts index 7bbba77b222..d36dca3863a 100644 --- a/apps/files/src/services/HotKeysService.spec.ts +++ b/apps/files/src/composables/useHotKeys.spec.ts @@ -2,9 +2,12 @@ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ +import type { Location } from 'vue-router' + import { File, Permission, View } from '@nextcloud/files' -import { describe, it, vi, expect, beforeEach, beforeAll, afterEach } from 'vitest' -import { nextTick } from 'vue' +import { enableAutoDestroy, mount } from '@vue/test-utils' +import { describe, it, vi, expect, beforeEach, afterEach } from 'vitest' +import { defineComponent, nextTick } from 'vue' import axios from '@nextcloud/axios' import { getPinia } from '../store/index.ts' @@ -14,38 +17,64 @@ 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 { registerHotkeys } from './HotKeysService.ts' +import { useHotKeys } from './useHotKeys.ts' import { useUserConfigStore } from '../store/userconfig.ts' +// this is the mocked current route +const route = vi.hoisted(() => ({ + name: 'test', + params: { + fileId: 123, + }, + query: { + openFile: 'false', + dir: '/parent/dir', + }, +})) + +// mocked router +const router = vi.hoisted(() => ({ + push: vi.fn<(route: Location) => void>(), +})) + +vi.mock('../actions/sidebarAction.ts', { spy: true }) +vi.mock('../actions/deleteAction.ts', { spy: true }) +vi.mock('../actions/favoriteAction.ts', { spy: true }) +vi.mock('../actions/renameAction.ts', { spy: true }) + +vi.mock('vue-router/composables', () => ({ + useRoute: vi.fn(() => route), + useRouter: vi.fn(() => router), +})) + let file: File const view = { id: 'files', name: 'Files', } as View -vi.mock('../actions/sidebarAction.ts', { spy: true }) -vi.mock('../actions/deleteAction.ts', { spy: true }) -vi.mock('../actions/favoriteAction.ts', { spy: true }) -vi.mock('../actions/renameAction.ts', { spy: true }) +const TestComponent = defineComponent({ + name: 'test', + setup() { + useHotKeys() + }, + template: '<div />', +}) describe('HotKeysService testing', () => { const activeStore = useActiveStore(getPinia()) - const goToRouteMock = vi.fn() - let initialState: HTMLInputElement + enableAutoDestroy(afterEach) + afterEach(() => { document.body.removeChild(initialState) }) - beforeAll(() => { - registerHotkeys() - }) - beforeEach(() => { // Make sure the router is reset before each test - goToRouteMock.mockClear() + router.push.mockClear() // Make sure the file is reset before each test file = new File({ @@ -61,9 +90,6 @@ describe('HotKeysService testing', () => { activeStore.setActiveNode(file) window.OCA = { Files: { Sidebar: { open: () => {}, setActiveTab: () => {} } } } - // We only mock what needed, we do not need Files.Router.goTo or Files.Navigation - window.OCP = { Files: { Router: { goToRoute: goToRouteMock, params: {}, query: {} } } } - initialState = document.createElement('input') initialState.setAttribute('type', 'hidden') initialState.setAttribute('id', 'initial-state-files_trashbin-config') @@ -71,6 +97,8 @@ describe('HotKeysService testing', () => { allow_delete: true, }))) document.body.appendChild(initialState) + + mount(TestComponent) }) it('Pressing d should open the sidebar once', () => { @@ -130,13 +158,11 @@ describe('HotKeysService testing', () => { }) it('Pressing alt+up should go to parent directory', () => { - expect(goToRouteMock).toHaveBeenCalledTimes(0) - window.OCP.Files.Router.query = { dir: '/foo/bar' } - + expect(router.push).toHaveBeenCalledTimes(0) dispatchEvent({ key: 'ArrowUp', code: 'ArrowUp', altKey: true }) - expect(goToRouteMock).toHaveBeenCalledOnce() - expect(goToRouteMock.mock.calls[0][2].dir).toBe('/foo') + expect(router.push).toHaveBeenCalledOnce() + expect(router.push.mock.calls[0][0].query?.dir).toBe('/parent') }) it('Pressing v should toggle grid view', async () => { diff --git a/apps/files/src/services/HotKeysService.ts b/apps/files/src/composables/useHotKeys.ts index 1ed369b061b..ff56627b2f9 100644 --- a/apps/files/src/services/HotKeysService.ts +++ b/apps/files/src/composables/useHotKeys.ts @@ -4,13 +4,15 @@ */ 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 { executeAction } from '../utils/actionUtils.ts' import { useUserConfigStore } from '../store/userconfig.ts' +import { useRouteParameters } from './useRouteParameters.ts' +import { executeAction } from '../utils/actionUtils.ts' import logger from '../logger.ts' /** @@ -18,7 +20,12 @@ import logger from '../logger.ts' * As much as possible, we try to have all the hotkeys in one place. * Please make sure to add tests for the hotkeys after adding a new one. */ -export const registerHotkeys = function() { +export function useHotKeys(): void { + const userConfigStore = useUserConfigStore() + const { directory } = useRouteParameters() + const router = useRouter() + const route = useRoute() + // d opens the sidebar useHotKey('d', () => executeAction(sidebarAction), { stop: true, @@ -57,26 +64,23 @@ export const registerHotkeys = function() { }) logger.debug('Hotkeys registered') -} - -const goToParentDir = function() { - const params = window.OCP.Files.Router?.params || {} - const query = window.OCP.Files.Router?.query || {} - const currentDir = (query?.dir || '/') as string - const parentDir = dirname(currentDir) + /** + * Use the router to go to the parent directory + */ + function goToParentDir() { + const dir = dirname(directory.value) - logger.debug('Navigating to parent directory', { parentDir }) - window.OCP.Files.Router.goToRoute( - null, - { ...params }, - { ...query, dir: parentDir }, - ) -} + logger.debug('Navigating to parent directory', { dir }) + router.push({ params: { ...route.params }, query: { ...route.query, dir } }) + } -const toggleGridView = function() { - const userConfigStore = useUserConfigStore() - const value = userConfigStore?.userConfig?.grid_view - logger.debug('Toggling grid view', { old: value, new: !value }) - userConfigStore.update('grid_view', !value) + /** + * Toggle the grid view + */ + function toggleGridView() { + const value = userConfigStore.userConfig.grid_view + logger.debug('Toggling grid view', { old: value, new: !value }) + userConfigStore.update('grid_view', !value) + } } diff --git a/apps/files/src/main.ts b/apps/files/src/main.ts index 4b8aca9efd4..463ecaf6239 100644 --- a/apps/files/src/main.ts +++ b/apps/files/src/main.ts @@ -8,7 +8,6 @@ import { PiniaVuePlugin } from 'pinia' import Vue from 'vue' import { getPinia } from './store/index.ts' -import { registerHotkeys } from './services/HotKeysService.ts' import FilesApp from './FilesApp.vue' import router from './router/router' import RouterService from './services/RouterService' @@ -40,9 +39,6 @@ if (!window.OCP.Files.Router) { // Init Pinia store Vue.use(PiniaVuePlugin) -// Init HotKeys AFTER pinia is set up -registerHotkeys() - // Init Files App Settings Service const Settings = new SettingsService() Object.assign(window.OCA.Files, { Settings }) |