diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 80d99b1..786dd3b 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -3,6 +3,7 @@ import { onMounted, onUnmounted, watch } from "vue"; import AppHeader from "@/components/AppHeader.vue"; import ToastNotification from "@/components/ToastNotification.vue"; import { useTheme } from "@/composables/useTheme"; +import { useShortcuts } from "@/composables/useShortcuts"; import { useAuthStore } from "@/stores/auth"; import { useChatStore } from "@/stores/chat"; import { useSettingsStore } from "@/stores/settings"; @@ -12,6 +13,7 @@ useTheme(); const authStore = useAuthStore(); const chatStore = useChatStore(); const settingsStore = useSettingsStore(); +const { showShortcuts, toggleShortcuts, closeShortcuts } = useShortcuts(); function startAppServices() { chatStore.startStatusPolling(); @@ -22,7 +24,28 @@ function stopAppServices() { chatStore.stopStatusPolling(); } +function isInputActive(): boolean { + const el = document.activeElement; + if (!el) return false; + const tag = (el as HTMLElement).tagName; + return tag === "INPUT" || tag === "TEXTAREA" || (el as HTMLElement).isContentEditable; +} + +function onGlobalKeydown(e: KeyboardEvent) { + if (!authStore.isAuthenticated) return; + // ? — toggle shortcuts overlay (only when not typing) + if (e.key === "?" && !isInputActive() && !e.ctrlKey && !e.metaKey) { + toggleShortcuts(); + return; + } + // Escape — close shortcuts overlay + if (e.key === "Escape" && showShortcuts.value) { + closeShortcuts(); + } +} + onMounted(async () => { + document.addEventListener("keydown", onGlobalKeydown); await authStore.checkAuth(); if (authStore.isAuthenticated) { startAppServices(); @@ -41,6 +64,7 @@ watch( ); onUnmounted(() => { + document.removeEventListener("keydown", onGlobalKeydown); stopAppServices(); }); @@ -53,6 +77,48 @@ onUnmounted(() => { + + + +
+
+
+

Keyboard Shortcuts

+ +
+
+
+
Navigation
+
+ Esc + Go to home / close dialog +
+
+ ? + Toggle this shortcuts panel +
+
+
+
Chat
+
+ Enter + Send message +
+
+ Shift + + + Enter + New line in message +
+
+ Esc + Clear input / go home +
+
+
+
+
+