import { IS_BROWSER } from "$fresh/runtime.ts"; import { useEffect, useRef, useState } from "preact/hooks"; import { JSX } from "preact/jsx-runtime"; import { Sockpuppet } from "puppet/client"; export function Terminal(props: { channelId: string }) { const puppet = useRef(new Sockpuppet("ws://sockpuppet.cyborggrizzly.com")); const [lines, setLines] = useState([]); const divRef = useRef(null); const storeKey = "commandHistory"; const [commandHistory, setCommandHistory] = useState( JSON.parse(localStorage.getItem(storeKey) || "[]"), ); const [historyIndex, setHistoryIndex] = useState(commandHistory.length); const [command, setCommand] = useState(""); const changeHistoryIndex = (by: number) => setHistoryIndex((i) => i + by); useEffect(() => { if (!IS_BROWSER) return; puppet.current.joinChannel(props.channelId, (line) => { setLines((l) => [...l, line]); }); setTimeout(() => { const channel = puppet.current.getChannel(props.channelId) // console.log(channel) channel?.send("log"); }, 200); document.addEventListener("keyup", (e) => { switch (e.key) { case "Up": case "ArrowUp": changeHistoryIndex(-1); break; case "Down": case "ArrowDown": changeHistoryIndex(1); break; } }); }, []); useEffect(() => { if (divRef.current) { divRef.current.scrollTop = divRef.current.scrollHeight; } }, [lines]); const sendCommand = (e: Event) => { e.preventDefault(); puppet.current.getChannel(props.channelId)?.send( historyIndex === commandHistory.length ? command : commandHistory[historyIndex], ); setCommandHistory((c) => [...c, command]); setHistoryIndex(commandHistory.length + 1); setCommand(""); }; const handleCommandUpdate = ( e: JSX.TargetedEvent, ) => { const value = e.currentTarget.value; if (historyIndex !== commandHistory.length) { setHistoryIndex(commandHistory.length); } setCommand(value || ""); }; useEffect(() => { localStorage.setItem( storeKey, JSON.stringify(commandHistory.slice(0, 100)), ); }, [commandHistory]); return (
{lines.map((l) =>
{l}
)}
); }