better terminal scrolling

This commit is contained in:
Olivier Gagnon 2021-09-16 20:14:09 -04:00
parent 3fc46c8fc6
commit b6924d6889
3 changed files with 45 additions and 36 deletions

@ -8,9 +8,6 @@
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
flex-grow: 1;
overflow-y: scroll;
height: 100vh;
bottom: 0px;
}
#generic-react-container::-webkit-scrollbar {

@ -77,7 +77,7 @@ export class Terminal implements ITerminal {
commandHistory: string[] = [];
commandHistoryIndex = 0;
outputHistory: (Output | Link)[] = [{ text: `Bitburner v${CONSTANTS.Version}`, color: "primary" }];
outputHistory: (Output | Link)[] = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")];
// True if a Coding Contract prompt is opened
contractOpen = false;
@ -489,6 +489,7 @@ export class Terminal implements ITerminal {
}
clear(): void {
// TODO: remove this once we figure out the height issue.
this.outputHistory = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")];
this.hasChanges = true;
}

@ -1,11 +1,11 @@
import React, { useState, useEffect } from "react";
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 makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import Box from "@mui/material/Box";
import { ITerminal, Output, Link } from "../ITerminal";
import { IEngine } from "../../IEngine";
@ -47,6 +47,7 @@ interface IProps {
}
export function TerminalRoot({ terminal, engine, player }: IProps): React.ReactElement {
const scrollHook = useRef<HTMLDivElement>(null);
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
@ -59,36 +60,46 @@ export function TerminalRoot({ terminal, engine, player }: IProps): React.ReactE
return () => clearInterval(id);
}, []);
const hook = scrollHook.current;
if (hook !== null) {
setTimeout(() => hook.scrollIntoView(true), 10);
}
const classes = useStyles();
return (
<Box position="fixed" bottom="0" width="100%" px={1}>
<List classes={{ root: classes.list }}>
{terminal.outputHistory.map((item, i) => {
if (item instanceof Output)
return (
<ListItem key={i} classes={{ root: classes.nopadding }}>
<Typography classes={{ root: classes.preformatted }} color={item.color} paragraph={false}>
{item.text}
</Typography>
</ListItem>
);
if (item instanceof Link)
return (
<ListItem key={i} classes={{ root: classes.nopadding }}>
<MuiLink
classes={{ root: classes.preformatted }}
color={"secondary"}
paragraph={false}
onClick={() => terminal.connectToServer(player, item.hostname)}
>
&gt;&nbsp;{item.hostname}
</MuiLink>
</ListItem>
);
})}
</List>
{terminal.action !== null && <ActionTimer terminal={terminal} />}
<TerminalInput player={player} engine={engine} terminal={terminal} />
</Box>
<>
<Box width="100%" minHeight="100vh" px={1}>
<List classes={{ root: classes.list }}>
{terminal.outputHistory.map((item, i) => {
if (item instanceof Output)
return (
<ListItem key={i} classes={{ root: classes.nopadding }}>
<Typography classes={{ root: classes.preformatted }} color={item.color} paragraph={false}>
{item.text}
</Typography>
</ListItem>
);
if (item instanceof Link)
return (
<ListItem key={i} classes={{ root: classes.nopadding }}>
<MuiLink
classes={{ root: classes.preformatted }}
color={"secondary"}
paragraph={false}
onClick={() => terminal.connectToServer(player, item.hostname)}
>
&gt;&nbsp;{item.hostname}
</MuiLink>
</ListItem>
);
})}
</List>
{terminal.action !== null && <ActionTimer terminal={terminal} />}
<div ref={scrollHook}></div>
</Box>
<Box position="sticky" bottom={0} width="100%" px={1}>
<TerminalInput player={player} engine={engine} terminal={terminal} />
</Box>
</>
);
}