diff --git a/packages/website/src/components/Performance/Tanks.tsx b/packages/website/src/components/Performance/Tanks.tsx index e1dfeba0d..8c095c0b0 100644 --- a/packages/website/src/components/Performance/Tanks.tsx +++ b/packages/website/src/components/Performance/Tanks.tsx @@ -1,9 +1,10 @@ import { Table } from "@radix-ui/themes"; import { times } from "lodash-es"; import { Fragment, Suspense, useEffect, useMemo, useState } from "react"; +import usePromise from "react-promise-suspense"; import { awaitableAverageDefinitions } from "../../core/awaitables/averageDefinitions"; import { awaitableTankDefinitions } from "../../core/awaitables/tankDefinitions"; -import { filterTank } from "../../core/blitzkit/filterTank"; +import { filterTanks } from "../../core/blitzkit/filterTanks"; import { Performance } from "../../stores/performance"; import { TankFilters } from "../../stores/tankFilters"; import { TankPerformanceSort } from "../../stores/tankPerformanceSort"; @@ -20,12 +21,7 @@ const [tankDefinitions, averageDefinitions] = await Promise.all([ awaitableAverageDefinitions, ]); -const averageDefinitionsArray = Object.entries(averageDefinitions.averages).map( - ([id, average]) => ({ - id: Number(id), - ...average, - }) -); +const tankList = Object.values(tankDefinitions.tanks); export function Tanks({ skeleton }: MaybeSkeletonComponentProps) { if (skeleton) { @@ -39,98 +35,109 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) { } const sort = TankPerformanceSort.use(); + const filters = TankFilters.use(); + const filteredTanks = usePromise( + () => + filterTanks(filters, tankList).then((tanks) => + tanks.filter(({ id }) => id in averageDefinitions.averages) + ), + // react-promise-suspense has awful type annotations + [filters] as any + ); + const tanksMapped = useMemo( + () => + filteredTanks.map(({ id }) => ({ + id, + ...averageDefinitions.averages[id], + })), + [filters] + ); const tanksSorted = useMemo(() => { const { playerCountPeriod } = Performance.state; switch (sort.type) { case "accuracy": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.hits / a.mu.shots - b.mu.hits / b.mu.shots) ); case "capture_points": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.capture_points / a.mu.battles - b.mu.capture_points / b.mu.battles) ); case "damage": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.damage_dealt / a.mu.battles - b.mu.damage_dealt / b.mu.battles) ); case "damage_ratio": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.damage_dealt / a.mu.damage_received - b.mu.damage_dealt / b.mu.damage_received) ); case "damage_taken": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.damage_received / a.mu.battles - b.mu.damage_received / b.mu.battles) ); case "hits": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.hits / a.mu.battles - b.mu.hits / b.mu.battles) ); case "kills": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.frags / a.mu.battles - b.mu.frags / b.mu.battles) ); case "shots": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.shots / a.mu.battles - b.mu.shots / b.mu.battles) ); case "players": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.samples[playerCountPeriod] - b.samples[playerCountPeriod]) ); case "spots": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.spotted / a.mu.battles - b.mu.spotted / b.mu.battles) ); case "survival": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.survived_battles / a.mu.battles - b.mu.survived_battles / b.mu.battles) ); case "winrate": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.wins / a.mu.battles - b.mu.wins / b.mu.battles) ); case "xp": - return averageDefinitionsArray.sort( + return tanksMapped.sort( (a, b) => sort.direction * (a.mu.xp / a.mu.battles - b.mu.xp / b.mu.battles) ); } - }, [sort]); - const filters = TankFilters.use(); - const tanks = useMemo(() => { - return tanksSorted.filter((tank) => - filterTank(filters, tankDefinitions.tanks[tank.id]) - ); }, [filters, sort]); const [loadedRows, setLoadedRows] = useState(DEFAULT_LOADED_ROWS); @@ -140,9 +147,9 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) { return (