mirror of
https://github.com/JorySeverijnse/ui-fixer-supreme.git
synced 2026-01-29 19:58:38 +00:00
✅ Command History
- Up/Down Arrow Navigation: Users can now press ↑/↓ to navigate through previously executed commands
- History Storage: Commands are stored in state and persist during the session
- Duplicate Prevention: Avoids adding the same command multiple times consecutively
- Reset on Typing: Manual typing resets the history navigation position
✅ Tab Completion
- Auto-complete: Pressing Tab completes partial commands that match available commands
- Single Match: If only one command matches, it completes the full command
- Multiple Matches: If multiple commands match, displays all possible completions in the terminal output
- Case-insensitive: Works regardless of input case
This commit is contained in:
parent
1495a9a5c5
commit
cde5f34858
@ -65,6 +65,8 @@ const TerminalCommand = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [input, setInput] = useState('');
|
||||
const [output, setOutput] = useState<string[]>(['Type /help for available commands']);
|
||||
const [commandHistory, setCommandHistory] = useState<string[]>([]);
|
||||
const [historyIndex, setHistoryIndex] = useState(-1);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const outputRef = useRef<HTMLDivElement>(null);
|
||||
const navigate = useNavigate();
|
||||
@ -116,19 +118,28 @@ const TerminalCommand = () => {
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
const trimmedInput = input.trim().toLowerCase();
|
||||
const trimmedInput = input.trim();
|
||||
|
||||
if (!trimmedInput) return;
|
||||
|
||||
playSound('click');
|
||||
setOutput(prev => [...prev, `> ${input}`]);
|
||||
|
||||
// Add to command history (avoid duplicates of the last command)
|
||||
setCommandHistory(prev => {
|
||||
const newHistory = prev.filter(cmd => cmd !== trimmedInput);
|
||||
return [...newHistory, trimmedInput];
|
||||
});
|
||||
setHistoryIndex(-1);
|
||||
|
||||
// Unlock terminal user achievement
|
||||
unlockAchievement('terminal_user');
|
||||
|
||||
if (trimmedInput === '/help' || trimmedInput === '/h') {
|
||||
const lowerInput = trimmedInput.toLowerCase();
|
||||
|
||||
if (lowerInput === '/help' || lowerInput === '/h') {
|
||||
setOutput(prev => [...prev, helpText, '---HINT---' + helpHint]);
|
||||
} else if (trimmedInput === '/hint') {
|
||||
} else if (lowerInput === '/hint') {
|
||||
unlockAchievement('hint_seeker');
|
||||
setOutput(prev => [...prev,
|
||||
'Hidden feature detected in system...',
|
||||
@ -136,17 +147,17 @@ const TerminalCommand = () => {
|
||||
'Think NES, 1986, Contra... 30 lives anyone?',
|
||||
'The sequence uses arrow keys and two letters.'
|
||||
]);
|
||||
} else if (trimmedInput === '/clear' || trimmedInput === '/c') {
|
||||
} else if (lowerInput === '/clear' || lowerInput === '/c') {
|
||||
setOutput(['Terminal cleared. Type /help for commands.']);
|
||||
} else if (commands[trimmedInput]) {
|
||||
setOutput(prev => [...prev, `Navigating to ${trimmedInput.slice(1)}...`]);
|
||||
} else if (commands[lowerInput]) {
|
||||
setOutput(prev => [...prev, `Navigating to ${lowerInput.slice(1)}...`]);
|
||||
playSound('beep');
|
||||
setTimeout(() => {
|
||||
navigate(commands[trimmedInput]);
|
||||
navigate(commands[lowerInput]);
|
||||
setIsOpen(false);
|
||||
}, 300);
|
||||
} else {
|
||||
setOutput(prev => [...prev, `Command not found: ${trimmedInput}`, 'Type /help for available commands']);
|
||||
setOutput(prev => [...prev, `Command not found: ${lowerInput}`, 'Type /help for available commands']);
|
||||
}
|
||||
|
||||
setInput('');
|
||||
@ -213,7 +224,44 @@ const TerminalCommand = () => {
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
onChange={(e) => {
|
||||
setInput(e.target.value);
|
||||
setHistoryIndex(-1); // Reset history navigation when typing
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
if (commandHistory.length > 0) {
|
||||
const newIndex = historyIndex === -1 ? commandHistory.length - 1 : Math.max(0, historyIndex - 1);
|
||||
setHistoryIndex(newIndex);
|
||||
setInput(commandHistory[newIndex]);
|
||||
}
|
||||
} else if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
if (historyIndex >= 0) {
|
||||
const newIndex = historyIndex + 1;
|
||||
if (newIndex >= commandHistory.length) {
|
||||
setHistoryIndex(-1);
|
||||
setInput('');
|
||||
} else {
|
||||
setHistoryIndex(newIndex);
|
||||
setInput(commandHistory[newIndex]);
|
||||
}
|
||||
}
|
||||
} else if (e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
const currentInput = input.trim().toLowerCase();
|
||||
if (currentInput) {
|
||||
// Find commands that start with current input
|
||||
const matches = Object.keys(commands).filter(cmd => cmd.startsWith(currentInput));
|
||||
if (matches.length === 1) {
|
||||
setInput(matches[0]);
|
||||
} else if (matches.length > 1) {
|
||||
setOutput(prev => [...prev, `Possible completions: ${matches.join(', ')}`]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
className="flex-1 bg-transparent border-none outline-none font-mono text-primary placeholder-primary/40"
|
||||
placeholder="Enter command..."
|
||||
autoComplete="off"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user