From 14c032aaffd886ec578620014e373ce4012a46b1 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Tue, 22 Apr 2025 20:13:52 +0800 Subject: [PATCH] feat: add global keyboard shortcut to toggle fullscreen with F11, closes #933 (#942) --- apps/readest-app/src/app/library/page.tsx | 11 ++++++++++- .../src/app/reader/hooks/useBookShortcuts.ts | 9 ++++++++- apps/readest-app/src/helpers/shortcuts.ts | 2 ++ apps/readest-app/src/hooks/useShortcuts.ts | 13 +++++++------ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/apps/readest-app/src/app/library/page.tsx b/apps/readest-app/src/app/library/page.tsx index bc4dc1da..040f9d85 100644 --- a/apps/readest-app/src/app/library/page.tsx +++ b/apps/readest-app/src/app/library/page.tsx @@ -30,7 +30,11 @@ import { useDemoBooks } from './hooks/useDemoBooks'; import { useBooksSync } from './hooks/useBooksSync'; import { useScreenWakeLock } from '@/hooks/useScreenWakeLock'; import { useOpenWithBooks } from '@/hooks/useOpenWithBooks'; -import { tauriHandleSetAlwaysOnTop, tauriQuitApp } from '@/utils/window'; +import { + tauriHandleSetAlwaysOnTop, + tauriHandleToggleFullScreen, + tauriQuitApp, +} from '@/utils/window'; import { AboutWindow } from '@/components/AboutWindow'; import { UpdaterWindow } from '@/components/UpdaterWindow'; @@ -85,6 +89,11 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP useScreenWakeLock(settings.screenWakeLock); useShortcuts({ + onToggleFullscreen: async () => { + if (isTauriAppPlatform()) { + await tauriHandleToggleFullScreen(); + } + }, onQuitApp: async () => { if (isTauriAppPlatform()) { await tauriQuitApp(); diff --git a/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts b/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts index aa0db947..96e17137 100644 --- a/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts +++ b/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts @@ -6,7 +6,7 @@ import useBooksManager from './useBooksManager'; import { useSidebarStore } from '@/store/sidebarStore'; import { useSettingsStore } from '@/store/settingsStore'; import { getStyles } from '@/utils/style'; -import { tauriQuitApp } from '@/utils/window'; +import { tauriHandleToggleFullScreen, tauriQuitApp } from '@/utils/window'; import { eventDispatcher } from '@/utils/event'; import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL, ZOOM_STEP } from '@/services/constants'; @@ -84,6 +84,12 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) = window.location.reload(); }; + const toggleFullscreen = async () => { + if (isTauriAppPlatform()) { + await tauriHandleToggleFullScreen(); + } + }; + const quitApp = async () => { // on web platform use browser's default shortcut to close the tab if (isTauriAppPlatform()) { @@ -136,6 +142,7 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) = onOpenFontLayoutSettings: () => setFontLayoutSettingsDialogOpen(true), onToggleSearchBar: showSearchBar, onReloadPage: reloadPage, + onToggleFullscreen: toggleFullscreen, onQuitApp: quitApp, onGoLeft: goLeft, onGoRight: goRight, diff --git a/apps/readest-app/src/helpers/shortcuts.ts b/apps/readest-app/src/helpers/shortcuts.ts index 632b4f22..2cdddf86 100644 --- a/apps/readest-app/src/helpers/shortcuts.ts +++ b/apps/readest-app/src/helpers/shortcuts.ts @@ -7,6 +7,7 @@ export interface ShortcutConfig { onToggleSelectMode: string[]; onOpenFontLayoutSettings: string[]; onReloadPage: string[]; + onToggleFullscreen: string[]; onQuitApp: string[]; onGoLeft: string[]; onGoRight: string[]; @@ -32,6 +33,7 @@ const DEFAULT_SHORTCUTS: ShortcutConfig = { onToggleSelectMode: ['shift+s'], onOpenFontLayoutSettings: ['shift+f'], onReloadPage: ['shift+r'], + onToggleFullscreen: ['F11'], onQuitApp: ['ctrl+q', 'cmd+q'], onGoLeft: ['ArrowLeft', 'PageUp', 'h'], onGoRight: ['ArrowRight', 'PageDown', 'l', ' '], diff --git a/apps/readest-app/src/hooks/useShortcuts.ts b/apps/readest-app/src/hooks/useShortcuts.ts index a91a46df..0fe7fcce 100644 --- a/apps/readest-app/src/hooks/useShortcuts.ts +++ b/apps/readest-app/src/hooks/useShortcuts.ts @@ -63,8 +63,8 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency handler && shortcutList?.some((shortcut) => isShortcutMatch(shortcut, key, ctrlKey, altKey, metaKey, shiftKey), - ) - ) { + ) + ) { handler(); return true; } @@ -76,11 +76,12 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency // Check if the focus is on an input, textarea, or contenteditable element const activeElement = document.activeElement as HTMLElement; const isInteractiveElement = - (activeElement.tagName === 'INPUT' || + activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || - activeElement.isContentEditable); + activeElement.isContentEditable; - const isNoteEditor = (activeElement.tagName === 'TEXTAREA' && activeElement.classList.contains('note-editor')) + const isNoteEditor = + activeElement.tagName === 'TEXTAREA' && activeElement.classList.contains('note-editor'); if (isInteractiveElement && !isNoteEditor) { return; // Skip handling if the user is typing in an input, textarea, or contenteditable @@ -89,7 +90,7 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency if (event instanceof KeyboardEvent) { const { key, ctrlKey, altKey, metaKey, shiftKey } = event; - if (isNoteEditor && !((key === "Enter" && ctrlKey) || (key == "Escape"))) { + if (isNoteEditor && !((key === 'Enter' && ctrlKey) || key == 'Escape')) { return; }