* AppContent component - Contains the main app logic, wrapped by providers
()
| 15 | * AppContent component - Contains the main app logic, wrapped by providers |
| 16 | */ |
| 17 | function AppContent() { |
| 18 | const { } = useTabState(); |
| 19 | const [showNFO, setShowNFO] = useState(false); |
| 20 | const [showClaudeBinaryDialog, setShowClaudeBinaryDialog] = useState(false); |
| 21 | const [toast, setToast] = useState<{ message: string; type: "success" | "error" | "info" } | null>(null); |
| 22 | const [showAgentsModal, setShowAgentsModal] = useState(false); |
| 23 | const [, setClaudeExecutableExists] = useState(true); |
| 24 | |
| 25 | // Keyboard shortcuts for tab navigation |
| 26 | useEffect(() => { |
| 27 | const handleKeyDown = (e: KeyboardEvent) => { |
| 28 | const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; |
| 29 | const modKey = isMac ? e.metaKey : e.ctrlKey; |
| 30 | |
| 31 | if (modKey) { |
| 32 | switch (e.key) { |
| 33 | case 't': |
| 34 | e.preventDefault(); |
| 35 | window.dispatchEvent(new CustomEvent('create-chat-tab')); |
| 36 | break; |
| 37 | case 'w': |
| 38 | e.preventDefault(); |
| 39 | window.dispatchEvent(new CustomEvent('close-current-tab')); |
| 40 | break; |
| 41 | case 'Tab': |
| 42 | e.preventDefault(); |
| 43 | if (e.shiftKey) { |
| 44 | window.dispatchEvent(new CustomEvent('switch-to-previous-tab')); |
| 45 | } else { |
| 46 | window.dispatchEvent(new CustomEvent('switch-to-next-tab')); |
| 47 | } |
| 48 | break; |
| 49 | default: |
| 50 | // Handle number keys 1-9 |
| 51 | const num = parseInt(e.key); |
| 52 | if (!isNaN(num) && num >= 1 && num <= 9) { |
| 53 | e.preventDefault(); |
| 54 | window.dispatchEvent(new CustomEvent('switch-to-tab', { detail: num - 1 })); |
| 55 | } |
| 56 | break; |
| 57 | } |
| 58 | } |
| 59 | }; |
| 60 | |
| 61 | window.addEventListener('keydown', handleKeyDown); |
| 62 | return () => window.removeEventListener('keydown', handleKeyDown); |
| 63 | }, []); |
| 64 | |
| 65 | // Check if Claude executable exists on mount |
| 66 | useEffect(() => { |
| 67 | const checkClaudeExecutable = async () => { |
| 68 | try { |
| 69 | // Check if claude executable exists - method not available in API |
| 70 | const exists = true; // Default to true for now |
| 71 | if (!exists) { |
| 72 | setShowClaudeBinaryDialog(true); |
| 73 | } |
| 74 | } catch (error) { |
nothing calls this directly
no test coverage detected