From 562d4ee80042a3d77a1506c5e3f3bbc196a6bf30 Mon Sep 17 00:00:00 2001 From: TheMas3212 Date: Tue, 11 Jan 2022 17:50:41 +1100 Subject: [PATCH] Add ErrorBoundary component to catch rendering error and redirect to recovery page also add softreset button on recovery page --- src/ui/ErrorBoundary.tsx | 29 ++++++++++++++ src/ui/GameRoot.tsx | 73 ++++++++++++++++++++--------------- src/ui/React/RecoveryRoot.tsx | 4 +- 3 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 src/ui/ErrorBoundary.tsx diff --git a/src/ui/ErrorBoundary.tsx b/src/ui/ErrorBoundary.tsx new file mode 100644 index 000000000..ab555124e --- /dev/null +++ b/src/ui/ErrorBoundary.tsx @@ -0,0 +1,29 @@ +import React, { ErrorInfo } from "react"; +import { RecoveryRoot } from "./React/RecoveryRoot"; +import { IRouter } from "./Router"; + +interface IProps { + router: IRouter; + softReset: () => void; +} + + +export class ErrorBoundary extends React.Component { + state: { hasError: boolean } + constructor(props: IProps) { + super(props); + this.state = { hasError: false }; + } + componentDidCatch(error: Error, errorInfo: ErrorInfo): void { + console.error(error, errorInfo); + } + render(): React.ReactNode { + if (this.state.hasError) { + return ; + } + return this.props.children; + } + static getDerivedStateFromError(): { hasError: true} { + return { hasError: true }; + } +} \ No newline at end of file diff --git a/src/ui/GameRoot.tsx b/src/ui/GameRoot.tsx index dd5633e3c..177d6fcf5 100644 --- a/src/ui/GameRoot.tsx +++ b/src/ui/GameRoot.tsx @@ -77,6 +77,7 @@ import { enterBitNode } from "../RedPill"; import { Context } from "./Context"; import { RecoveryMode, RecoveryRoot } from "./React/RecoveryRoot"; import { AchievementsRoot } from "../Achievements/AchievementsRoot"; +import { ErrorBoundary } from "./ErrorBoundary"; const htmlLocation = location; @@ -234,6 +235,11 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme throw new Error("Trying to go to a page without the proper setup"); const [cinematicText, setCinematicText] = useState(""); + const [errorBoundaryKey, setErrorBoundaryKey] = useState(0); + + function resetErrorBoundary(): void { + setErrorBoundaryKey(errorBoundaryKey+1); + } function rerender(): void { setRerender((old) => old + 1); @@ -382,12 +388,19 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme if (page !== Page.Terminal) window.scrollTo(0, 0); }); + function softReset(): void { + dialogBoxCreate("Soft Reset!"); + prestigeAugmentation(); + resetErrorBoundary(); + Router.toTerminal(); + } + let mainPage = Cannot load; let withSidebar = true; let withPopups = true; switch (page) { case Page.Recovery: { - mainPage = ; + mainPage = ; withSidebar = false; withPopups = false; break; @@ -540,11 +553,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme saveObject.exportGame(); }} forceKill={killAllScripts} - softReset={() => { - dialogBoxCreate("Soft Reset!"); - prestigeAugmentation(); - Router.toTerminal(); - }} + softReset={softReset} /> ); break; @@ -574,37 +583,39 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme return ( - - - {!ITutorial.isRunning ? ( - + + + {!ITutorial.isRunning ? ( + saveObject.saveGame()} killScripts={killAllScripts} router={Router} allowBackButton={withSidebar} /> + ) : ( + + )} + + {withSidebar ? ( + + + {mainPage} + ) : ( - - )} - - {withSidebar ? ( - - {mainPage} - - ) : ( - {mainPage} - )} - - {withPopups && ( - <> - - - - - - - )} - + )} + + {withPopups && ( + <> + + + + + + + )} + + ); diff --git a/src/ui/React/RecoveryRoot.tsx b/src/ui/React/RecoveryRoot.tsx index 267e265e3..5c0e2e42c 100644 --- a/src/ui/React/RecoveryRoot.tsx +++ b/src/ui/React/RecoveryRoot.tsx @@ -15,9 +15,10 @@ export function ActivateRecoveryMode(): void { interface IProps { router: IRouter; + softReset: () => void; } -export function RecoveryRoot({ router }: IProps): React.ReactElement { +export function RecoveryRoot({ router, softReset }: IProps): React.ReactElement { function recover(): void { RecoveryMode = false; router.toTerminal(); @@ -48,6 +49,7 @@ export function RecoveryRoot({ router }: IProps): React.ReactElement {
You can disable recovery mode now. But chances are the game will not work correctly. + ); }