get loading screen inside GameRoot

This commit is contained in:
Olivier Gagnon 2021-09-19 18:04:12 -04:00
parent 7a2dd16092
commit 9bc20526ff
11 changed files with 92 additions and 4941 deletions

1
src/SaveObject.d.ts vendored

@ -1 +1,2 @@
export declare const saveObject: any; export declare const saveObject: any;
export declare function openImportFileHandler(evt: any): void;

@ -538,4 +538,4 @@ function openImportFileHandler(evt) {
reader.readAsText(file); reader.readAsText(file);
} }
export { saveObject, loadGame }; export { saveObject, loadGame, openImportFileHandler };

File diff suppressed because it is too large Load Diff

@ -43,7 +43,7 @@ import { Reputation } from "./ui/React/Reputation";
import { dialogBoxCreate } from "../utils/DialogBox"; import { dialogBoxCreate } from "../utils/DialogBox";
import { exceptionAlert } from "../utils/helpers/exceptionAlert"; import { exceptionAlert } from "../utils/helpers/exceptionAlert";
import { removeLoadingScreen } from "../utils/uiHelpers/removeLoadingScreen";
import "./Exploits/tampering"; import "./Exploits/tampering";
import "./Exploits/unclickable"; import "./Exploits/unclickable";
@ -375,7 +375,6 @@ const Engine = {
Player.lastUpdate = Engine._lastUpdate; Player.lastUpdate = Engine._lastUpdate;
Engine.start(); // Run main game loop and Scripts loop Engine.start(); // Run main game loop and Scripts loop
removeLoadingScreen();
const timeOfflineString = convertTimeMsToTimeElapsedString(time); const timeOfflineString = convertTimeMsToTimeElapsedString(time);
dialogBoxCreate( dialogBoxCreate(
<> <>
@ -388,7 +387,6 @@ const Engine = {
// No save found, start new game // No save found, start new game
initBitNodeMultipliers(Player); initBitNodeMultipliers(Player);
initSpecialServerIps(); initSpecialServerIps();
Engine.setDisplayElements(); // Sets variables for important DOM elements
Engine.start(); // Run main game loop and Scripts loop Engine.start(); // Run main game loop and Scripts loop
Player.init(); Player.init();
initForeignServers(Player.getHomeComputer()); initForeignServers(Player.getHomeComputer());
@ -400,7 +398,6 @@ const Engine = {
// Start interactive tutorial // Start interactive tutorial
iTutorialStart(); iTutorialStart();
removeLoadingScreen();
} }
ReactDOM.render( ReactDOM.render(
@ -409,6 +406,7 @@ const Engine = {
</Theme>, </Theme>,
document.getElementById("mainmenu-container"), document.getElementById("mainmenu-container"),
); );
Router.toTerminal();
}, },
start: function () { start: function () {

@ -38,7 +38,7 @@
<% } %> <% } %>
</head> </head>
<body> <body>
<div id="entire-game-container" style="visibility: hidden"> <div id="entire-game-container">
<div id="mainmenu-container" style="display: flex; flex-direction: row"> <div id="mainmenu-container" style="display: flex; flex-direction: row">
<!-- Main menu --> <!-- Main menu -->
<div id="sidebar" style=""></div> <div id="sidebar" style=""></div>
@ -51,33 +51,6 @@
</div> </div>
</div> </div>
<input type="file" id="import-game-file-selector" name="file" />
<!-- Loader (Loading screen) -->
<div id="loader" class="loaderoverlay">
<div class="loaderspinner"></div>
<div class="loaderlabel">Loading Bitburner...</div>
<div id="killAllMessageWrapper" class="killAllMessage killAllMessageWrapperHidden">
<script>
setTimeout(function () {
var w = document.getElementById("killAllMessageWrapper");
if (w == null) {
return;
}
w.classList.remove("killAllMessageWrapperHidden");
w.classList.add("killAllMessageWrapperShow");
}, 2000);
</script>
<p>
If the game fails to load, consider
<a href="?noScripts">killing all scripts</a>
</p>
</div>
</div>
<div id="unclickable" style="display: none">Click on this to upgrade your Source-File -1!</div> <div id="unclickable" style="display: none">Click on this to upgrade your Source-File -1!</div>
</body> </body>
<!-- Misc Scripts -->
<script src="src/ThirdParty/raphael.min.js"></script>
</html> </html>

@ -4,7 +4,7 @@ import { IPlayer } from "../PersonObjects/IPlayer";
import { IEngine } from "../IEngine"; import { IEngine } from "../IEngine";
import { ITerminal } from "../Terminal/ITerminal"; import { ITerminal } from "../Terminal/ITerminal";
import { installAugmentations } from "../Augmentation/AugmentationHelpers"; import { installAugmentations } from "../Augmentation/AugmentationHelpers";
import { saveObject } from "../SaveObject"; import { saveObject, openImportFileHandler } from "../SaveObject";
import { onExport } from "../ExportBonus"; import { onExport } from "../ExportBonus";
import { LocationName } from "../Locations/data/LocationNames"; import { LocationName } from "../Locations/data/LocationNames";
import { Location } from "../Locations/Location"; import { Location } from "../Locations/Location";
@ -63,6 +63,7 @@ import { TravelAgencyRoot } from "../Locations/ui/TravelAgencyRoot";
import { StockMarketRoot } from "../StockMarket/ui/StockMarketRoot"; import { StockMarketRoot } from "../StockMarket/ui/StockMarketRoot";
import { BitverseRoot } from "../BitNode/ui/BitverseRoot"; import { BitverseRoot } from "../BitNode/ui/BitverseRoot";
import { CharacterOverview } from "./React/CharacterOverview"; import { CharacterOverview } from "./React/CharacterOverview";
import { LoadingScreen } from "./LoadingScreen";
import { BladeburnerCinematic } from "../Bladeburner/ui/BladeburnerCinematic"; import { BladeburnerCinematic } from "../Bladeburner/ui/BladeburnerCinematic";
import { workerScripts } from "../Netscript/WorkerScripts"; import { workerScripts } from "../Netscript/WorkerScripts";
@ -185,7 +186,7 @@ function determineStartPage(player: IPlayer): Page {
export function GameRoot({ player, engine, terminal }: IProps): React.ReactElement { export function GameRoot({ player, engine, terminal }: IProps): React.ReactElement {
const classes = useStyles(); const classes = useStyles();
const [page, setPage] = useState(determineStartPage(player)); const [page, setPage] = useState(/*determineStartPage(player)*/ Page.Loading);
const setRerender = useState(0)[1]; const setRerender = useState(0)[1];
const [faction, setFaction] = useState<Faction>( const [faction, setFaction] = useState<Faction>(
player.currentWorkFactionName ? Factions[player.currentWorkFactionName] : (undefined as unknown as Faction), player.currentWorkFactionName ? Factions[player.currentWorkFactionName] : (undefined as unknown as Faction),
@ -287,7 +288,9 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
<InteractiveTutorialRoot /> <InteractiveTutorialRoot />
)} )}
</Overview> </Overview>
{page === Page.BitVerse ? ( {page === Page.Loading ? (
<LoadingScreen />
) : page === Page.BitVerse ? (
<BitverseRoot flume={flume} enter={enterBitNode} quick={quick} /> <BitverseRoot flume={flume} enter={enterBitNode} quick={quick} />
) : page === Page.Infiltration ? ( ) : page === Page.Infiltration ? (
<InfiltrationRoot location={location} /> <InfiltrationRoot location={location} />
@ -360,7 +363,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
save={() => saveObject.saveGame(engine.indexedDb)} save={() => saveObject.saveGame(engine.indexedDb)}
delete={() => saveObject.deleteGame(engine.indexedDb)} delete={() => saveObject.deleteGame(engine.indexedDb)}
export={() => saveObject.exportGame()} export={() => saveObject.exportGame()}
import={() => saveObject.importGame()} import={openImportFileHandler}
forceKill={() => { forceKill={() => {
for (const hostname of Object.keys(AllServers)) { for (const hostname of Object.keys(AllServers)) {
AllServers[hostname].runningScripts = []; AllServers[hostname].runningScripts = [];

49
src/ui/LoadingScreen.tsx Normal file

@ -0,0 +1,49 @@
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 Paper from "@mui/material/Paper";
import { Theme } from "@mui/material";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import { CONSTANTS } from "../Constants";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
center: {
position: "fixed",
top: "50%",
left: "50%",
},
}),
);
export function LoadingScreen(): React.ReactElement {
const classes = useStyles();
const [show, setShow] = useState(false);
useEffect(() => {
const id = setTimeout(() => {
setShow(true);
}, 2000);
return () => clearTimeout(id);
}, []);
return (
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<CircularProgress size={150} color="primary" />
</Grid>
<Grid item>
<Typography variant="h3">Loading Bitburner v{CONSTANTS.Version}</Typography>
</Grid>
{show && (
<Grid item>
<Typography>
If the game fails to load, consider <a href="?noScripts">killing all scripts</a>
</Typography>
</Grid>
)}
</Grid>
);
}

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useRef } from "react";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
@ -13,7 +13,7 @@ import Switch from "@mui/material/Switch";
import Select, { SelectChangeEvent } from "@mui/material/Select"; import Select, { SelectChangeEvent } from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import List from "@mui/material/List"; import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem"; import ListItem from "@mui/material/ListItem";
@ -24,6 +24,7 @@ import DownloadIcon from "@mui/icons-material/Download";
import UploadIcon from "@mui/icons-material/Upload"; import UploadIcon from "@mui/icons-material/Upload";
import { FileDiagnosticModal } from "../../Diagnostic/FileDiagnosticModal"; import { FileDiagnosticModal } from "../../Diagnostic/FileDiagnosticModal";
import { dialogBoxCreate } from "../../../utils/DialogBox";
import { ConfirmationModal } from "./ConfirmationModal"; import { ConfirmationModal } from "./ConfirmationModal";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
@ -43,13 +44,14 @@ interface IProps {
save: () => void; save: () => void;
delete: () => void; delete: () => void;
export: () => void; export: () => void;
import: () => void; import: (evt: any) => void;
forceKill: () => void; forceKill: () => void;
softReset: () => void; softReset: () => void;
} }
export function GameOptionsRoot(props: IProps): React.ReactElement { export function GameOptionsRoot(props: IProps): React.ReactElement {
const classes = useStyles(); const classes = useStyles();
const importInput = useRef<HTMLInputElement>(null);
const [execTime, setExecTime] = useState(Settings.CodeInstructionRunTime); const [execTime, setExecTime] = useState(Settings.CodeInstructionRunTime);
const [logSize, setLogSize] = useState(Settings.MaxLogCapacity); const [logSize, setLogSize] = useState(Settings.MaxLogCapacity);
@ -151,6 +153,22 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
Settings.Locale = event.target.value as string; Settings.Locale = event.target.value as string;
} }
function importSave(): void {
if (window.File && window.FileReader && window.FileList && window.Blob) {
// var fileSelector = clearEventListeners("import-game-file-selector");
// fileSelector.addEventListener("change", openImportFileHandler, false);
const ii = importInput.current;
if (ii === null) throw new Error("import input should not be null");
ii.click();
} else {
dialogBoxCreate("ERR: Your browser does not support HTML5 File API. Cannot import.");
}
}
function onImport(event: React.ChangeEvent<HTMLInputElement>): void {
props.import(event);
}
return ( return (
<div className={classes.root} style={{ width: "90%" }}> <div className={classes.root} style={{ width: "90%" }}>
<Typography variant="h4" gutterBottom> <Typography variant="h4" gutterBottom>
@ -466,14 +484,17 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</Box> </Box>
<Box> <Box>
<Tooltip title={<Typography>export</Typography>}> <Tooltip title={<Typography>export</Typography>}>
<IconButton onClick={() => props.export()}> <Button onClick={() => props.export()}>
<DownloadIcon color="primary" /> <DownloadIcon color="primary" />
</IconButton> <Typography>Export</Typography>
</Button>
</Tooltip> </Tooltip>
<Tooltip title={<Typography>import</Typography>}> <Tooltip title={<Typography>import</Typography>}>
<IconButton onClick={() => props.import()}> <Button onClick={importSave}>
<UploadIcon color="primary" /> <UploadIcon color="primary" />
</IconButton> <Typography>Import</Typography>
<input ref={importInput} id="import-game-file-selector" type="file" hidden onChange={onImport} />
</Button>
</Tooltip> </Tooltip>
</Box> </Box>
<Box> <Box>

@ -22,7 +22,8 @@ export function Overview({ children }: IProps): React.ReactElement {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const classes = useStyles(); const classes = useStyles();
const router = use.Router(); const router = use.Router();
if (router.page() === Page.BitVerse || router.page() === Page.HackingMission) return <></>; if (router.page() === Page.BitVerse || router.page() === Page.HackingMission || router.page() === Page.Loading)
return <></>;
return ( return (
<div style={{ position: "fixed", top: 0, right: 0, zIndex: 1500 }}> <div style={{ position: "fixed", top: 0, right: 0, zIndex: 1500 }}>
<Box display="flex" justifyContent="flex-end" flexDirection={"column"}> <Box display="flex" justifyContent="flex-end" flexDirection={"column"}>

@ -35,6 +35,7 @@ export enum Page {
BladeburnerCinematic, BladeburnerCinematic,
Location, Location,
HackingMission, HackingMission,
Loading,
} }
/** /**

@ -1,11 +0,0 @@
import { getElementById } from "./getElementById";
import { removeElementById } from "./removeElementById";
/**
* Routes the player from the Loading screen to the main game content.
*/
export function removeLoadingScreen(): void {
// TODO: Have this manipulate CSS classes instead of direct styles
removeElementById("loader");
getElementById("entire-game-container").style.visibility = "visible";
}