From fd3ff76976d5fc0998a1dc25855e10704ef2f01d Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 16 Aug 2022 02:32:25 -0400 Subject: [PATCH 1/6] Improve ScriptEditor responsiveness --- src/ScriptEditor/ui/ScriptEditorRoot.tsx | 22 +---------- src/ui/GameRoot.tsx | 2 +- src/ui/LoadingScreen.tsx | 49 ++++++++---------------- 3 files changed, 18 insertions(+), 55 deletions(-) diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index fa4db9370..a0ee8de96 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -142,25 +142,6 @@ export function Root(props: IProps): React.ReactElement { if (currentScript === undefined) currentScript = null; } - const [dimensions, setDimensions] = useState({ - height: window.innerHeight, - width: window.innerWidth, - }); - useEffect(() => { - const debouncedHandleResize = debounce(function handleResize() { - setDimensions({ - height: window.innerHeight, - width: window.innerWidth, - }); - }, 250); - - window.addEventListener("resize", debouncedHandleResize); - - return () => { - window.removeEventListener("resize", debouncedHandleResize); - }; - }, []); - useEffect(() => { if (currentScript !== null) { updateRAM(currentScript.code); @@ -815,7 +796,6 @@ export function Root(props: IProps): React.ReactElement { // 5px padding for top of editor // 44px bottom tool bar + 16px margin // + vim bar 34px - const editorHeight = dimensions.height - (130 + (options.vim ? 34 : 0)); const tabsMaxWidth = 1640; const tabMargin = 5; const tabMaxWidth = filteredOpenScripts.length ? tabsMaxWidth / filteredOpenScripts.length - tabMargin : 0; @@ -951,7 +931,7 @@ export function Root(props: IProps): React.ReactElement { beforeMount={beforeMount} onMount={onMount} loading={Loading script editor!} - height={`${editorHeight}px`} + height={`calc(100vh - ${130 + (options.vim ? 34 : 0)}px)`} defaultLanguage="javascript" defaultValue={""} onChange={updateCode} diff --git a/src/ui/GameRoot.tsx b/src/ui/GameRoot.tsx index 281ef5006..3569b2ea7 100644 --- a/src/ui/GameRoot.tsx +++ b/src/ui/GameRoot.tsx @@ -104,10 +104,10 @@ const useStyles = makeStyles((theme: Theme) => "scrollbar-width": "none" /* for Firefox */, margin: theme.spacing(0), flexGrow: 1, - display: "block", padding: "8px", minHeight: "100vh", boxSizing: "border-box", + width: "1px", }, }), ); diff --git a/src/ui/LoadingScreen.tsx b/src/ui/LoadingScreen.tsx index 0bdd57090..9390360a1 100644 --- a/src/ui/LoadingScreen.tsx +++ b/src/ui/LoadingScreen.tsx @@ -2,10 +2,6 @@ import React, { useState, useEffect } from "react"; import CircularProgress from "@mui/material/CircularProgress"; import Typography from "@mui/material/Typography"; import Grid from "@mui/material/Grid"; -import Box from "@mui/material/Box"; -import { Theme } from "@mui/material/styles"; -import makeStyles from "@mui/styles/makeStyles"; -import createStyles from "@mui/styles/createStyles"; import { Terminal } from "../Terminal"; import { load } from "../db"; @@ -18,16 +14,7 @@ import { ActivateRecoveryMode } from "./React/RecoveryRoot"; import { hash } from "../hash/hash"; import { pushGameReady } from "../Electron"; -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - backgroundColor: theme.colors.backgroundprimary, - }, - }), -); - export function LoadingScreen(): React.ReactElement { - const classes = useStyles(); const [show, setShow] = useState(false); const [loaded, setLoaded] = useState(false); @@ -69,27 +56,23 @@ export function LoadingScreen(): React.ReactElement { doLoad(); }, []); - return ( - - {loaded ? ( - - ) : ( - - - - - - Loading Bitburner {version} - - {show && ( - - - If the game fails to load, consider killing all scripts - - - )} + return loaded ? ( + + ) : ( + + + + + + Loading Bitburner {version} + + {show && ( + + + If the game fails to load, consider killing all scripts + )} - + ); } From fbee07ffd72fe149e5c62a0aee47ad2d755480a9 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 16 Aug 2022 10:41:40 -0400 Subject: [PATCH 2/6] Fix dirty indicator --- src/ScriptEditor/ui/ScriptEditorRoot.tsx | 43 +++++++++++------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index a0ee8de96..013b0c289 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -90,6 +90,7 @@ class OpenScript { hostname: string; lastPosition: monaco.Position; model: ITextModel; + isTxt: boolean; constructor(fileName: string, code: string, hostname: string, lastPosition: monaco.Position, model: ITextModel) { this.fileName = fileName; @@ -97,6 +98,7 @@ class OpenScript { this.hostname = hostname; this.lastPosition = lastPosition; this.model = model; + this.isTxt = fileName.endsWith(".txt"); } } @@ -234,10 +236,7 @@ export function Root(props: IProps): React.ReactElement { // Generates a new model for the script function regenerateModel(script: OpenScript): void { if (monacoRef.current !== null) { - script.model = monacoRef.current.editor.createModel( - script.code, - script.fileName.endsWith(".txt") ? "plaintext" : "javascript", - ); + script.model = monacoRef.current.editor.createModel(script.code, script.isTxt ? "plaintext" : "javascript"); } } @@ -252,7 +251,7 @@ export function Root(props: IProps): React.ReactElement { ); async function updateRAM(newCode: string): Promise { - if (currentScript != null && currentScript.fileName.endsWith(".txt")) { + if (currentScript != null && currentScript.isTxt) { debouncedSetRAM("N/A", [["N/A", ""]]); return; } @@ -405,7 +404,7 @@ export function Root(props: IProps): React.ReactElement { monacoRef.current.editor.createModel(code, filename.endsWith(".txt") ? "plaintext" : "javascript"), ); openScripts.push(newScript); - currentScript = { ...newScript }; + currentScript = newScript; editorRef.current.setModel(newScript.model); updateRAM(newScript.code); } @@ -500,7 +499,7 @@ export function Root(props: IProps): React.ReactElement { server.scripts, ); server.scripts.push(script); - } else if (scriptToSave.fileName.endsWith(".txt")) { + } else if (scriptToSave.isTxt) { for (let i = 0; i < server.textFiles.length; ++i) { if (server.textFiles[i].fn === scriptToSave.fileName) { server.textFiles[i].write(scriptToSave.code); @@ -574,6 +573,7 @@ export function Root(props: IProps): React.ReactElement { server.scripts, ); if (Settings.SaveGameOnFileSave) saveObject.saveGame(); + rerender(); return; } } @@ -588,11 +588,12 @@ export function Root(props: IProps): React.ReactElement { server.scripts, ); server.scripts.push(script); - } else if (currentScript.fileName.endsWith(".txt")) { + } else if (currentScript.isTxt) { for (let i = 0; i < server.textFiles.length; ++i) { if (server.textFiles[i].fn === currentScript.fileName) { server.textFiles[i].write(currentScript.code); if (Settings.SaveGameOnFileSave) saveObject.saveGame(); + rerender(); return; } } @@ -604,6 +605,7 @@ export function Root(props: IProps): React.ReactElement { } if (Settings.SaveGameOnFileSave) saveObject.saveGame(); + rerender(); } function reorder(list: Array, startIndex: number, endIndex: number): OpenScript[] { @@ -763,21 +765,20 @@ export function Root(props: IProps): React.ReactElement { function dirty(index: number): string { const openScript = openScripts[index]; - const serverScriptCode = getServerCode(index); - if (serverScriptCode === null) return " *"; - - // The server code is stored with its starting & trailing whitespace removed - const openScriptFormatted = Script.formatCode(openScript.code); - return serverScriptCode !== openScriptFormatted ? " *" : ""; + const serverData = getServerCode(index); + if (serverData === null) return " *"; + // For scripts, server code is stored with its starting & trailing whitespace removed + const code = openScript.isTxt ? openScript.code : Script.formatCode(openScript.code); + return serverData !== code ? " *" : ""; } - function getServerCode(index: number): string | null { const openScript = openScripts[index]; const server = GetServer(openScript.hostname); if (server === null) throw new Error(`Server '${openScript.hostname}' should not be null, but it is.`); - - const serverScript = server.scripts.find((s) => s.filename === openScript.fileName); - return serverScript?.code ?? null; + const data = openScript.isTxt + ? server.textFiles.find((t) => t.filename === openScript.fileName)?.text + : server.scripts.find((s) => s.filename === openScript.fileName)?.code; + return data ?? null; } function handleFilterChange(event: React.ChangeEvent): void { setFilter(event.target.value); @@ -790,12 +791,6 @@ export function Root(props: IProps): React.ReactElement { (script) => script.hostname.includes(filter) || script.fileName.includes(filter), ); - // Toolbars are roughly 112px: - // 8px body margin top - // 38.5px filename tabs - // 5px padding for top of editor - // 44px bottom tool bar + 16px margin - // + vim bar 34px const tabsMaxWidth = 1640; const tabMargin = 5; const tabMaxWidth = filteredOpenScripts.length ? tabsMaxWidth / filteredOpenScripts.length - tabMargin : 0; From 8cbb8aac2eefc9508fc554a1bbac4655384b95b1 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 16 Aug 2022 12:24:50 -0400 Subject: [PATCH 3/6] Remove unnecessary assignments & spreads --- src/ScriptEditor/ui/ScriptEditorRoot.tsx | 88 +++++++----------------- 1 file changed, 25 insertions(+), 63 deletions(-) diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index 013b0c289..4effb2cec 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -451,18 +451,8 @@ export function Root(props: IProps): React.ReactElement { const newPos = editorRef.current.getPosition(); if (newPos === null) return; if (currentScript !== null) { - currentScript = { ...currentScript, code: newCode, lastPosition: newPos }; - const curIndex = openScripts.findIndex( - (script) => - currentScript !== null && - script.fileName === currentScript.fileName && - script.hostname === currentScript.hostname, - ); - const newArr = [...openScripts]; - const tempScript = currentScript; - tempScript.code = newCode; - newArr[curIndex] = tempScript; - openScripts = [...newArr]; + currentScript.code = newCode; + currentScript.lastPosition = newPos; } try { infLoop(newCode); @@ -608,24 +598,15 @@ export function Root(props: IProps): React.ReactElement { rerender(); } - function reorder(list: Array, startIndex: number, endIndex: number): OpenScript[] { - const result = Array.from(list); - const [removed] = result.splice(startIndex, 1); - result.splice(endIndex, 0, removed); - - return result; + function reorder(list: OpenScript[], startIndex: number, endIndex: number): void { + const [removed] = list.splice(startIndex, 1); + list.splice(endIndex, 0, removed); } function onDragEnd(result: any): void { // Dropped outside of the list - if (!result.destination) { - result; - return; - } - - const items = reorder(openScripts, result.source.index, result.destination.index); - - openScripts = items; + if (!result.destination) return; + reorder(openScripts, result.source.index, result.destination.index); } function currentTabIndex(): number | undefined { @@ -650,17 +631,17 @@ export function Root(props: IProps): React.ReactElement { } } - currentScript = { ...openScripts[index] }; + currentScript = openScripts[index]; if (editorRef.current !== null && openScripts[index] !== null) { - if (openScripts[index].model === undefined || openScripts[index].model.isDisposed()) { - regenerateModel(openScripts[index]); + if (currentScript.model === undefined || currentScript.model.isDisposed()) { + regenerateModel(currentScript); } - editorRef.current.setModel(openScripts[index].model); + editorRef.current.setModel(currentScript.model); - editorRef.current.setPosition(openScripts[index].lastPosition); - editorRef.current.revealLineInCenter(openScripts[index].lastPosition.lineNumber); - updateRAM(openScripts[index].code); + editorRef.current.setPosition(currentScript.lastPosition); + editorRef.current.revealLineInCenter(currentScript.lastPosition.lineNumber); + updateRAM(currentScript.code); editorRef.current.focus(); } } @@ -668,18 +649,10 @@ export function Root(props: IProps): React.ReactElement { function onTabClose(index: number): void { // See if the script on the server is up to date const closingScript = openScripts[index]; - const savedScriptIndex = openScripts.findIndex( - (script) => script.fileName === closingScript.fileName && script.hostname === closingScript.hostname, - ); - let savedScriptCode = ""; - if (savedScriptIndex !== -1) { - savedScriptCode = openScripts[savedScriptIndex].code; - } - const server = GetServer(closingScript.hostname); - if (server === null) throw new Error(`Server '${closingScript.hostname}' should not be null, but it is.`); + const savedScriptCode = closingScript.code; + const wasCurrentScript = openScripts[index] === currentScript; - const serverScriptIndex = server.scripts.findIndex((script) => script.filename === closingScript.fileName); - if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex].code) { + if (dirty(index)) { PromptEvent.emit({ txt: `Do you want to save changes to ${closingScript.fileName} on ${closingScript.hostname}?`, resolve: (result: boolean | string) => { @@ -693,30 +666,19 @@ export function Root(props: IProps): React.ReactElement { } if (openScripts.length > 1) { - openScripts = openScripts.filter((value, i) => i !== index); - - let indexOffset = -1; - if (openScripts[index + indexOffset] === undefined) { - indexOffset = 1; - if (openScripts[index + indexOffset] === undefined) { - indexOffset = 0; - } - } + openScripts.splice(index, 1); + const indexOffset = openScripts.length === index ? -1 : 0; // Change current script if we closed it - currentScript = openScripts[index + indexOffset]; + currentScript = wasCurrentScript ? openScripts[index + indexOffset] : (currentScript as OpenScript); if (editorRef.current !== null) { - if ( - openScripts[index + indexOffset].model === undefined || - openScripts[index + indexOffset].model === null || - openScripts[index + indexOffset].model.isDisposed() - ) { - regenerateModel(openScripts[index + indexOffset]); + if (currentScript.model.isDisposed() || !currentScript.model) { + regenerateModel(currentScript); } - editorRef.current.setModel(openScripts[index + indexOffset].model); - editorRef.current.setPosition(openScripts[index + indexOffset].lastPosition); - editorRef.current.revealLineInCenter(openScripts[index + indexOffset].lastPosition.lineNumber); + editorRef.current.setModel(currentScript.model); + editorRef.current.setPosition(currentScript.lastPosition); + editorRef.current.revealLineInCenter(currentScript.lastPosition.lineNumber); editorRef.current.focus(); } rerender(); From 57fa1b743ab6ef5846be98ee4bf791febb435fc9 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 16 Aug 2022 15:17:44 -0400 Subject: [PATCH 4/6] const openScripts --- src/ScriptEditor/ui/ScriptEditorRoot.tsx | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index 4effb2cec..47df72880 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -102,7 +102,7 @@ class OpenScript { } } -let openScripts: OpenScript[] = []; +const openScripts: OpenScript[] = []; let currentScript: OpenScript | null = null; // Called every time script editor is opened @@ -136,9 +136,9 @@ export function Root(props: IProps): React.ReactElement { const [ramInfoOpen, setRamInfoOpen] = useState(false); // Prevent Crash if script is open on deleted server - openScripts = openScripts.filter((script) => { - return GetServer(script.hostname) !== null; - }); + for (let i=openScripts.length-1;i>=0;i--){ + GetServer(openScripts[i].hostname) === null && openScripts.splice(i,1); + } if (currentScript && GetServer(currentScript.hostname) === null) { currentScript = openScripts[0]; if (currentScript === undefined) currentScript = null; @@ -665,29 +665,29 @@ export function Root(props: IProps): React.ReactElement { }); } - if (openScripts.length > 1) { - openScripts.splice(index, 1); + openScripts.splice(index, 1); + if (openScripts.length === 0) { + currentScript = null; + props.router.toTerminal(); + return; + } + + // Change current script if we closed it + if(wasCurrentScript){ + //Keep the same index unless we were on the last script const indexOffset = openScripts.length === index ? -1 : 0; - - // Change current script if we closed it - currentScript = wasCurrentScript ? openScripts[index + indexOffset] : (currentScript as OpenScript); + currentScript = openScripts[index + indexOffset]; if (editorRef.current !== null) { if (currentScript.model.isDisposed() || !currentScript.model) { regenerateModel(currentScript); } - editorRef.current.setModel(currentScript.model); editorRef.current.setPosition(currentScript.lastPosition); editorRef.current.revealLineInCenter(currentScript.lastPosition.lineNumber); editorRef.current.focus(); } - rerender(); - } else { - // No more scripts are open - openScripts = []; - currentScript = null; - props.router.toTerminal(); } + rerender(); } function onTabUpdate(index: number): void { From e6f9f9ed751600ab9d5c36ea65d119c383b97864 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 16 Aug 2022 15:19:33 -0400 Subject: [PATCH 5/6] const openScripts (format) --- src/ScriptEditor/ui/ScriptEditorRoot.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index 47df72880..a5c1931dc 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -136,8 +136,8 @@ export function Root(props: IProps): React.ReactElement { const [ramInfoOpen, setRamInfoOpen] = useState(false); // Prevent Crash if script is open on deleted server - for (let i=openScripts.length-1;i>=0;i--){ - GetServer(openScripts[i].hostname) === null && openScripts.splice(i,1); + for (let i = openScripts.length - 1; i >= 0; i--) { + GetServer(openScripts[i].hostname) === null && openScripts.splice(i, 1); } if (currentScript && GetServer(currentScript.hostname) === null) { currentScript = openScripts[0]; @@ -669,11 +669,11 @@ export function Root(props: IProps): React.ReactElement { if (openScripts.length === 0) { currentScript = null; props.router.toTerminal(); - return; + return; } - + // Change current script if we closed it - if(wasCurrentScript){ + if (wasCurrentScript) { //Keep the same index unless we were on the last script const indexOffset = openScripts.length === index ? -1 : 0; currentScript = openScripts[index + indexOffset]; From d4c7edf351114203427770b7aea8467d7db80e53 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 23 Aug 2022 02:37:53 -0400 Subject: [PATCH 6/6] Fix fullscreen pages --- src/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.html b/src/index.html index fb801e99b..a61c6928d 100644 --- a/src/index.html +++ b/src/index.html @@ -76,6 +76,6 @@ -
+