mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 13:43:49 +01:00
CODEBASE: Add custom useRerender hook (#359)
This commit is contained in:
parent
b4074328ec
commit
6a6043c509
@ -2,7 +2,7 @@
|
||||
* Root React component for the Augmentations UI page that display all of your
|
||||
* owned and purchased Augmentations and Source-Files.
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { InstalledAugmentations } from "./InstalledAugmentations";
|
||||
import { PlayerMultipliers } from "./PlayerMultipliers";
|
||||
@ -26,6 +26,7 @@ import { formatNumberNoSuffix } from "../../ui/formatNumber";
|
||||
import { Info } from "@mui/icons-material";
|
||||
import { Link } from "@mui/material";
|
||||
import { AlertEvents } from "../../ui/React/AlertManager";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
const NeuroFluxDisplay = (): React.ReactElement => {
|
||||
const level = Player.augmentations.find((e) => e.name === AugmentationNames.NeuroFluxGovernor)?.level ?? 0;
|
||||
@ -84,14 +85,7 @@ interface IProps {
|
||||
|
||||
export function AugmentationsRoot(props: IProps): React.ReactElement {
|
||||
const [installOpen, setInstallOpen] = useState(false);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const rerender = useRerender(200);
|
||||
|
||||
function doExport(): void {
|
||||
props.exportGameFn();
|
||||
|
@ -15,9 +15,10 @@ import { Settings } from "../../Settings/Settings";
|
||||
import { Player } from "@player";
|
||||
import { StaticAugmentations } from "../StaticAugmentations";
|
||||
import { AugmentationNames } from "../data/AugmentationNames";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export function InstalledAugmentations(): React.ReactElement {
|
||||
const setRerender = useState(true)[1];
|
||||
const rerender = useRerender();
|
||||
const sourceAugs = Player.augmentations.slice().filter((aug) => aug.name !== AugmentationNames.NeuroFluxGovernor);
|
||||
|
||||
const [selectedAug, setSelectedAug] = useState(sourceAugs[0]);
|
||||
@ -28,10 +29,6 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
});
|
||||
}
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
function sortByAcquirementTime(): void {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||
rerender();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { formatNumberNoSuffix } from "../../ui/formatNumber";
|
||||
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
@ -14,6 +14,7 @@ import { StartButton } from "./StartButton";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
bladeburner: Bladeburner;
|
||||
@ -21,10 +22,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function BlackOpElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
const isCompleted = props.bladeburner.blackops[props.action.name] != null;
|
||||
if (isCompleted) {
|
||||
return (
|
||||
|
@ -1,22 +1,14 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { Stats } from "./Stats";
|
||||
import { Console } from "./Console";
|
||||
import { AllPages } from "./AllPages";
|
||||
|
||||
import { Player } from "@player";
|
||||
import Box from "@mui/material/Box";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export function BladeburnerRoot(): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
useRerender(200);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (!bladeburner) return <></>;
|
||||
return (
|
||||
|
@ -11,6 +11,7 @@ import TextField from "@mui/material/TextField";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface ILineProps {
|
||||
content: React.ReactNode;
|
||||
@ -54,8 +55,8 @@ interface IProps {
|
||||
export function Console(props: IProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const [command, setCommand] = useState("");
|
||||
const setRerender = useState(false)[1];
|
||||
const consoleInput = useRef<HTMLInputElement>(null);
|
||||
useRerender(1000);
|
||||
|
||||
function handleCommandChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setCommand(event.target.value);
|
||||
@ -63,17 +64,6 @@ export function Console(props: IProps): React.ReactElement {
|
||||
|
||||
const [consoleHistoryIndex, setConsoleHistoryIndex] = useState(props.bladeburner.consoleHistory.length);
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 1000);
|
||||
return () => {
|
||||
clearInterval(id);
|
||||
};
|
||||
}, []);
|
||||
|
||||
function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||
if (event.key === KEY.ENTER) {
|
||||
event.preventDefault();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
|
||||
@ -14,6 +14,7 @@ import { StartButton } from "./StartButton";
|
||||
import { formatNumberNoSuffix, formatBigNumber } from "../../ui/formatNumber";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
bladeburner: Bladeburner;
|
||||
@ -21,10 +22,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function ContractElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
const isActive =
|
||||
props.bladeburner.action.type === ActionTypes["Contract"] && props.action.name === props.bladeburner.action.name;
|
||||
const computedActionTimeCurrent = Math.min(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||
import { formatNumberNoSuffix } from "../../ui/formatNumber";
|
||||
@ -14,6 +14,7 @@ import { StartButton } from "./StartButton";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
bladeburner: Bladeburner;
|
||||
@ -21,10 +22,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function GeneralActionElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
const isActive = props.action.name === props.bladeburner.action.name;
|
||||
const computedActionTimeCurrent = Math.min(
|
||||
props.bladeburner.actionTimeCurrent + props.bladeburner.actionTimeOverflow,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
|
||||
@ -15,6 +15,7 @@ import { CopyableText } from "../../ui/React/CopyableText";
|
||||
import { formatNumberNoSuffix, formatBigNumber } from "../../ui/formatNumber";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
bladeburner: Bladeburner;
|
||||
@ -22,10 +23,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function OperationElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
const isActive =
|
||||
props.bladeburner.action.type === ActionTypes["Operation"] && props.action.name === props.bladeburner.action.name;
|
||||
const computedActionTimeCurrent = Math.min(
|
||||
|
@ -1,7 +1,7 @@
|
||||
// React Components for the Corporation UI's navigation tabs
|
||||
// These are the tabs at the top of the UI that let you switch to different
|
||||
// divisions, see an overview of your corporation, or create a new industry
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { MainPanel } from "./MainPanel";
|
||||
import { IndustryType } from "../data/Enums";
|
||||
import { ExpandIndustryTab } from "./ExpandIndustryTab";
|
||||
@ -11,22 +11,16 @@ import { Overview } from "./Overview";
|
||||
|
||||
import Tabs from "@mui/material/Tabs";
|
||||
import Tab from "@mui/material/Tab";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export function CorporationRoot(): React.ReactElement {
|
||||
const rerender = useRerender(200);
|
||||
const corporation = Player.corporation;
|
||||
if (corporation === null) return <></>;
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const [divisionName, setDivisionName] = useState<string | number>("Overview");
|
||||
function handleChange(event: React.SyntheticEvent, tab: string | number): void {
|
||||
setDivisionName(tab);
|
||||
}
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const canExpand =
|
||||
Object.values(IndustryType).filter(
|
||||
|
@ -14,6 +14,7 @@ import Box from "@mui/material/Box";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import { CityName } from "../../../Enums";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -32,11 +33,7 @@ export function ExportModal(props: IProps): React.ReactElement {
|
||||
const [industry, setIndustry] = useState<string>(defaultDivision.name);
|
||||
const [city, setCity] = useState(Object.keys(defaultDivision.warehouses)[0] as CityName);
|
||||
const [amt, setAmt] = useState("");
|
||||
const setRerender = useState(false)[1];
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
|
||||
function onCityChange(event: SelectChangeEvent<string>): void {
|
||||
setCity(event.target.value as CityName);
|
||||
|
@ -8,6 +8,7 @@ import TextField from "@mui/material/TextField";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
interface IMarketTA2Props {
|
||||
mat: Material;
|
||||
@ -17,10 +18,7 @@ function MarketTA2(props: IMarketTA2Props): React.ReactElement {
|
||||
const division = useDivision();
|
||||
if (!division.hasResearch("Market-TA.II")) return <></>;
|
||||
const [newCost, setNewCost] = useState<number>(props.mat.bCost);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
const markupLimit = props.mat.getMarkupLimit();
|
||||
|
||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
|
@ -8,6 +8,7 @@ import TextField from "@mui/material/TextField";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
interface ITa2Props {
|
||||
product: Product;
|
||||
@ -18,10 +19,7 @@ function MarketTA2(props: ITa2Props): React.ReactElement {
|
||||
if (!division.hasResearch("Market-TA.II")) return <></>;
|
||||
const markupLimit = props.product.rat / props.product.mku;
|
||||
const [value, setValue] = useState(props.product.pCost);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
|
||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setValue(parseFloat(event.target.value));
|
||||
|
@ -10,6 +10,7 @@ import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import { CorpMaterialName } from "@nsdefs";
|
||||
import { materialNames } from "../../data/Constants";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
interface ILeftoverProps {
|
||||
matName: CorpMaterialName;
|
||||
@ -49,10 +50,7 @@ interface IProps {
|
||||
|
||||
export function SmartSupplyModal(props: IProps): React.ReactElement {
|
||||
const division = useDivision();
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
|
||||
// Smart Supply Checkbox
|
||||
function smartSupplyOnChange(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { StaneksGiftEvents } from "../StaneksGiftEvents";
|
||||
@ -11,16 +11,14 @@ import { ActiveFragment } from "../ActiveFragment";
|
||||
import { Fragments } from "../Fragment";
|
||||
import { DummyGrid } from "./DummyGrid";
|
||||
import Container from "@mui/material/Container";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
staneksGift: StaneksGift;
|
||||
};
|
||||
|
||||
export function StaneksGiftRoot({ staneksGift }: IProps): React.ReactElement {
|
||||
const setRerender = useState(true)[1];
|
||||
function rerender(): void {
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
useEffect(() => StaneksGiftEvents.subscribe(rerender), []);
|
||||
return (
|
||||
<Container maxWidth="lg" disableGutters sx={{ mx: 0 }}>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material";
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||
import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
||||
@ -15,6 +15,7 @@ import { FactionNames } from "../data/FactionNames";
|
||||
import { Faction } from "../Faction";
|
||||
import { getFactionAugmentationsFiltered, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
faction: Faction;
|
||||
@ -23,11 +24,7 @@ type IProps = {
|
||||
|
||||
/** Root React Component for displaying a faction's "Purchase Augmentations" page */
|
||||
export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
|
||||
function getAugs(): string[] {
|
||||
return getFactionAugmentationsFiltered(props.faction);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* This is the component for displaying a single faction's UI, not the list of all
|
||||
* accessible factions
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { AugmentationsPage } from "./AugmentationsPage";
|
||||
import { DonateOption } from "./DonateOption";
|
||||
@ -25,6 +25,7 @@ import { FactionNames } from "../data/FactionNames";
|
||||
import { GangButton } from "./GangButton";
|
||||
import { FactionWork } from "../../Work/FactionWork";
|
||||
import { FactionWorkType } from "../../Enums";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
faction: Faction;
|
||||
@ -152,18 +153,9 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
|
||||
}
|
||||
|
||||
export function FactionRoot(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = useRerender(200);
|
||||
const [purchasingAugs, setPurchasingAugs] = useState(props.augPage);
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const faction = props.faction;
|
||||
|
||||
if (!Player.factions.includes(faction.name)) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Explore, Info, LastPage, LocalPolice, NewReleases, Report, SportsMma } from "@mui/icons-material";
|
||||
import { Box, Button, Container, Paper, Tooltip, Typography, useTheme } from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { Player } from "@player";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { formatFavor, formatReputation } from "../../ui/formatNumber";
|
||||
@ -9,6 +9,7 @@ import { FactionNames } from "../data/FactionNames";
|
||||
import { Faction } from "../Faction";
|
||||
import { getFactionAugmentationsFiltered, joinFaction } from "../FactionHelpers";
|
||||
import { Factions } from "../Factions";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export const InvitationsSeen: string[] = [];
|
||||
|
||||
@ -166,15 +167,7 @@ const FactionElement = (props: FactionElementProps): React.ReactElement => {
|
||||
|
||||
export function FactionsRoot(): React.ReactElement {
|
||||
const theme = useTheme();
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const rerender = useRerender(200);
|
||||
useEffect(() => {
|
||||
Player.factionInvitations.forEach((faction) => {
|
||||
if (InvitationsSeen.includes(faction)) return;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* React component for general information about the faction. This includes the
|
||||
* factions "motto", reputation, favor, and gameplay instructions
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { Faction } from "../Faction";
|
||||
import { FactionInfo } from "../FactionInfo";
|
||||
@ -16,6 +16,7 @@ import createStyles from "@mui/styles/createStyles";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Box from "@mui/material/Box";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
faction: Faction;
|
||||
@ -43,16 +44,7 @@ function DefaultAssignment(): React.ReactElement {
|
||||
}
|
||||
|
||||
export function Info(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
useRerender(200);
|
||||
const classes = useStyles();
|
||||
|
||||
const Assignment = props.factionInfo.assignment ?? DefaultAssignment;
|
||||
|
@ -19,6 +19,7 @@ import { UpgradeType } from "../data/upgrades";
|
||||
import { Player } from "@player";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { StatsRow } from "../../ui/React/StatsRow";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface INextRevealProps {
|
||||
upgrades: string[];
|
||||
@ -86,13 +87,9 @@ interface IPanelProps {
|
||||
|
||||
function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
|
||||
const gang = useGang();
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = useRerender();
|
||||
const [currentCategory, setCurrentCategory] = useState("Weapons");
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
function filterUpgrades(list: string[], type: UpgradeType): GangMemberUpgrade[] {
|
||||
return Object.keys(GangMemberUpgrades)
|
||||
.filter((upgName: string) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { GeneralInfo } from "./GeneralInfo";
|
||||
import { HacknetNodeElem } from "./HacknetNodeElem";
|
||||
@ -25,21 +25,14 @@ import Typography from "@mui/material/Typography";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Button from "@mui/material/Button";
|
||||
import { Box } from "@mui/material";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
/** Root React Component for the Hacknet Node UI */
|
||||
export function HacknetRoot(): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender(200);
|
||||
const [purchaseMultiplier, setPurchaseMultiplier] = useState<number | "MAX">(PurchaseMultipliers.x1);
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
let totalProduction = 0;
|
||||
for (let i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
const node = Player.hacknetNodes[i];
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { HashUpgrades } from "../HashUpgrades";
|
||||
|
||||
@ -7,6 +7,7 @@ import { HacknetUpgradeElem } from "./HacknetUpgradeElem";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { Player } from "@player";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -15,15 +16,7 @@ interface IProps {
|
||||
|
||||
/** Create the pop-up for purchasing upgrades with hashes */
|
||||
export function HashUpgradeModal(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => setRerender((old) => !old), 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const rerender = useRerender(200);
|
||||
|
||||
const hashManager = Player.hashManager;
|
||||
if (!hashManager) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This subcomponent renders all of the buttons for applying to jobs at a company
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
@ -25,6 +25,7 @@ import { Page } from "../../ui/Router";
|
||||
import { Player } from "@player";
|
||||
import { QuitJobModal } from "../../Company/ui/QuitJobModal";
|
||||
import { CompanyWork } from "../../Work/CompanyWork";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
locName: LocationName;
|
||||
@ -32,15 +33,8 @@ type IProps = {
|
||||
|
||||
export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
const [quitOpen, setQuitOpen] = useState(false);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender(200);
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
/**
|
||||
* We'll keep a reference to the Company that this component is being rendered for,
|
||||
* so we don't have to look it up every time
|
||||
|
@ -12,20 +12,12 @@ import { getHospitalizationCost } from "../../Hospital/Hospital";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export function HospitalLocation(): React.ReactElement {
|
||||
/** Stores button styling that sets them all to block display */
|
||||
const btnStyle = { display: "block" };
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const rerender = useRerender(200);
|
||||
|
||||
function getHealed(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
|
@ -14,7 +14,6 @@ interface IProps {
|
||||
onClose: () => void;
|
||||
ram: number;
|
||||
cost: number;
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
/** React Component for the popup used to purchase a new server. */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This subcomponent renders all of the buttons for committing crimes
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
@ -15,15 +15,11 @@ import { Page } from "../../ui/Router";
|
||||
import { Player } from "@player";
|
||||
import { Box } from "@mui/material";
|
||||
import { Crime } from "../../Crime/Crime";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export function SlumsLocation(): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = () => setRerender((o) => !o);
|
||||
useRerender(1000);
|
||||
const crimes = Object.values(Crimes);
|
||||
useEffect(() => {
|
||||
const timerId = setInterval(() => rerender(), 1000);
|
||||
return () => clearInterval(timerId);
|
||||
});
|
||||
|
||||
function doCrime(e: React.MouseEvent<HTMLElement>, crime: Crime) {
|
||||
if (!e.isTrusted) return;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This subcomponent renders all of the buttons for purchasing things from tech vendors
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
|
||||
@ -19,13 +19,9 @@ import { Player } from "@player";
|
||||
import { PurchaseServerModal } from "./PurchaseServerModal";
|
||||
import { formatRam } from "../../ui/formatNumber";
|
||||
import { Box } from "@mui/material";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IServerProps {
|
||||
ram: number;
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
function ServerButton(props: IServerProps): React.ReactElement {
|
||||
function ServerButton(props: { ram: number }): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
const cost = getPurchaseServerCost(props.ram);
|
||||
return (
|
||||
@ -34,35 +30,17 @@ function ServerButton(props: IServerProps): React.ReactElement {
|
||||
Purchase {formatRam(props.ram)} Server -
|
||||
<Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
<PurchaseServerModal
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
ram={props.ram}
|
||||
cost={cost}
|
||||
rerender={props.rerender}
|
||||
/>
|
||||
<PurchaseServerModal open={open} onClose={() => setOpen(false)} ram={props.ram} cost={cost} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
};
|
||||
|
||||
export function TechVendorLocation(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 1000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
export function TechVendorLocation(props: { loc: Location }): React.ReactElement {
|
||||
const rerender = useRerender(1000);
|
||||
|
||||
const purchaseServerButtons: React.ReactNode[] = [];
|
||||
for (let i = props.loc.techVendorMinRam; i <= props.loc.techVendorMaxRam; i *= 2) {
|
||||
purchaseServerButtons.push(<ServerButton key={i} ram={i} rerender={rerender} />);
|
||||
purchaseServerButtons.push(<ServerButton key={i} ram={i} />);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* TThis subcomponent renders all of the buttons for traveling to different cities
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { CityName } from "../../Enums";
|
||||
import { TravelConfirmationModal } from "./TravelConfirmationModal";
|
||||
@ -21,6 +21,7 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
function travel(to: CityName): void {
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
@ -35,17 +36,9 @@ function travel(to: CityName): void {
|
||||
}
|
||||
|
||||
export function TravelAgencyRoot(): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const [open, setOpen] = useState(false);
|
||||
const [destination, setDestination] = useState(CityName.Sector12);
|
||||
function rerender(): void {
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 1000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
useRerender(1000);
|
||||
|
||||
function startTravel(city: CityName): void {
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { CheckBox, CheckBoxOutlineBlank, Construction } from "@mui/icons-material";
|
||||
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { GraftingWork } from "../../../Work/GraftingWork";
|
||||
import { Augmentation } from "../../../Augmentation/Augmentation";
|
||||
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
|
||||
@ -20,6 +20,7 @@ import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFun
|
||||
import { Player } from "@player";
|
||||
import { GraftableAugmentation } from "../GraftableAugmentation";
|
||||
import { calculateGraftingTimeWithBonus, getGraftingAvailableAugs } from "../GraftingHelpers";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
export const GraftableAugmentations = (): Record<string, GraftableAugmentation> => {
|
||||
const gAugs: Record<string, GraftableAugmentation> = {};
|
||||
@ -65,11 +66,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs()[0]);
|
||||
const [graftOpen, setGraftOpen] = useState(false);
|
||||
const selectedAugmentation = StaticAugmentations[selectedAug];
|
||||
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
const rerender = useRerender(200);
|
||||
|
||||
const getAugsSorted = (): string[] => {
|
||||
const augs = getGraftingAvailableAugs();
|
||||
@ -86,11 +83,6 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
rerender();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container disableGutters maxWidth="lg" sx={{ mx: 0 }}>
|
||||
<Button onClick={() => Router.toLocation(Locations[LocationName.NewTokyoVitaLife])}>Back</Button>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Root React component for the popup that lets player purchase Duplicate
|
||||
* Sleeves and Sleeve-related upgrades from The Covenant
|
||||
*/
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { CovenantSleeveMemoryUpgrade } from "./CovenantSleeveMemoryUpgrade";
|
||||
|
||||
@ -17,6 +17,7 @@ import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import { FactionNames } from "../../../Faction/data/FactionNames";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -24,18 +25,13 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
|
||||
const [update, setUpdate] = useState(0);
|
||||
const rerender = useRerender();
|
||||
|
||||
/** Get the cost to purchase a new Duplicate Sleeve */
|
||||
function purchaseCost(): number {
|
||||
return Math.pow(10, Player.sleevesFromCovenant) * BaseCostPerSleeve;
|
||||
}
|
||||
|
||||
/** Force a rerender by just changing an arbitrary state value */
|
||||
function rerender(): void {
|
||||
setUpdate(update + 1);
|
||||
}
|
||||
|
||||
// Purchasing a new Duplicate Sleeve
|
||||
let purchaseDisabled = false;
|
||||
if (!Player.canAfford(purchaseCost())) {
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { Container, Typography, Paper } from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { PurchasableAugmentations } from "../../../Augmentation/ui/PurchasableAugmentations";
|
||||
import { Player } from "@player";
|
||||
import { Modal } from "../../../ui/React/Modal";
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -12,15 +13,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 150);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const rerender = useRerender(150);
|
||||
|
||||
// Array of all owned Augmentations. Names only
|
||||
const ownedAugNames = props.sleeve.augmentations.map((e) => e.name);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Box, Typography, Button, Container } from "@mui/material";
|
||||
|
||||
@ -6,18 +6,11 @@ import { Player } from "@player";
|
||||
|
||||
import { SleeveElem } from "./SleeveElem";
|
||||
import { FAQModal } from "./FAQModal";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
|
||||
export function SleeveRoot(): React.ReactElement {
|
||||
const [FAQOpen, setFAQOpen] = useState(false);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const rerender = useRerender(200);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { find } from "lodash";
|
||||
|
||||
import { Box, Typography, Button, Container, Paper } from "@mui/material";
|
||||
@ -11,14 +11,12 @@ import { Settings } from "../../Settings/Settings";
|
||||
|
||||
import { Programs } from "../Programs";
|
||||
import { CreateProgramWork } from "../../Work/CreateProgramWork";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
export const ProgramsSeen: string[] = [];
|
||||
|
||||
export function ProgramsRoot(): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
useRerender(200);
|
||||
|
||||
const programs = [...Object.values(Programs)]
|
||||
.filter((prog) => {
|
||||
@ -42,11 +40,6 @@ export function ProgramsRoot(): React.ReactElement {
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const getHackingLevelRemaining = (lvl: number): number => {
|
||||
return Math.ceil(Math.max(lvl - (Player.skills.hacking + Player.skills.intelligence / 2), 0));
|
||||
};
|
||||
|
@ -45,6 +45,7 @@ import { Modal } from "../../ui/React/Modal";
|
||||
|
||||
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
|
||||
import { TextField, Tooltip } from "@mui/material";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
interface IProps {
|
||||
// Map of filename -> code
|
||||
@ -106,10 +107,7 @@ let currentScript: OpenScript | null = null;
|
||||
|
||||
// Called every time script editor is opened
|
||||
export function Root(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
|
||||
const monacoRef = useRef<Monaco | null>(null);
|
||||
const vimStatusRef = useRef<HTMLElement>(null);
|
||||
|
@ -4,6 +4,7 @@ import IconButton from "@mui/material/IconButton";
|
||||
import _ from "lodash";
|
||||
import { Color, ColorPicker } from "material-ui-color";
|
||||
import React, { useState } from "react";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { OptionSwitch } from "../../ui/React/OptionSwitch";
|
||||
@ -65,10 +66,7 @@ function ColorEditor({ label, themePath, onColorChange, color, defaultColor }: I
|
||||
}
|
||||
|
||||
export function ThemeEditorModal(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
|
||||
// Need to deep copy the object since it has nested attributes
|
||||
const [themeCopy, setThemeCopy] = useState<IScriptEditorTheme>(JSON.parse(JSON.stringify(Settings.EditorTheme)));
|
||||
|
@ -54,6 +54,7 @@ import { ProgramsSeen } from "../../Programs/ui/ProgramsRoot";
|
||||
import { InvitationsSeen } from "../../Faction/ui/FactionsRoot";
|
||||
import { hash } from "../../hash/hash";
|
||||
import { Locations } from "../../Locations/Locations";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
const RotatedDoubleArrowIcon = React.forwardRef((props: { color: "primary" | "secondary" | "error" }, __ref) => (
|
||||
<DoubleArrowIcon color={props.color} style={{ transform: "rotate(-90deg)" }} />
|
||||
@ -108,15 +109,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function SidebarRoot(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
useRerender(200);
|
||||
|
||||
let flash: Page | null = null;
|
||||
switch (ITutorial.currStep) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { InfoAndPurchases } from "./InfoAndPurchases";
|
||||
import { StockTickers } from "./StockTickers";
|
||||
@ -6,6 +6,7 @@ import { StockTickers } from "./StockTickers";
|
||||
import { IStockMarket } from "../IStockMarket";
|
||||
|
||||
import { Player } from "@player";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
stockMarket: IStockMarket;
|
||||
@ -13,15 +14,7 @@ type IProps = {
|
||||
|
||||
/** Root React component for the Stock Market UI */
|
||||
export function StockMarketRoot(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
const rerender = useRerender(200);
|
||||
return (
|
||||
<>
|
||||
<InfoAndPurchases rerender={rerender} />
|
||||
|
@ -10,13 +10,14 @@ import { StockTickersConfig, TickerDisplayMode } from "./StockTickersConfig";
|
||||
|
||||
import { IStockMarket } from "../IStockMarket";
|
||||
import { Stock } from "../Stock";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
type IProps = {
|
||||
stockMarket: IStockMarket;
|
||||
};
|
||||
|
||||
export function StockTickers(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = useRerender();
|
||||
const [tickerDisplayMode, setTickerDisplayMode] = useState(TickerDisplayMode.AllStocks);
|
||||
const [watchlistSymbols, setWatchlistSymbols] = useState<string[]>([]);
|
||||
|
||||
@ -39,10 +40,6 @@ export function StockTickers(props: IProps): React.ReactElement {
|
||||
}
|
||||
}
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
const tickers: React.ReactElement[] = [];
|
||||
for (const stockMarketProp of Object.keys(props.stockMarket)) {
|
||||
const val = props.stockMarket[stockMarketProp];
|
||||
|
@ -16,6 +16,7 @@ import { CodingContractModal } from "../../ui/React/CodingContractModal";
|
||||
|
||||
import _ from "lodash";
|
||||
import { ANSIITypography } from "../../ui/React/ANSIITypography";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
|
||||
function ActionTimer(): React.ReactElement {
|
||||
return (
|
||||
@ -44,11 +45,8 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
|
||||
export function TerminalRoot(): React.ReactElement {
|
||||
const scrollHook = useRef<HTMLDivElement>(null);
|
||||
const setRerender = useState(0)[1];
|
||||
const rerender = useRerender();
|
||||
const [key, setKey] = useState(0);
|
||||
function rerender(): void {
|
||||
setRerender((old) => old + 1);
|
||||
}
|
||||
|
||||
function clear(): void {
|
||||
setKey((key) => key + 1);
|
||||
|
@ -2,30 +2,23 @@
|
||||
* Root React Component for the "Active Scripts" UI page. This page displays
|
||||
* and provides information about all of the player's scripts that are currently running
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
import Tabs from "@mui/material/Tabs";
|
||||
import Tab from "@mui/material/Tab";
|
||||
|
||||
import { ActiveScriptsPage } from "./ActiveScriptsPage";
|
||||
import { RecentScriptsPage } from "./RecentScriptsPage";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
import { useRerender } from "../React/hooks";
|
||||
|
||||
interface IProps {
|
||||
workerScripts: Map<number, WorkerScript>;
|
||||
}
|
||||
|
||||
export function ActiveScriptsRoot(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const [tab, setTab] = useState<"active" | "recent">("active");
|
||||
useRerender(200);
|
||||
|
||||
function handleChange(event: React.SyntheticEvent, tab: "active" | "recent"): void {
|
||||
setTab(tab);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import { BaseServer } from "../../Server/BaseServer";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
import { useRerender } from "../React/hooks";
|
||||
|
||||
// Map of server hostname -> all workerscripts on that server for all active scripts
|
||||
interface IServerData {
|
||||
@ -35,7 +36,7 @@ export function ServerAccordions(props: IProps): React.ReactElement {
|
||||
const [filter, setFilter] = useState("");
|
||||
const [page, setPage] = useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(Settings.ActiveScriptsServerPageSize);
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = useRerender();
|
||||
|
||||
const handleChangePage = (event: unknown, newPage: number): void => {
|
||||
setPage(newPage);
|
||||
@ -78,10 +79,6 @@ export function ServerAccordions(props: IProps): React.ReactElement {
|
||||
(data.server.hostname.includes(filter) || data.server.runningScripts.find((s) => s.filename.includes(filter))),
|
||||
);
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => WorkerScriptStartStopEventEmitter.subscribe(rerender));
|
||||
|
||||
return (
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Paper, Table, TableBody, Box, IconButton, Typography, Container, Tooltip } from "@mui/material";
|
||||
import { MoreHoriz, Info } from "@mui/icons-material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { BitNodes, defaultMultipliers, getBitNodeMultipliers } from "../BitNode/BitNode";
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import { BitNodeMultipliersDisplay } from "../BitNode/ui/BitnodeMultipliersDescription";
|
||||
@ -16,6 +16,7 @@ import { Money } from "./React/Money";
|
||||
import { StatsRow } from "./React/StatsRow";
|
||||
import { StatsTable } from "./React/StatsTable";
|
||||
import { isEqual } from "lodash";
|
||||
import { useRerender } from "./React/hooks";
|
||||
|
||||
interface EmployersModalProps {
|
||||
open: boolean;
|
||||
@ -199,15 +200,7 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
|
||||
export function CharacterStats(): React.ReactElement {
|
||||
const [moneyOpen, setMoneyOpen] = useState(false);
|
||||
const [employersOpen, setEmployersOpen] = useState(false);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
useRerender(200);
|
||||
|
||||
const timeRows = [
|
||||
["Since last Augmentation installation", convertTimeMsToTimeElapsedString(Player.playtimeSinceLastAug)],
|
||||
|
@ -77,6 +77,7 @@ import { Apr1 } from "./Apr1";
|
||||
import { isFactionWork } from "../Work/FactionWork";
|
||||
import { V2Modal } from "../utils/V2Modal";
|
||||
import { MathJaxContext } from "better-react-mathjax";
|
||||
import { useRerender } from "./React/hooks";
|
||||
|
||||
const htmlLocation = location;
|
||||
|
||||
@ -127,7 +128,7 @@ export function GameRoot(): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const [{ files, vim }, setEditorOptions] = useState({ files: {}, vim: false });
|
||||
const [page, setPage] = useState(determineStartPage());
|
||||
const setRerender = useState(0)[1];
|
||||
const rerender = useRerender();
|
||||
const [augPage, setAugPage] = useState<boolean>(false);
|
||||
const [faction, setFaction] = useState<Faction>(
|
||||
isFactionWork(Player.currentWork) ? Factions[Player.currentWork.factionName] : (undefined as unknown as Faction),
|
||||
@ -155,9 +156,6 @@ export function GameRoot(): React.ReactElement {
|
||||
setErrorBoundaryKey(errorBoundaryKey + 1);
|
||||
}
|
||||
|
||||
function rerender(): void {
|
||||
setRerender((old) => old + 1);
|
||||
}
|
||||
useEffect(() => {
|
||||
return ITutorialEvents.subscribe(rerender);
|
||||
}, []);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Typography from "@mui/material/Typography";
|
||||
@ -27,6 +27,7 @@ import {
|
||||
iTutorialSteps,
|
||||
iTutorialEnd,
|
||||
} from "../../InteractiveTutorial";
|
||||
import { useRerender } from "../React/hooks";
|
||||
|
||||
interface IContent {
|
||||
content: React.ReactElement;
|
||||
@ -47,6 +48,7 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
|
||||
export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const rerender = useRerender();
|
||||
|
||||
const tutorialScriptName = `n00dles.js`;
|
||||
|
||||
@ -556,11 +558,6 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
},
|
||||
};
|
||||
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
return ITutorialEvents.subscribe(rerender);
|
||||
}, []);
|
||||
|
@ -19,6 +19,7 @@ import { debounce } from "lodash";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { ANSIITypography } from "./ANSIITypography";
|
||||
import { ScriptArg } from "../../Netscript/ScriptArg";
|
||||
import { useRerender } from "./hooks";
|
||||
|
||||
let layerCounter = 0;
|
||||
|
||||
@ -53,10 +54,7 @@ interface Log {
|
||||
let logs: Log[] = [];
|
||||
|
||||
export function LogBoxManager(): React.ReactElement {
|
||||
const setRerender = useState(true)[1];
|
||||
function rerender(): void {
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
const rerender = useRerender();
|
||||
useEffect(
|
||||
() =>
|
||||
LogBoxEvents.subscribe((script: RunningScript) => {
|
||||
@ -140,12 +138,9 @@ function LogWindow(props: IProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const container = useRef<HTMLDivElement>(null);
|
||||
const textArea = useRef<HTMLDivElement>(null);
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = useRerender(1000);
|
||||
const [size, setSize] = useState<[number, number]>([500, 500]);
|
||||
const [minimized, setMinimized] = useState(false);
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
const textAreaKeyDown = (e: React.KeyboardEvent) => {
|
||||
if (e.ctrlKey && e.key === "a") {
|
||||
@ -214,8 +209,6 @@ function LogWindow(props: IProps): React.ReactElement {
|
||||
|
||||
useEffect(() => {
|
||||
updateLayer();
|
||||
const id = setInterval(rerender, 1000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
function kill(): void {
|
||||
|
15
src/ui/React/hooks.ts
Normal file
15
src/ui/React/hooks.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
/** Hook that returns a function for the component. Optionally set an interval to rerender the component.
|
||||
* @param autoRerenderTime: Optional. If provided and nonzero, used as the ms interval to automatically call the rerender function.
|
||||
*/
|
||||
export function useRerender(autoRerenderTime?: number) {
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = () => setRerender((old) => !old);
|
||||
useEffect(() => {
|
||||
if (!autoRerenderTime) return;
|
||||
const intervalID = setInterval(rerender, autoRerenderTime);
|
||||
return () => clearInterval(intervalID);
|
||||
}, []);
|
||||
return rerender;
|
||||
}
|
@ -2,7 +2,7 @@ import { Box, Container, Paper, Table, TableBody, Tooltip } from "@mui/material"
|
||||
import Button from "@mui/material/Button";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { uniqueId } from "lodash";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { LocationName } from "../Enums";
|
||||
@ -27,6 +27,7 @@ import { isGraftingWork } from "../Work/GraftingWork";
|
||||
import { isFactionWork } from "../Work/FactionWork";
|
||||
import { FactionWorkType } from "../Enums";
|
||||
import { isCompanyWork } from "../Work/CompanyWork";
|
||||
import { useRerender } from "./React/hooks";
|
||||
|
||||
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
|
||||
|
||||
@ -193,15 +194,7 @@ function CrimeExpRows(rate: WorkStats): React.ReactElement[] {
|
||||
}
|
||||
|
||||
export function WorkInProgressRoot(): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, CONSTANTS.MilliPerCycle);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
useRerender(CONSTANTS.MilliPerCycle);
|
||||
|
||||
let workInfo: IWorkInfo = {
|
||||
buttons: {
|
||||
|
Loading…
Reference in New Issue
Block a user