import React, { useState, useEffect, useRef } from "react"; import Typography from "@mui/material/Typography"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import { Link as MuiLink } from "@mui/material"; import { Theme } from "@mui/material/styles"; import makeStyles from "@mui/styles/makeStyles"; import createStyles from "@mui/styles/createStyles"; import Box from "@mui/material/Box"; import { Output, Link, RawOutput } from "../ITerminal"; import { Terminal } from "../../Terminal"; import { TerminalInput } from "./TerminalInput"; import { TerminalEvents, TerminalClearEvents } from "../TerminalEvents"; import { BitFlumeModal } from "../../BitNode/ui/BitFlumeModal"; import { CodingContractModal } from "../../ui/React/CodingContractModal"; import _ from "lodash"; import { ANSIITypography } from "../../ui/React/ANSIITypography"; function ActionTimer(): React.ReactElement { return ( {Terminal.getProgressText()} ); } const useStyles = makeStyles((theme: Theme) => createStyles({ nopadding: { padding: theme.spacing(0), }, preformatted: { whiteSpace: "pre-wrap", overflowWrap: "anywhere", margin: theme.spacing(0), }, list: { padding: theme.spacing(0), height: "100%", }, }), ); export function TerminalRoot(): React.ReactElement { const scrollHook = useRef(null); const setRerender = useState(0)[1]; const [key, setKey] = useState(0); function rerender(): void { setRerender((old) => old + 1); } function clear(): void { setKey((key) => key + 1); } useEffect(() => { const debounced = _.debounce(async () => rerender(), 25, { maxWait: 50 }); const unsubscribe = TerminalEvents.subscribe(debounced); return () => { debounced.cancel(); unsubscribe(); }; }, []); useEffect(() => { const debounced = _.debounce(async () => clear(), 25, { maxWait: 50 }); const unsubscribe = TerminalClearEvents.subscribe(debounced); return () => { debounced.cancel(); unsubscribe(); }; }, []); function doScroll(): number | undefined { const hook = scrollHook.current; if (hook !== null) { return window.setTimeout(() => hook.scrollIntoView(true), 50); } } doScroll(); useEffect(() => { let scrollId: number; const id = setTimeout(() => { scrollId = doScroll() ?? 0; }, 50); return () => { clearTimeout(id); clearTimeout(scrollId); }; }, []); const classes = useStyles(); return ( <> {Terminal.outputHistory.map((item, i) => ( {item instanceof Output && } {item instanceof RawOutput && ( {item.raw} )} {item instanceof Link && ( <> {item.dashes}>  Terminal.connectToServer(item.hostname)} > {item.hostname} )} ))} {Terminal.action !== null && ( {" "} )}
); }