mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-19 04:35:46 +01:00
TERMINAL: Fix inconsistent / janky scrolling behavior (#1063)
This commit is contained in:
parent
cf45981cd2
commit
0ded11af53
@ -12,9 +12,6 @@ import { longestCommonStart } from "../../utils/StringHelperFunctions";
|
|||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) =>
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
textfield: {
|
|
||||||
margin: theme.spacing(0),
|
|
||||||
},
|
|
||||||
input: {
|
input: {
|
||||||
backgroundColor: theme.colors.backgroundprimary,
|
backgroundColor: theme.colors.backgroundprimary,
|
||||||
},
|
},
|
||||||
@ -24,14 +21,10 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
preformatted: {
|
preformatted: {
|
||||||
margin: theme.spacing(0),
|
margin: theme.spacing(0),
|
||||||
},
|
},
|
||||||
list: {
|
|
||||||
padding: theme.spacing(0),
|
|
||||||
height: "100%",
|
|
||||||
},
|
|
||||||
absolute: {
|
absolute: {
|
||||||
margin: theme.spacing(0),
|
margin: theme.spacing(0),
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
bottom: "5px",
|
bottom: "12px",
|
||||||
opacity: "0.75",
|
opacity: "0.75",
|
||||||
maxWidth: "100%",
|
maxWidth: "100%",
|
||||||
whiteSpace: "pre",
|
whiteSpace: "pre",
|
||||||
@ -419,7 +412,7 @@ export function TerminalInput(): React.ReactElement {
|
|||||||
disabled={Terminal.action !== null}
|
disabled={Terminal.action !== null}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
value={value}
|
value={value}
|
||||||
classes={{ root: classes.textfield }}
|
classes={{ root: classes.preformatted }}
|
||||||
onChange={handleValueChange}
|
onChange={handleValueChange}
|
||||||
inputRef={terminalInput}
|
inputRef={terminalInput}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import Typography from "@mui/material/Typography";
|
import { Link as MuiLink, Typography } from "@mui/material";
|
||||||
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 { Theme } from "@mui/material/styles";
|
||||||
import makeStyles from "@mui/styles/makeStyles";
|
import makeStyles from "@mui/styles/makeStyles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import Box from "@mui/material/Box";
|
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
|
||||||
import { Output, Link, RawOutput } from "../OutputTypes";
|
import { Output, Link, RawOutput } from "../OutputTypes";
|
||||||
@ -22,8 +18,16 @@ import { TerminalActionTimer } from "./TerminalActionTimer";
|
|||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) =>
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
nopadding: {
|
container: {
|
||||||
padding: theme.spacing(0),
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
height: "calc(100vh - 16px)",
|
||||||
|
},
|
||||||
|
entries: {
|
||||||
|
padding: 0,
|
||||||
|
overflow: "scroll",
|
||||||
|
flex: "0 1 auto",
|
||||||
|
margin: "auto 0 0",
|
||||||
},
|
},
|
||||||
preformatted: {
|
preformatted: {
|
||||||
whiteSpace: "pre-wrap",
|
whiteSpace: "pre-wrap",
|
||||||
@ -31,16 +35,11 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
margin: theme.spacing(0),
|
margin: theme.spacing(0),
|
||||||
width: "100%",
|
width: "100%",
|
||||||
},
|
},
|
||||||
list: {
|
|
||||||
padding: theme.spacing(0),
|
|
||||||
height: "100%",
|
|
||||||
width: "100%",
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export function TerminalRoot(): React.ReactElement {
|
export function TerminalRoot(): React.ReactElement {
|
||||||
const scrollHook = useRef<HTMLDivElement>(null);
|
const scrollHook = useRef<HTMLUListElement>(null);
|
||||||
const rerender = useRerender();
|
const rerender = useRerender();
|
||||||
const [key, setKey] = useState(0);
|
const [key, setKey] = useState(0);
|
||||||
|
|
||||||
@ -66,7 +65,7 @@ export function TerminalRoot(): React.ReactElement {
|
|||||||
function doScroll(): number | undefined {
|
function doScroll(): number | undefined {
|
||||||
const hook = scrollHook.current;
|
const hook = scrollHook.current;
|
||||||
if (hook !== null) {
|
if (hook !== null) {
|
||||||
return window.setTimeout(() => hook.scrollIntoView(true), 50);
|
return window.setTimeout(() => (hook.scrollTop = hook.scrollHeight), 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,39 +84,34 @@ export function TerminalRoot(): React.ReactElement {
|
|||||||
|
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={classes.container}>
|
||||||
<Box width="100%" minHeight="100vh" display={"flex"} alignItems={"flex-end"}>
|
<ul key={key} id="terminal" className={classes.entries} ref={scrollHook}>
|
||||||
<List key={key} id="terminal" classes={{ root: classes.list }}>
|
{Terminal.outputHistory.map((item, i) => (
|
||||||
{Terminal.outputHistory.map((item, i) => (
|
<li key={i}>
|
||||||
<ListItem key={i} classes={{ root: classes.nopadding }}>
|
{item instanceof Output && <ANSIITypography text={item.text} color={item.color} />}
|
||||||
{item instanceof Output && <ANSIITypography text={item.text} color={item.color} />}
|
{item instanceof RawOutput && (
|
||||||
{item instanceof RawOutput && (
|
<Typography classes={{ root: classes.preformatted }} paragraph={false}>
|
||||||
<Typography classes={{ root: classes.preformatted }} paragraph={false}>
|
{item.raw}
|
||||||
{item.raw}
|
</Typography>
|
||||||
</Typography>
|
)}
|
||||||
)}
|
{item instanceof Link && (
|
||||||
{item instanceof Link && (
|
<Typography classes={{ root: classes.preformatted }}>
|
||||||
<Typography classes={{ root: classes.preformatted }}>
|
{item.dashes}
|
||||||
{item.dashes}
|
<MuiLink onClick={() => Terminal.connectToServer(item.hostname)}>{item.hostname}</MuiLink>
|
||||||
<MuiLink onClick={() => Terminal.connectToServer(item.hostname)}>{item.hostname}</MuiLink>
|
</Typography>
|
||||||
</Typography>
|
)}
|
||||||
)}
|
</li>
|
||||||
</ListItem>
|
))}
|
||||||
))}
|
|
||||||
|
|
||||||
{Terminal.action !== null && (
|
{Terminal.action !== null && (
|
||||||
<ListItem classes={{ root: classes.nopadding }}>
|
<li>
|
||||||
<TerminalActionTimer />{" "}
|
<TerminalActionTimer />{" "}
|
||||||
</ListItem>
|
</li>
|
||||||
)}
|
)}
|
||||||
</List>
|
</ul>
|
||||||
<div ref={scrollHook}></div>
|
<TerminalInput />
|
||||||
</Box>
|
|
||||||
<Box position="sticky" bottom={0} width="100%" px={0}>
|
|
||||||
<TerminalInput />
|
|
||||||
</Box>
|
|
||||||
<BitFlumeModal />
|
<BitFlumeModal />
|
||||||
<CodingContractModal />
|
<CodingContractModal />
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user