diff --git a/doc/source/netscript/netscriptjs.rst b/doc/source/netscript/netscriptjs.rst index 00927865e..b018d3041 100644 --- a/doc/source/netscript/netscriptjs.rst +++ b/doc/source/netscript/netscriptjs.rst @@ -117,30 +117,6 @@ that are loaded. Examples -------- -**DOM Manipulation (tprintColored.ns)** - -Directly alter the game's terminal and print colored text:: - - export function tprintColored(txt, color) { - let terminalInput = document.getElementById("terminal-input"); - let rowElement = document.createElement("tr"); - let cellElement = document.createElement("td"); - - rowElement.classList.add("posted"); - cellElement.classList.add("terminal-line"); - cellElement.style.color = color; - cellElement.innerText = txt; - - rowElement.appendChild(cellElement); - terminalInput.before(rowElement); - } - - export async function main(ns) { - tprintColored("Red Text!", "red"); - tprintColored("Blue Text!", "blue"); - tprintColored("Use Hex Codes!", "#3087E3"); - } - **Script Scheduler (scriptScheduler.ns)** This script shows some of the new functionality that is available in NetscriptJS, diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts index e57097aea..e16cc8300 100644 --- a/src/Terminal/Terminal.ts +++ b/src/Terminal/Terminal.ts @@ -5,7 +5,7 @@ import { HacknetServer } from "../Hacknet/HacknetServer"; import { BaseServer } from "../Server/BaseServer"; import { Programs } from "../Programs/Programs"; import { CodingContractResult } from "../CodingContracts"; -import { TerminalEvents } from "./TerminalEvents"; +import { TerminalEvents, TerminalClearEvents } from "./TerminalEvents"; import { TextFile } from "../TextFile"; import { Script } from "../Script/Script"; @@ -480,6 +480,7 @@ export class Terminal implements ITerminal { // TODO: remove this once we figure out the height issue. this.outputHistory = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")]; TerminalEvents.emit(); + TerminalClearEvents.emit(); } prestige(): void { diff --git a/src/Terminal/TerminalEvents.ts b/src/Terminal/TerminalEvents.ts index 795bbbdb2..94c7f9df8 100644 --- a/src/Terminal/TerminalEvents.ts +++ b/src/Terminal/TerminalEvents.ts @@ -1,2 +1,3 @@ import { EventEmitter } from "../utils/EventEmitter"; export const TerminalEvents = new EventEmitter<[]>(); +export const TerminalClearEvents = new EventEmitter<[]>(); diff --git a/src/Terminal/ui/TerminalRoot.tsx b/src/Terminal/ui/TerminalRoot.tsx index 5a09a6b19..5fa74228a 100644 --- a/src/Terminal/ui/TerminalRoot.tsx +++ b/src/Terminal/ui/TerminalRoot.tsx @@ -11,7 +11,7 @@ import { ITerminal, Output, Link } from "../ITerminal"; import { IRouter } from "../../ui/Router"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { TerminalInput } from "./TerminalInput"; -import { TerminalEvents } from "../TerminalEvents"; +import { TerminalEvents, TerminalClearEvents } from "../TerminalEvents"; interface IActionTimerProps { terminal: ITerminal; @@ -51,13 +51,17 @@ interface IProps { export function TerminalRoot({ terminal, router, player }: IProps): React.ReactElement { const scrollHook = useRef(null); const setRerender = useState(0)[1]; + const [key, setKey] = useState(0); function rerender(): void { setRerender((old) => old + 1); } - useEffect(() => { - return TerminalEvents.subscribe(rerender); - }, []); + function clear(): void { + setKey((key) => key + 1); + } + + useEffect(() => TerminalEvents.subscribe(rerender), []); + useEffect(() => TerminalClearEvents.subscribe(clear), []); function doScroll(): void { const hook = scrollHook.current; @@ -76,7 +80,7 @@ export function TerminalRoot({ terminal, router, player }: IProps): React.ReactE return ( <> - + {terminal.outputHistory.map((item, i) => { if (item instanceof Output) return ( diff --git a/src/ui/ActiveScripts/ActiveScriptsRoot.tsx b/src/ui/ActiveScripts/ActiveScriptsRoot.tsx index d4a93c3a1..3433329d0 100644 --- a/src/ui/ActiveScripts/ActiveScriptsRoot.tsx +++ b/src/ui/ActiveScripts/ActiveScriptsRoot.tsx @@ -22,8 +22,8 @@ export function ActiveScriptsRoot(props: IProps): React.ReactElement { } useEffect(() => { - const id = setInterval(rerender, 20); - return () => clearInterval(id); + // const id = setInterval(rerender, 20); + // return () => clearInterval(id); }, []); return ( diff --git a/src/ui/ActiveScripts/ServerAccordionContent.tsx b/src/ui/ActiveScripts/ServerAccordionContent.tsx index 8deb63551..e8aef48c1 100644 --- a/src/ui/ActiveScripts/ServerAccordionContent.tsx +++ b/src/ui/ActiveScripts/ServerAccordionContent.tsx @@ -21,10 +21,17 @@ export function ServerAccordionContent(props: IProps): React.ReactElement { setPage(0); }; + let safePage = page; + while (safePage * rowsPerPage + 1 > props.workerScripts.length) { + safePage--; + } + + if (safePage != page) setPage(safePage); + return ( <> - {props.workerScripts.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((ws) => ( + {props.workerScripts.slice(safePage * rowsPerPage, safePage * rowsPerPage + rowsPerPage).map((ws) => ( ))} @@ -33,7 +40,7 @@ export function ServerAccordionContent(props: IProps): React.ReactElement { component="div" count={props.workerScripts.length} rowsPerPage={rowsPerPage} - page={page} + page={safePage} onPageChange={handleChangePage} onRowsPerPageChange={handleChangeRowsPerPage} ActionsComponent={TablePaginationActionsAll} diff --git a/src/ui/ActiveScripts/ServerAccordions.tsx b/src/ui/ActiveScripts/ServerAccordions.tsx index c8dd3cf0b..917266a88 100644 --- a/src/ui/ActiveScripts/ServerAccordions.tsx +++ b/src/ui/ActiveScripts/ServerAccordions.tsx @@ -35,13 +35,6 @@ export function ServerAccordions(props: IProps): React.ReactElement { const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(10); const setRerender = useState(false)[1]; - function rerender(): void { - setRerender((old) => !old); - } - - useEffect(() => { - return WorkerScriptStartStopEventEmitter.subscribe(rerender); - }, []); const handleChangePage = (event: unknown, newPage: number): void => { setPage(newPage); @@ -79,6 +72,19 @@ export function ServerAccordions(props: IProps): React.ReactElement { const filtered = Object.values(serverToScriptMap).filter((data) => data && data.server.hostname.includes(filter)); + function rerender(): void { + setRerender((old) => !old); + + let safePage = page; + while (safePage * rowsPerPage + 1 >= filtered.length) { + safePage--; + } + + if (safePage != page) setPage(safePage); + } + + useEffect(() => WorkerScriptStartStopEventEmitter.subscribe(rerender)); + return ( <>