perf: improve smoothness of Arrow Up/Down scrolling, closes #2080 (#2306)

This commit is contained in:
Huang Xin
2025-10-23 21:32:51 +08:00
committed by GitHub
parent 5bde091704
commit 55c97cab7e
4 changed files with 39 additions and 8 deletions
@@ -81,6 +81,32 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) =
getView(sideBarBookKey)?.next(distance);
};
const goPrevArrowUp = (event?: KeyboardEvent | MessageEvent) => {
const view = getView(sideBarBookKey);
if (
view?.renderer.scrolled &&
event instanceof MessageEvent &&
event.data.type === 'iframe-keydown'
) {
// already handled in the iframe for better smoothness
return;
}
view?.prev(distance);
};
const goNextArrowDown = (event?: KeyboardEvent | MessageEvent) => {
const view = getView(sideBarBookKey);
if (
view?.renderer.scrolled &&
event instanceof MessageEvent &&
event.data.type === 'iframe-keydown'
) {
// already handled in the iframe for better smoothness
return;
}
view?.next(distance);
};
const goBack = () => {
getView(sideBarBookKey)?.history.back();
};
@@ -194,6 +220,8 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) =
onGoRight: goRight,
onGoPrev: goPrev,
onGoNext: goNext,
onGoPrevArrowUp: goPrevArrowUp,
onGoNextArrowDown: goNextArrowDown,
onGoHalfPageDown: goHalfPageDown,
onGoHalfPageUp: goHalfPageUp,
onGoPrevSection: goPrevSection,
@@ -5,7 +5,7 @@ let lastClickTime = 0;
let longHoldTimeout: ReturnType<typeof setTimeout> | null = null;
export const handleKeydown = (bookKey: string, event: KeyboardEvent) => {
if (['Backspace', 'ArrowDown', 'ArrowUp'].includes(event.key)) {
if (['Backspace'].includes(event.key)) {
event.preventDefault();
}
window.postMessage(
+4 -2
View File
@@ -15,8 +15,10 @@ const DEFAULT_SHORTCUTS = {
onQuitApp: ['ctrl+q', 'cmd+q'],
onGoLeft: ['ArrowLeft', 'PageUp', 'h', 'shift+ '],
onGoRight: ['ArrowRight', 'PageDown', 'l', ' '],
onGoNext: ['ArrowDown', 'j'],
onGoPrev: ['ArrowUp', 'k'],
onGoNext: ['j'],
onGoPrev: ['k'],
onGoNextArrowDown: ['ArrowDown'],
onGoPrevArrowUp: ['ArrowUp'],
onGoLeftSection: ['opt+ArrowLeft', 'alt+ArrowLeft'],
onGoRightSection: ['opt+ArrowRight', 'alt+ArrowRight'],
onGoPrevSection: ['opt+ArrowUp', 'alt+ArrowUp'],
+6 -5
View File
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
import { loadShortcuts, ShortcutConfig } from '../helpers/shortcuts';
export type KeyActionHandlers = {
[K in keyof ShortcutConfig]?: () => void;
[K in keyof ShortcutConfig]?: (event?: KeyboardEvent | MessageEvent) => void;
};
const useShortcuts = (actions: KeyActionHandlers, dependencies: React.DependencyList = []) => {
@@ -52,12 +52,13 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency
altKey: boolean,
metaKey: boolean,
shiftKey: boolean,
event: KeyboardEvent | MessageEvent,
) => {
// FIXME: This is a temporary fix to disable Back button navigation
if (key === 'backspace') return true;
for (const [actionName, actionHandler] of Object.entries(actions)) {
const shortcutKey = actionName as keyof ShortcutConfig;
const handler = actionHandler as (() => void) | undefined;
const handler = actionHandler as ((event?: KeyboardEvent | MessageEvent) => void) | undefined;
const shortcutList = shortcuts[shortcutKey as keyof ShortcutConfig];
if (
handler &&
@@ -65,7 +66,7 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency
isShortcutMatch(shortcut, key, ctrlKey, altKey, metaKey, shiftKey),
)
) {
handler();
handler(event);
return true;
}
}
@@ -94,7 +95,7 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency
return;
}
const handled = processKeyEvent(key.toLowerCase(), ctrlKey, altKey, metaKey, shiftKey);
const handled = processKeyEvent(key.toLowerCase(), ctrlKey, altKey, metaKey, shiftKey, event);
if (handled) event.preventDefault();
} else if (
event instanceof MessageEvent &&
@@ -102,7 +103,7 @@ const useShortcuts = (actions: KeyActionHandlers, dependencies: React.Dependency
event.data.type === 'iframe-keydown'
) {
const { key, ctrlKey, altKey, metaKey, shiftKey } = event.data;
processKeyEvent(key.toLowerCase(), ctrlKey, altKey, metaKey, shiftKey);
processKeyEvent(key.toLowerCase(), ctrlKey, altKey, metaKey, shiftKey, event);
}
};