mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-22 14:12:27 +01:00
UI: Better support for custom player React content (#513)
This commit is contained in:
parent
0d55b957f1
commit
87f2ae459d
14
package-lock.json
generated
14
package-lock.json
generated
@ -61,7 +61,7 @@
|
||||
"@types/numeral": "^2.0.2",
|
||||
"@types/react": "^17.0.52",
|
||||
"@types/react-beautiful-dnd": "^13.1.3",
|
||||
"@types/react-dom": "^17.0.18",
|
||||
"@types/react-dom": "^17.0.20",
|
||||
"@types/react-resizable": "^3.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
@ -4472,9 +4472,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
"version": "17.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz",
|
||||
"integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==",
|
||||
"version": "17.0.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz",
|
||||
"integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "^17"
|
||||
@ -18963,9 +18963,9 @@
|
||||
}
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"version": "17.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz",
|
||||
"integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==",
|
||||
"version": "17.0.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz",
|
||||
"integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "^17"
|
||||
|
@ -62,7 +62,7 @@
|
||||
"@types/numeral": "^2.0.2",
|
||||
"@types/react": "^17.0.52",
|
||||
"@types/react-beautiful-dnd": "^13.1.3",
|
||||
"@types/react-dom": "^17.0.18",
|
||||
"@types/react-dom": "^17.0.20",
|
||||
"@types/react-resizable": "^3.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
|
@ -548,7 +548,7 @@ export const RamCosts: RamCostTree<NSFull> = {
|
||||
alterReality: 0,
|
||||
rainbow: 0,
|
||||
heart: { break: 0 },
|
||||
iKnowWhatImDoing: 0,
|
||||
tprintRaw: 0,
|
||||
printRaw: 0,
|
||||
|
||||
formulas: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type React from "react";
|
||||
import React from "react";
|
||||
import { Player } from "../Player";
|
||||
import { Exploit } from "../Exploits/Exploit";
|
||||
import * as bcrypt from "bcryptjs";
|
||||
@ -7,6 +7,10 @@ import { InternalAPI } from "../Netscript/APIWrapper";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { Terminal } from "../Terminal";
|
||||
import { RamCostConstants } from "../Netscript/RamCostGenerator";
|
||||
import { CustomBoundary } from "../ui/Components/CustomBoundary";
|
||||
|
||||
// Incrementing value for custom element keys
|
||||
let customElementKey = 0;
|
||||
|
||||
export interface INetscriptExtra {
|
||||
heart: {
|
||||
@ -17,7 +21,7 @@ export interface INetscriptExtra {
|
||||
bypass(doc: Document): void;
|
||||
alterReality(): void;
|
||||
rainbow(guess: string): void;
|
||||
iKnowWhatImDoing(): void;
|
||||
tprintRaw(value: React.ReactNode): void;
|
||||
printRaw(value: React.ReactNode): void;
|
||||
}
|
||||
|
||||
@ -67,14 +71,15 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
|
||||
Player.giveExploit(Exploit.INeedARainbow);
|
||||
return true;
|
||||
},
|
||||
iKnowWhatImDoing: (ctx) => () => {
|
||||
helpers.log(ctx, () => "Unlocking unsupported feature: window.tprintRaw");
|
||||
// @ts-expect-error window has no tprintRaw property defined
|
||||
window.tprintRaw = Terminal.printRaw.bind(Terminal);
|
||||
tprintRaw: () => (value) => {
|
||||
Terminal.printRaw(
|
||||
<CustomBoundary key={`PlayerContent${customElementKey++}`} children={value as React.ReactNode} />,
|
||||
);
|
||||
},
|
||||
printRaw: (ctx) => (value) => {
|
||||
// Using this voids the warranty on your tail log
|
||||
ctx.workerScript.print(value as React.ReactNode);
|
||||
ctx.workerScript.print(
|
||||
<CustomBoundary key={`PlayerContent${customElementKey++}`} children={value as React.ReactNode} />,
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
31
src/ui/Components/CustomBoundary.tsx
Normal file
31
src/ui/Components/CustomBoundary.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import React from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
interface CustomBoundaryProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
interface CustomBoundaryState {
|
||||
error?: Error;
|
||||
}
|
||||
/** Error boundary for custom content printed by the player using printRaw-like functions.
|
||||
* Error boundaries are required to be class components due to no hook equivalent to componentDidCatch. */
|
||||
export class CustomBoundary extends React.Component<CustomBoundaryProps, CustomBoundaryState> {
|
||||
state: CustomBoundaryState;
|
||||
constructor(props: CustomBoundaryProps) {
|
||||
super(props);
|
||||
this.state = { error: undefined };
|
||||
}
|
||||
componentDidCatch(error: Error): void {
|
||||
this.setState({ error });
|
||||
console.warn("Error in custom react content:");
|
||||
console.error(error);
|
||||
}
|
||||
render(): React.ReactNode {
|
||||
if (this.state.error) {
|
||||
// Typography is used because there are no default page styles.
|
||||
// Span is used because it does not conflict with the DOM validation nesting (default Typography element of p is invalid at this location in dom tree)
|
||||
return <Typography component={"span"}>Error in custom react content. See console for details.</Typography>;
|
||||
}
|
||||
return <Typography component={"span"}>{this.props.children}</Typography>;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user