'use client'; import { useEffect, useRef } from 'react'; import { useDockviewStore } from '@/lib/state/dockview-store'; import { useAppStoreApi } from '@/components/state-provider'; import { createUserShell } from '@/lib/api/domains/user-shell-api'; import type { DockviewApi } from 'dockview-react'; function handleTabNavigation(e: KeyboardEvent, api: DockviewApi) { const activePanel = api.activePanel; if (!activePanel) return; const panels = activePanel.group.panels; if (panels.length <= 1) return; const currentIndex = panels.findIndex((p) => p.id === activePanel.id); if (currentIndex === -1) return; e.preventDefault(); e.stopPropagation(); const direction = e.code === 'BracketLeft' ? -1 : 1; const nextIndex = (currentIndex + direction + panels.length) % panels.length; panels[nextIndex].api.setActive(); } function handleTerminalToggle( e: KeyboardEvent, api: DockviewApi, previousPanelIdRef: React.MutableRefObject, getSessionId: () => string | null, ) { e.preventDefault(); e.stopPropagation(); const activePanel = api.activePanel; const isTerminalFocused = activePanel?.id.startsWith('terminal-') ?? false; if (isTerminalFocused) { const prevId = previousPanelIdRef.current; const target = prevId ? api.getPanel(prevId) : api.getPanel('chat'); if (target) target.api.setActive(); previousPanelIdRef.current = null; return; } if (activePanel) { previousPanelIdRef.current = activePanel.id; } const terminalPanel = api.panels.find((p) => p.id.startsWith('terminal-')); if (terminalPanel) { terminalPanel.api.setActive(); return; } const sessionId = getSessionId(); if (!sessionId) return; createUserShell(sessionId) .then((result) => { useDockviewStore.getState().addTerminalPanel(result.terminalId); }) .catch((err) => { console.warn('Failed to create terminal shell:', err); }); } /** * Global editor keybinds for dockview: * - Cmd/Ctrl+Shift+[ / ] — navigate prev/next tab in active group * - Ctrl+` — toggle terminal focus */ export function useEditorKeybinds() { const previousPanelIdRef = useRef(null); const appStore = useAppStoreApi(); useEffect(() => { const handler = (e: KeyboardEvent) => { const api = useDockviewStore.getState().api; if (!api) return; const isTabNav = (e.metaKey || e.ctrlKey) && e.shiftKey && (e.code === 'BracketLeft' || e.code === 'BracketRight'); if (isTabNav) { handleTabNavigation(e, api); return; } const isTerminalToggle = e.ctrlKey && !e.metaKey && !e.shiftKey && e.code === 'Backquote'; if (isTerminalToggle) { handleTerminalToggle( e, api, previousPanelIdRef, () => appStore.getState().tasks.activeSessionId, ); } }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, [appStore]); }