sendou.ink/pages/analyzer.tsx
2020-11-27 20:41:29 +02:00

209 lines
6.7 KiB
TypeScript

import {
Badge,
Box,
Button,
Flex,
FormLabel,
Switch,
Wrap,
} from "@chakra-ui/react";
import { t, Trans } from "@lingui/macro";
import BuildStats from "components/analyzer/BuildStats";
import EditableBuilds from "components/analyzer/EditableBuilds";
import { ViewSlotsAbilities } from "components/builds/ViewSlots";
import Breadcrumbs from "components/common/Breadcrumbs";
import WeaponSelector from "components/common/WeaponSelector";
import { isAbilityArray } from "lib/lists/abilities";
import { isWeapon } from "lib/lists/weapons";
import { AbilityOrUnknown } from "lib/types";
import useAbilityEffects from "lib/useAbilityEffects";
import { useMyTheme } from "lib/useMyTheme";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { FiSettings } from "react-icons/fi";
const CURRENT_PATCH = "5.3.";
const defaultBuild: ViewSlotsAbilities = {
headAbilities: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
clothingAbilities: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
shoesAbilities: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
};
const BuildAnalyzerPage = () => {
const router = useRouter();
const { gray } = useMyTheme();
const [build, setBuild] = useState<ViewSlotsAbilities>({
...defaultBuild,
});
const [otherBuild, setOtherBuild] = useState<ViewSlotsAbilities>({
...defaultBuild,
});
const [weapon, setWeapon] = useState("Splattershot Jr.");
const [showOther, setShowOther] = useState(false);
const [showNotActualProgress, setShowNotActualProgress] = useState(false);
const [startChartsAtZero, setStartChartsAtZero] = useState(true);
const [otherFocused, setOtherFocused] = useState(false);
const [hideExtra, setHideExtra] = useState(true);
const [showSettings, setShowSettings] = useState(false);
const [bonusAp, setBonusAp] = useState<
Partial<Record<AbilityOrUnknown, boolean>>
>({});
const [otherBonusAp, setOtherBonusAp] = useState<
Partial<Record<AbilityOrUnknown, boolean>>
>({});
const [lde, setLde] = useState(0);
const [otherLde, setOtherLde] = useState(0);
const explanations = useAbilityEffects({
abilities: build,
weapon,
bonusAp,
lde,
});
const otherExplanations = useAbilityEffects({
abilities: otherBuild,
weapon,
bonusAp: otherBonusAp,
lde: otherLde,
});
useEffect(parseQuery, []);
return (
<>
<Breadcrumbs pages={[{ name: t`Build Analyzer` }]} />
<Flex justifyContent="space-between">
<Badge>
<Trans>Patch {CURRENT_PATCH}</Trans>
</Badge>
<Box color={gray} fontSize="0.75em">
<Trans>AP = Ability Point = Mains * 10 + Subs * 3</Trans>
</Box>
</Flex>
<Box my="1em">
<WeaponSelector value={weapon} onChange={setWeapon} />
</Box>
<Wrap justify="space-between">
<Box>
<Box position="sticky" top={0}>
{weapon && (
<EditableBuilds
build={build}
otherBuild={otherBuild}
setBuild={otherFocused ? setOtherBuild : setBuild}
showOther={showOther}
setShowOther={setShowOther}
changeFocus={() => {
setOtherFocused(!otherFocused);
}}
otherFocused={otherFocused}
bonusAp={bonusAp}
setBonusAp={setBonusAp}
otherBonusAp={otherBonusAp}
setOtherBonusAp={setOtherBonusAp}
lde={lde}
setLde={setLde}
otherLde={otherLde}
setOtherLde={setOtherLde}
/>
)}
</Box>
</Box>
<Box>
<Button
leftIcon={<FiSettings />}
onClick={() => setShowSettings(!showSettings)}
my="1rem"
>
{showSettings ? t`Hide settings` : t`Show settings`}
</Button>
{showSettings && (
<Box my="1em">
<Switch
id="show-all"
color="blue"
isChecked={hideExtra}
onChange={() => setHideExtra(!hideExtra)}
mr="0.5em"
/>
<FormLabel htmlFor="show-all">
{t`Hide stats at base value`}
</FormLabel>
<Box>
<Switch
id="show-not-actual"
color="blue"
isChecked={showNotActualProgress}
onChange={() =>
setShowNotActualProgress(!showNotActualProgress)
}
mr="0.5em"
/>
<FormLabel htmlFor="show-not-actual">
{t`Progress bars show progress to max value`}
</FormLabel>
</Box>
<Box>
<Switch
id="charts-zero"
color="blue"
isChecked={startChartsAtZero}
onChange={() => setStartChartsAtZero(!startChartsAtZero)}
mr="0.5em"
/>
<FormLabel htmlFor="charts-zero">
{t`Start charts Y axis from zero`}
</FormLabel>
</Box>
</Box>
)}
<Box m="1rem" w={["95%", null, "30rem"]}>
<BuildStats
build={build}
explanations={explanations}
otherExplanations={showOther ? otherExplanations : undefined}
hideExtra={hideExtra}
showNotActualProgress={showNotActualProgress}
startChartsAtZero={startChartsAtZero}
/>
</Box>
</Box>
</Wrap>
</>
);
function parseQuery() {
const query = router.query;
const weapon = isWeapon(query.weapon) ? query.weapon : "Splattershot Jr.";
const headAbilities =
typeof query.head === "string" &&
isAbilityArray(query.head.split(","), "HEAD")
? query.head.split(",")
: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"];
const clothingAbilities =
typeof query.clothing === "string" &&
isAbilityArray(query.clothing.split(","), "CLOTHING")
? query.clothing.split(",")
: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"];
const shoesAbilities =
typeof query.shoes === "string" &&
isAbilityArray(query.shoes.split(","), "SHOES")
? query.shoes.split(",")
: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"];
setWeapon(weapon as string);
setBuild({
headAbilities: headAbilities as AbilityOrUnknown[],
clothingAbilities: clothingAbilities as AbilityOrUnknown[],
shoesAbilities: shoesAbilities as AbilityOrUnknown[],
});
}
};
export default BuildAnalyzerPage;