From 360c0fd5798ac533d796bb8fc994a74fe9c879a3 Mon Sep 17 00:00:00 2001 From: Ronnie Date: Wed, 20 Nov 2024 22:04:05 -0500 Subject: [PATCH] Fixed ASCII Art & Added Auto-suggest --- src/components/Terminal.tsx | 75 +++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/src/components/Terminal.tsx b/src/components/Terminal.tsx index 1ae922e..9582cb8 100644 --- a/src/components/Terminal.tsx +++ b/src/components/Terminal.tsx @@ -3,24 +3,30 @@ import { useState, useRef, useEffect } from "react"; import helpCommand from "../app/commands/help"; import socialsCommand from "../app/commands/socials"; -import selfhostedCommand from "../app/commands/selfhosted" +import selfhostedCommand from "../app/commands/selfhosted"; import exitCommand from "../app/commands/exit"; import unknownCommand from "../app/commands/unknown"; -// Dynamically import React Icons with client-side rendering const Terminal: React.FC = () => { const [input, setInput] = useState(""); const [output, setOutput] = useState([]); const [history, setHistory] = useState([]); const [historyIndex, setHistoryIndex] = useState(null); + const [suggestion, setSuggestion] = useState(null); // For live suggestions const terminalEndRef = useRef(null); const inputRef = useRef(null); + const commandsList = ["help", "socials", "exit", "selfhosted"]; + useEffect(() => { + window.scrollTo(0, 0); // Automatically scroll to the top + }, []); + + const handleInput = (e: React.FormEvent) => { e.preventDefault(); - // If the input is empty, add a blank line and return + // If the input is empty, add a blank line if (input.trim() === "") { setOutput((prev) => [ ...prev, @@ -49,10 +55,18 @@ const Terminal: React.FC = () => { setHistory((prev) => [...prev, input]); setHistoryIndex(null); setInput(""); + setSuggestion(null); // Clear suggestion after submission }; - const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Tab") { + e.preventDefault(); // Prevent browser default behavior + if (suggestion) { + setInput(suggestion); + setSuggestion(null); // Clear suggestion after Tab + } + } + if (history.length === 0) return; if (e.key === "ArrowUp") { @@ -84,6 +98,17 @@ const Terminal: React.FC = () => { } }; + const handleInputChange = (value: string) => { + setInput(value); + + // Suggest commands dynamically + const normalizedInput = value.toLowerCase(); + const matchedCommand = commandsList.find((command) => + command.startsWith(normalizedInput) + ); + setSuggestion(matchedCommand || null); + }; + useEffect(() => { terminalEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [output]); @@ -100,24 +125,40 @@ const Terminal: React.FC = () => { ))} -
+ $ - setInput(e.target.value)} - onKeyDown={handleKeyDown} - autoFocus - /> +
+ handleInputChange(e.target.value)} + onKeyDown={handleKeyDown} + autoFocus + /> + {suggestion && input.trim() !== suggestion && ( +
+ {input} + + {suggestion.slice(input.length)} + +
+ )} +
); }; - const MOTD = () => { const socialsOutput = socialsCommand(false); const selfHostedOutput = selfhostedCommand(false); @@ -125,7 +166,9 @@ const MOTD = () => { return ( <> -
+
{` _____ _ _ _ `} {`\n | __ \\ (_|_) | | `} {`\n | |__) |___ _ __ _ __ _ _ ___ __| | _____ __`}