Fix more overview issues

Previous changes had overview become empty when collapsing it, which broke the collapse animation. It also would have broken use of the player-visible hooks, because those would have been removed from the document on collapse.
Now a context is used to store whether the overview is being shown or not, and components that update themselves will only do so when they are being shown.
This commit is contained in:
omuretsu 2022-12-30 15:42:58 -05:00
parent 62a2532d05
commit 313f6ada94

@ -1,5 +1,5 @@
// Root React Component for the Corporation UI // Root React Component for the Corporation UI
import React, { useMemo, useState, useEffect } from "react"; import React, { useMemo, useState, useEffect, createContext, useContext } from "react";
import { Theme, useTheme } from "@mui/material/styles"; import { Theme, useTheme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
@ -43,6 +43,7 @@ import { calculateSkillProgress } from "../../PersonObjects/formulas/skill";
type SkillRowName = "Hack" | "Str" | "Def" | "Dex" | "Agi" | "Cha" | "Int"; type SkillRowName = "Hack" | "Str" | "Def" | "Dex" | "Agi" | "Cha" | "Int";
type RowName = SkillRowName | "HP" | "Money"; type RowName = SkillRowName | "HP" | "Money";
const ShownContext = createContext(true); //Context for whether to update components
// These values aren't displayed, they're just used for comparison to check if state has changed // These values aren't displayed, they're just used for comparison to check if state has changed
const valUpdaters: Record<RowName, () => any> = { const valUpdaters: Record<RowName, () => any> = {
@ -96,17 +97,17 @@ interface SkillBarProps {
color?: string; color?: string;
} }
function SkillBar({ name, color }: SkillBarProps): React.ReactElement { function SkillBar({ name, color }: SkillBarProps): React.ReactElement {
const shown = useContext(ShownContext);
const [mult, setMult] = useState(skillMultUpdaters[name]?.()); const [mult, setMult] = useState(skillMultUpdaters[name]?.());
const [progress, setProgress] = useState(calculateSkillProgress(Player.exp[skillNameMap[name]], mult)); const [progress, setProgress] = useState(calculateSkillProgress(Player.exp[skillNameMap[name]], mult));
useEffect(() => { useEffect(() => {
if (!shown) return;
const interval = setInterval(() => { const interval = setInterval(() => {
setMult(skillMultUpdaters[name]()); setMult(skillMultUpdaters[name]());
setProgress(calculateSkillProgress(Player.exp[skillNameMap[name] as keyof Skills], mult)); setProgress(calculateSkillProgress(Player.exp[skillNameMap[name] as keyof Skills], mult));
}, 600); }, 600);
return () => { return () => clearInterval(interval);
clearInterval(interval); }, [shown]);
};
}, []);
return ( return (
<TableRow> <TableRow>
<StatsProgressOverviewCell progress={progress} color={color} /> <StatsProgressOverviewCell progress={progress} color={color} />
@ -121,10 +122,12 @@ interface ValProps {
export function Val({ name, color }: ValProps): React.ReactElement { export function Val({ name, color }: ValProps): React.ReactElement {
//val isn't actually used here, the update of val just forces a refresh of the formattedVal that gets shown //val isn't actually used here, the update of val just forces a refresh of the formattedVal that gets shown
const setVal = useState(valUpdaters[name]())[1]; const setVal = useState(valUpdaters[name]())[1];
const shown = useContext(ShownContext);
useEffect(() => { useEffect(() => {
const interval = setInterval(() => setVal(valUpdaters[name]())); if (!shown) return;
const interval = setInterval(() => setVal(valUpdaters[name]()), 600);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, [shown]);
return <Typography color={color}>{formattedVals[name]()}</Typography>; return <Typography color={color}>{formattedVals[name]()}</Typography>;
} }
@ -178,8 +181,8 @@ export function CharacterOverview({ parentOpen, save, killScripts }: OverviewPro
}, []); }, []);
const classes = useStyles(); const classes = useStyles();
const theme = useTheme(); const theme = useTheme();
return parentOpen ? ( return (
<> <ShownContext.Provider value={parentOpen}>
<Table sx={{ display: "block", m: 1 }}> <Table sx={{ display: "block", m: 1 }}>
<TableBody> <TableBody>
<DataRow name="HP" showBar={false} color={theme.colors.hp} cellType={"cellNone"} /> <DataRow name="HP" showBar={false} color={theme.colors.hp} cellType={"cellNone"} />
@ -233,9 +236,7 @@ export function CharacterOverview({ parentOpen, save, killScripts }: OverviewPro
</Box> </Box>
</Box> </Box>
<KillScriptsModal open={killOpen} onClose={() => setKillOpen(false)} killScripts={killScripts} /> <KillScriptsModal open={killOpen} onClose={() => setKillOpen(false)} killScripts={killScripts} />
</> </ShownContext.Provider>
) : (
<></>
); );
} }
@ -250,12 +251,14 @@ function ActionText(props: { action: ActionIdentifier }): React.ReactElement {
} }
function BladeburnerText(): React.ReactElement { function BladeburnerText(): React.ReactElement {
const shown = useContext(ShownContext);
const classes = useStyles(); const classes = useStyles();
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
useEffect(() => { useEffect(() => {
if (!shown) return;
const interval = setInterval(() => setRerender((old) => !old), 600); const interval = setInterval(() => setRerender((old) => !old), 600);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, [shown]);
const action = Player.bladeburner?.action; const action = Player.bladeburner?.action;
return useMemo( return useMemo(
@ -327,11 +330,13 @@ function WorkInProgressOverview({ tooltip, children, header }: WorkInProgressOve
} }
function Work(): React.ReactElement { function Work(): React.ReactElement {
const shown = useContext(ShownContext);
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
useEffect(() => { useEffect(() => {
if (!shown) return;
const interval = setInterval(() => setRerender((old) => !old), 600); const interval = setInterval(() => setRerender((old) => !old), 600);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, [shown]);
if (Player.currentWork === null || Player.focus) return <></>; if (Player.currentWork === null || Player.focus) return <></>;