import { useEffect, useRef } from 'react' import { useSessionStore } from '../stores/sessionStore' import { useChatStore } from '../stores/chatStore' import { useTabStore } from '../stores/tabStore' import { useUIStore } from '../stores/uiStore' import { getAppZoomKeyboardAction, nextAppZoomLevel, } from '../lib/appZoom' import { useSettingsStore } from '../stores/settingsStore' export function useKeyboardShortcuts() { const setActiveSession = useSessionStore((s) => s.setActiveSession) const setActiveView = useUIStore((s) => s.setActiveView) const setSidebarOpen = useUIStore((s) => s.setSidebarOpen) const closeModal = useUIStore((s) => s.closeModal) const activeModal = useUIStore((s) => s.activeModal) const stopGeneration = useChatStore((s) => s.stopGeneration) const activeTabId = useTabStore((s) => s.activeTabId) const chatState = useChatStore((s) => activeTabId ? s.sessions[activeTabId]?.chatState ?? 'idle' : 'idle') const uiZoom = useSettingsStore((s) => s.uiZoom) const setUiZoom = useSettingsStore((s) => s.setUiZoom) const activeModalRef = useRef(activeModal) activeModalRef.current = activeModal const chatStateRef = useRef(chatState) chatStateRef.current = chatState const activeTabIdRef = useRef(activeTabId) activeTabIdRef.current = activeTabId const appZoomLevelRef = useRef(uiZoom) appZoomLevelRef.current = uiZoom useEffect(() => { const handler = (e: KeyboardEvent) => { const zoomAction = getAppZoomKeyboardAction(e) if (zoomAction) { e.preventDefault() const nextZoom = nextAppZoomLevel(appZoomLevelRef.current, zoomAction) appZoomLevelRef.current = nextZoom setUiZoom(nextZoom) return } const meta = e.metaKey || e.ctrlKey // Cmd+N — New session if (meta && e.key === 'n') { e.preventDefault() setActiveSession(null) setActiveView('code') } // Cmd+K — Focus search (sidebar search input) if (meta && e.key === 'k') { e.preventDefault() setSidebarOpen(true) requestAnimationFrame(() => { const searchInput = document.querySelector('#sidebar-search') as HTMLInputElement | null searchInput?.focus() searchInput?.select() }) } // Escape — Close modal or clear state if (e.key === 'Escape') { if (activeModalRef.current) { closeModal() } } // Cmd+. — Stop generation if (meta && e.key === '.') { if (chatStateRef.current !== 'idle' && activeTabIdRef.current) { e.preventDefault() stopGeneration(activeTabIdRef.current) } } } document.addEventListener('keydown', handler) return () => document.removeEventListener('keydown', handler) }, [closeModal, setActiveSession, setActiveView, setSidebarOpen, setUiZoom, stopGeneration]) }