Refactor keyboard shortcuts; add Turkish README

Use dashboard store state at handler runtime and simplify shortcut wiring to avoid stale closures. App.tsx: replace many useDashboardStore selectors with runtime getState() calls inside keyboard shortcut actions and reduce useMemo dependencies to showKeyboardHelp. KeyboardShortcutsHelp.tsx: remove local Escape key effect (handled globally). useKeyboardShortcuts.ts: ignore shortcuts while typing in inputs/textareas/contentEditable (allow Escape), and improve Mac detection via userAgentData.platform fallback; use the same isMac flag in formatShortcutKey. README (zh-CN & ja-JP): add link to Turkish README (README.tr-TR.md).
This commit is contained in:
Berkcan Gümüşışık
2026-03-23 19:58:29 +03:00
Unverified
parent 5f23a45e3d
commit 6723ff3ea5
5 changed files with 39 additions and 48 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
</p>
<p align="center">
<a href="README.md">English</a> | <a href="README.zh-CN.md">中文</a> | <a href="README.ja-JP.md">日本語</a>
<a href="README.md">English</a> | <a href="README.zh-CN.md">中文</a> | <a href="README.ja-JP.md">日本語</a> | <a href="README.tr-TR.md">Türkçe</a>
</p>
<p align="center">
+1 -1
View File
@@ -4,7 +4,7 @@
</p>
<p align="center">
<a href="README.md">English</a> | <a href="README.zh-CN.md">中文</a> | <a href="README.ja-JP.md">日本語</a>
<a href="README.md">English</a> | <a href="README.zh-CN.md">中文</a> | <a href="README.ja-JP.md">日本語</a> | <a href="README.tr-TR.md">Türkçe</a>
</p>
<p align="center">
@@ -23,12 +23,6 @@ function App() {
const codeViewerOpen = useDashboardStore((s) => s.codeViewerOpen);
const closeCodeViewer = useDashboardStore((s) => s.closeCodeViewer);
const setDiffOverlay = useDashboardStore((s) => s.setDiffOverlay);
const selectNode = useDashboardStore((s) => s.selectNode);
const toggleLayers = useDashboardStore((s) => s.toggleLayers);
const toggleDiffMode = useDashboardStore((s) => s.toggleDiffMode);
const stopTour = useDashboardStore((s) => s.stopTour);
const nextTourStep = useDashboardStore((s) => s.nextTourStep);
const prevTourStep = useDashboardStore((s) => s.prevTourStep);
const [loadError, setLoadError] = useState<string | null>(null);
const [showKeyboardHelp, setShowKeyboardHelp] = useState(false);
@@ -38,7 +32,6 @@ function App() {
// Help
{
key: "?",
shiftKey: true,
description: "Show keyboard shortcuts",
action: () => setShowKeyboardHelp((prev) => !prev),
category: "General",
@@ -48,14 +41,16 @@ function App() {
key: "Escape",
description: "Close panels and modals",
action: () => {
// Read from store at invocation time to avoid stale closures
const state = useDashboardStore.getState();
if (showKeyboardHelp) {
setShowKeyboardHelp(false);
} else if (codeViewerOpen) {
closeCodeViewer();
} else if (selectedNodeId) {
selectNode(null);
} else if (tourActive) {
stopTour();
} else if (state.codeViewerOpen) {
state.closeCodeViewer();
} else if (state.selectedNodeId) {
state.selectNode(null);
} else if (state.tourActive) {
state.stopTour();
}
},
category: "Navigation",
@@ -76,8 +71,9 @@ function App() {
key: "ArrowRight",
description: "Next tour step",
action: () => {
if (tourActive) {
nextTourStep();
const state = useDashboardStore.getState();
if (state.tourActive) {
state.nextTourStep();
}
},
category: "Tour",
@@ -86,8 +82,9 @@ function App() {
key: "ArrowLeft",
description: "Previous tour step",
action: () => {
if (tourActive) {
prevTourStep();
const state = useDashboardStore.getState();
if (state.tourActive) {
state.prevTourStep();
}
},
category: "Tour",
@@ -96,29 +93,23 @@ function App() {
{
key: "l",
description: "Toggle layer visualization",
action: toggleLayers,
action: () => {
const state = useDashboardStore.getState();
state.toggleLayers();
},
category: "View",
},
{
key: "d",
description: "Toggle diff mode",
action: toggleDiffMode,
action: () => {
const state = useDashboardStore.getState();
state.toggleDiffMode();
},
category: "View",
},
],
[
showKeyboardHelp,
codeViewerOpen,
selectedNodeId,
tourActive,
closeCodeViewer,
selectNode,
stopTour,
nextTourStep,
prevTourStep,
toggleLayers,
toggleDiffMode,
]
[showKeyboardHelp]
);
// Register keyboard shortcuts
@@ -1,4 +1,3 @@
import { useEffect } from "react";
import type { KeyboardShortcut } from "../hooks/useKeyboardShortcuts";
import { formatShortcutKey } from "../hooks/useKeyboardShortcuts";
@@ -11,17 +10,6 @@ export default function KeyboardShortcutsHelp({
shortcuts,
onClose,
}: KeyboardShortcutsHelpProps) {
// Close on Escape key
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === "Escape") {
onClose();
}
};
document.addEventListener("keydown", handleEscape);
return () => document.removeEventListener("keydown", handleEscape);
}, [onClose]);
// Group shortcuts by category
const groupedShortcuts = shortcuts.reduce((acc, shortcut) => {
if (!acc[shortcut.category]) {
@@ -19,6 +19,13 @@ export function useKeyboardShortcuts(
if (!enabled) return;
const handleKeyDown = (event: KeyboardEvent) => {
// Prevent shortcuts from firing when typing in input fields
const target = event.target as HTMLElement;
const tagName = target.tagName.toLowerCase();
if (tagName === 'input' || tagName === 'textarea' || target.isContentEditable) {
if (event.key !== 'Escape') return;
}
for (const shortcut of shortcuts) {
const keyMatches = event.key.toLowerCase() === shortcut.key.toLowerCase();
const ctrlMatches = shortcut.ctrlKey ? event.ctrlKey : !event.ctrlKey;
@@ -45,11 +52,16 @@ export function useKeyboardShortcuts(
export function formatShortcutKey(shortcut: KeyboardShortcut): string {
const keys: string[] = [];
// Use userAgentData with fallback to navigator.platform
const isMac = (navigator as Navigator & { userAgentData?: { platform: string } }).userAgentData?.platform
? (navigator as Navigator & { userAgentData: { platform: string } }).userAgentData.platform === 'macOS'
: navigator.platform.includes("Mac");
if (shortcut.ctrlKey || shortcut.metaKey) {
keys.push(navigator.platform.includes("Mac") ? "⌘" : "Ctrl");
keys.push(isMac ? "⌘" : "Ctrl");
}
if (shortcut.shiftKey) keys.push("⇧");
if (shortcut.altKey) keys.push(navigator.platform.includes("Mac") ? "⌥" : "Alt");
if (shortcut.altKey) keys.push(isMac ? "⌥" : "Alt");
keys.push(shortcut.key.toUpperCase());