import React, { useState, useRef, useMemo, useEffect } from 'react'; import type { CommandLineProps } from '../types/ui.types'; import { getCommandRegistry, type CommandDefinition } from '../services/commandRegistry'; import { useUIMode } from '../services/uiModeService'; const defaultHistory = [ { prefix: '·' as const, text: 'Bereit · Werkzeug: Auswahl · 110 Objekte · 5 Ebenen', type: 'info' as const }, { prefix: '·' as const, text: 'Auto-Save aktiv · letzte Speicherung vor 3 Sekunden', type: 'info' as const }, { prefix: '›' as const, text: 'hallo', type: 'command' as const }, { prefix: '·' as const, text: 'Hallo! Ich bin der KI Copilot. Tippe KI oder drücke Strg+K für Hilfe.', type: 'info' as const }, { prefix: '›' as const, text: 'BESTUHLUNG 5,22', type: 'command' as const }, { prefix: '·' as const, text: '110 Stühle angelegt auf Ebene "Bestuhlung" ✓', type: 'info' as const }, ]; const categoryColors: Record = { draw: '#22c55e', modify: '#f97316', view: '#06b6d4', meta: '#a855f7', special: '#ec4899', }; const CommandLine: React.FC = ({ history, onCommand }) => { const uiMode = useUIMode(); if (uiMode === 'simple') return null; const [input, setInput] = useState(''); const [selectedSuggestion, setSelectedSuggestion] = useState(0); const [commandHistory, setCommandHistory] = useState([]); const [historyIndex, setHistoryIndex] = useState(-1); const [showSuggestions, setShowSuggestions] = useState(false); const inputRef = useRef(null); const historyRef = useRef(null); const entries = history.length > 0 ? history : defaultHistory; const suggestions = useMemo(() => { if (!input.trim()) return []; const registry = getCommandRegistry(); return registry.autocomplete(input.trim()); }, [input]); useEffect(() => { setSelectedSuggestion(0); }, [suggestions]); useEffect(() => { if (historyRef.current) { historyRef.current.scrollTop = historyRef.current.scrollHeight; } }, [entries]); const executeCommand = (cmd: string) => { const trimmed = cmd.trim(); if (!trimmed) return; onCommand(trimmed); setCommandHistory((prev) => [...prev, trimmed]); setInput(''); setShowSuggestions(false); setHistoryIndex(-1); }; const handleKeyDown = (e: React.KeyboardEvent) => { const navKeys = ['ArrowUp', 'ArrowDown', 'Tab', 'Enter', 'Escape']; if (showSuggestions && suggestions.length > 0 && navKeys.includes(e.key)) { if (e.key === 'ArrowDown') { e.preventDefault(); setSelectedSuggestion((prev) => Math.min(prev + 1, suggestions.length - 1)); return; } if (e.key === 'ArrowUp') { e.preventDefault(); setSelectedSuggestion((prev) => Math.max(prev - 1, 0)); return; } if (e.key === 'Tab') { e.preventDefault(); const suggestion = suggestions[selectedSuggestion] || suggestions[0]; if (suggestion) { setInput(suggestion.name); setShowSuggestions(false); } return; } if (e.key === 'Enter') { e.preventDefault(); const suggestion = suggestions[selectedSuggestion]; if (suggestion) { executeCommand(suggestion.name); } else { executeCommand(input); } return; } if (e.key === 'Escape') { e.preventDefault(); setShowSuggestions(false); return; } } if (!showSuggestions || suggestions.length === 0) { if (e.key === 'Enter' && input.trim()) { executeCommand(input); return; } if (e.key === 'ArrowUp') { e.preventDefault(); if (commandHistory.length === 0) return; const newIdx = historyIndex === -1 ? commandHistory.length - 1 : Math.max(historyIndex - 1, 0); setHistoryIndex(newIdx); setInput(commandHistory[newIdx]); return; } if (e.key === 'ArrowDown') { e.preventDefault(); if (historyIndex === -1) return; const newIdx = historyIndex + 1; if (newIdx >= commandHistory.length) { setHistoryIndex(-1); setInput(''); } else { setHistoryIndex(newIdx); setInput(commandHistory[newIdx]); } return; } if (e.key === 'Escape') { e.preventDefault(); setInput(''); setShowSuggestions(false); setHistoryIndex(-1); return; } } }; const handleChange = (e: React.ChangeEvent) => { setInput(e.target.value); setShowSuggestions(true); setHistoryIndex(-1); }; const handleBlur = () => { setTimeout(() => setShowSuggestions(false), 150); }; const handleFocus = () => { if (input.trim()) setShowSuggestions(true); }; const handleSuggestionClick = (cmd: CommandDefinition) => { executeCommand(cmd.name); }; return (
{entries.map((entry, i) => (
{entry.prefix} {entry.text}
))}
{showSuggestions && suggestions.length > 0 && (
{suggestions.map((cmd, i) => (
{ e.preventDefault(); handleSuggestionClick(cmd); }} onMouseEnter={() => setSelectedSuggestion(i)} > {cmd.category} {cmd.name} {cmd.aliases.length > 0 && ( ({cmd.aliases.join(', ')}) )} {cmd.description}
))}
)}
); }; export default CommandLine;