mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
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:
+1
-1
@@ -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
@@ -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
|
||||
|
||||
-12
@@ -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());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user