|
|
import paths from "./paths"; |
|
|
import { useEffect } from "react"; |
|
|
import { userFromStorage } from "./request"; |
|
|
import { TOGGLE_LLM_SELECTOR_EVENT } from "@/components/WorkspaceChat/ChatContainer/PromptInput/LLMSelector/action"; |
|
|
|
|
|
export const KEYBOARD_SHORTCUTS_HELP_EVENT = "keyboard-shortcuts-help"; |
|
|
export const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0; |
|
|
export const SHORTCUTS = { |
|
|
"⌘ + ,": { |
|
|
translationKey: "settings", |
|
|
action: () => { |
|
|
window.location.href = paths.settings.interface(); |
|
|
}, |
|
|
}, |
|
|
"⌘ + H": { |
|
|
translationKey: "home", |
|
|
action: () => { |
|
|
window.location.href = paths.home(); |
|
|
}, |
|
|
}, |
|
|
"⌘ + I": { |
|
|
translationKey: "workspaces", |
|
|
action: () => { |
|
|
window.location.href = paths.settings.workspaces(); |
|
|
}, |
|
|
}, |
|
|
"⌘ + K": { |
|
|
translationKey: "apiKeys", |
|
|
action: () => { |
|
|
window.location.href = paths.settings.apiKeys(); |
|
|
}, |
|
|
}, |
|
|
"⌘ + L": { |
|
|
translationKey: "llmPreferences", |
|
|
action: () => { |
|
|
window.location.href = paths.settings.llmPreference(); |
|
|
}, |
|
|
}, |
|
|
"⌘ + Shift + C": { |
|
|
translationKey: "chatSettings", |
|
|
action: () => { |
|
|
window.location.href = paths.settings.chat(); |
|
|
}, |
|
|
}, |
|
|
"⌘ + Shift + ?": { |
|
|
translationKey: "help", |
|
|
action: () => { |
|
|
window.dispatchEvent( |
|
|
new CustomEvent(KEYBOARD_SHORTCUTS_HELP_EVENT, { |
|
|
detail: { show: true }, |
|
|
}) |
|
|
); |
|
|
}, |
|
|
}, |
|
|
F1: { |
|
|
translationKey: "help", |
|
|
action: () => { |
|
|
window.dispatchEvent( |
|
|
new CustomEvent(KEYBOARD_SHORTCUTS_HELP_EVENT, { |
|
|
detail: { show: true }, |
|
|
}) |
|
|
); |
|
|
}, |
|
|
}, |
|
|
"⌘ + Shift + L": { |
|
|
translationKey: "showLLMSelector", |
|
|
action: () => { |
|
|
window.dispatchEvent(new Event(TOGGLE_LLM_SELECTOR_EVENT)); |
|
|
}, |
|
|
}, |
|
|
}; |
|
|
|
|
|
const LISTENERS = {}; |
|
|
const modifier = isMac ? "meta" : "ctrl"; |
|
|
for (const key in SHORTCUTS) { |
|
|
const listenerKey = key |
|
|
.replace("⌘", modifier) |
|
|
.replaceAll(" ", "") |
|
|
.toLowerCase(); |
|
|
LISTENERS[listenerKey] = SHORTCUTS[key].action; |
|
|
} |
|
|
|
|
|
|
|
|
function getShortcutKey(event) { |
|
|
let key = ""; |
|
|
if (event.metaKey || event.ctrlKey) key += modifier + "+"; |
|
|
if (event.shiftKey) key += "shift+"; |
|
|
if (event.altKey) key += "alt+"; |
|
|
|
|
|
|
|
|
if (event.key === ",") key += ","; |
|
|
|
|
|
else if (event.key === "?" || event.key === "/") key += "?"; |
|
|
else if (event.key === "Control") |
|
|
return ""; |
|
|
else if (event.key === "Shift") |
|
|
return ""; |
|
|
else key += event.key.toLowerCase(); |
|
|
return key; |
|
|
} |
|
|
|
|
|
|
|
|
export function initKeyboardShortcuts() { |
|
|
function handleKeyDown(event) { |
|
|
const shortcutKey = getShortcutKey(event); |
|
|
if (!shortcutKey) return; |
|
|
|
|
|
const action = LISTENERS[shortcutKey]; |
|
|
if (action) { |
|
|
event.preventDefault(); |
|
|
action(); |
|
|
} |
|
|
} |
|
|
|
|
|
window.addEventListener("keydown", handleKeyDown); |
|
|
return () => window.removeEventListener("keydown", handleKeyDown); |
|
|
} |
|
|
|
|
|
function useKeyboardShortcuts() { |
|
|
useEffect(() => { |
|
|
|
|
|
|
|
|
const user = userFromStorage(); |
|
|
if (!!user && user?.role !== "admin") return; |
|
|
const cleanup = initKeyboardShortcuts(); |
|
|
|
|
|
return () => cleanup(); |
|
|
}, []); |
|
|
return; |
|
|
} |
|
|
|
|
|
export function KeyboardShortcutWrapper({ children }) { |
|
|
useKeyboardShortcuts(); |
|
|
return children; |
|
|
} |
|
|
|