From f0fc23712ad18c68ea08b3ad926e15232d1e03af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Mon, 8 Jul 2024 19:59:15 -0500
Subject: [PATCH] feat: safe sort
---
.../tank-performance/components/Header.tsx | 13 +++---
.../tank-performance/components/Info.tsx | 2 +-
.../tank-performance/components/RowLoader.tsx | 2 +-
.../tank-performance/components/Tanks.tsx | 7 +++-
.../components/TierBreakdown.tsx | 2 +-
src/app/tools/tank-performance/layout.tsx | 11 +++++
src/app/tools/tank-performance/page.tsx | 15 +++----
src/core/blitzkit/filterTank.ts | 1 +
src/core/zustand/createNextSafeStore.tsx | 6 +--
.../{tankFilters.tsx => tankFilters.ts} | 0
src/stores/tankPerformanceSort.ts | 41 -------------------
src/stores/tankPerformanceSort/constants.ts | 21 ++++++++++
src/stores/tankPerformanceSort/index.ts | 17 ++++++++
13 files changed, 73 insertions(+), 65 deletions(-)
create mode 100644 src/app/tools/tank-performance/layout.tsx
rename src/stores/{tankFilters.tsx => tankFilters.ts} (100%)
delete mode 100644 src/stores/tankPerformanceSort.ts
create mode 100644 src/stores/tankPerformanceSort/constants.ts
create mode 100644 src/stores/tankPerformanceSort/index.ts
diff --git a/src/app/tools/tank-performance/components/Header.tsx b/src/app/tools/tank-performance/components/Header.tsx
index 44a77b328..fd2aade88 100644
--- a/src/app/tools/tank-performance/components/Header.tsx
+++ b/src/app/tools/tank-performance/components/Header.tsx
@@ -6,14 +6,15 @@ import {
CaretUpIcon,
} from '@radix-ui/react-icons';
import { Flex, IconButton, Table } from '@radix-ui/themes';
+import * as TankPerformanceSort from '../../../../stores/tankPerformanceSort';
import {
tankPerformanceSortTypeNames,
tankPerformanceSortTypeNamesArray,
- useTankPerformanceSort,
-} from '../../../../stores/tankPerformanceSort';
+} from '../../../../stores/tankPerformanceSort/constants';
export function Header() {
- const sort = useTankPerformanceSort();
+ const sort = TankPerformanceSort.use();
+ const store = TankPerformanceSort.useStore();
return (
@@ -40,11 +41,9 @@ export function Header() {
highContrast={!isSelected}
onClick={() => {
if (isSelected) {
- useTankPerformanceSort.setState({
- direction: -sort.direction as 1 | -1,
- });
+ store.setState({ direction: -sort.direction as 1 | -1 });
} else {
- useTankPerformanceSort.setState({ type, direction: -1 });
+ store.setState({ type, direction: -1 });
}
}}
>
diff --git a/src/app/tools/tank-performance/components/Info.tsx b/src/app/tools/tank-performance/components/Info.tsx
index 6aa6c82f0..2e9859c25 100644
--- a/src/app/tools/tank-performance/components/Info.tsx
+++ b/src/app/tools/tank-performance/components/Info.tsx
@@ -20,7 +20,7 @@ export function Info() {
Career stats based on {numberFormat.format(Math.round(samples))}{' '}
- players with at least 5K career battles and 1 battle in the past 30
+ players with at least 5K career battles and 1 battle in the past 120
days; updated daily.
diff --git a/src/app/tools/tank-performance/components/RowLoader.tsx b/src/app/tools/tank-performance/components/RowLoader.tsx
index 418e93d52..bf0b9ad6e 100644
--- a/src/app/tools/tank-performance/components/RowLoader.tsx
+++ b/src/app/tools/tank-performance/components/RowLoader.tsx
@@ -2,7 +2,7 @@ import { Skeleton, Table } from '@radix-ui/themes';
import { times } from 'lodash';
import { memo, useRef } from 'react';
import { useIntersection } from '../../../../hooks/useIntersection';
-import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort';
+import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort/constants';
interface RowLoaderProps {
onIntersection?: () => void;
diff --git a/src/app/tools/tank-performance/components/Tanks.tsx b/src/app/tools/tank-performance/components/Tanks.tsx
index 25af192a6..62172989c 100644
--- a/src/app/tools/tank-performance/components/Tanks.tsx
+++ b/src/app/tools/tank-performance/components/Tanks.tsx
@@ -7,7 +7,7 @@ import { averageDefinitionsArray } from '../../../../core/blitzkit/averageDefini
import { filterTank } from '../../../../core/blitzkit/filterTank';
import { tankDefinitions } from '../../../../core/blitzkit/tankDefinitions';
import * as TankFilters from '../../../../stores/tankFilters';
-import { useTankPerformanceSort } from '../../../../stores/tankPerformanceSort';
+import * as TankPerformanceSort from '../../../../stores/tankPerformanceSort';
import { RowLoader } from './RowLoader';
import { TankRow } from './TankRow';
import { Total } from './Total';
@@ -19,7 +19,7 @@ export function Tanks() {
const awaitedTankDefinitions = use(tankDefinitions);
const awaitedAverageDefinitionsArray = use(averageDefinitionsArray);
const filters = TankFilters.use();
- const sort = useTankPerformanceSort();
+ const sort = TankPerformanceSort.use();
const tanksSorted = useMemo(() => {
switch (sort.type) {
case 'accuracy':
@@ -126,6 +126,9 @@ export function Tanks() {
{tanks.slice(0, loadedRows).map((averages) => {
const tank = awaitedTankDefinitions[averages.id];
+
+ if (tank === undefined) return null;
+
return (
}>
diff --git a/src/app/tools/tank-performance/components/TierBreakdown.tsx b/src/app/tools/tank-performance/components/TierBreakdown.tsx
index ae851c26a..f4b9fcd34 100644
--- a/src/app/tools/tank-performance/components/TierBreakdown.tsx
+++ b/src/app/tools/tank-performance/components/TierBreakdown.tsx
@@ -33,7 +33,7 @@ export function TierBreakdown() {
data={times(10, (index) => {
const tier = (index + 1) as Tier;
const tierTanks = awaitedAverageDefinitionsArray.filter(
- ({ id }) => awaitedTankDefinitions[id].tier === tier,
+ ({ id }) => awaitedTankDefinitions[id]?.tier === tier,
);
const populations: Record = {
'AT-SPG': 0,
diff --git a/src/app/tools/tank-performance/layout.tsx b/src/app/tools/tank-performance/layout.tsx
new file mode 100644
index 000000000..8a0c5b6b2
--- /dev/null
+++ b/src/app/tools/tank-performance/layout.tsx
@@ -0,0 +1,11 @@
+import { ReactNode } from 'react';
+import * as TankFilters from '../../../stores/tankFilters';
+import * as TankPerformanceSort from '../../../stores/tankPerformanceSort';
+
+export default function Layout({ children }: { children: ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/app/tools/tank-performance/page.tsx b/src/app/tools/tank-performance/page.tsx
index 1e4f6fdcc..4bb880d81 100644
--- a/src/app/tools/tank-performance/page.tsx
+++ b/src/app/tools/tank-performance/page.tsx
@@ -1,5 +1,4 @@
import PageWrapper from '../../../components/PageWrapper';
-import * as TankFilters from '../../../stores/tankFilters';
import { FilterControl } from '../tankopedia/components/FilterControl';
import { Info } from './components/Info';
import { TankTable } from './components/Table';
@@ -7,13 +6,11 @@ import { TierBreakdown } from './components/TierBreakdown';
export default function Page() {
return (
-
-
-
-
-
-
-
-
+
+
+
+
+
+
);
}
diff --git a/src/core/blitzkit/filterTank.ts b/src/core/blitzkit/filterTank.ts
index 5351b09ee..e25e36fd1 100644
--- a/src/core/blitzkit/filterTank.ts
+++ b/src/core/blitzkit/filterTank.ts
@@ -1,3 +1,4 @@
+import { TankFilters } from '../../stores/tankFilters';
import { TankDefinition } from './tankDefinitions';
export function filterTank(filters: TankFilters, tank: TankDefinition) {
diff --git a/src/core/zustand/createNextSafeStore.tsx b/src/core/zustand/createNextSafeStore.tsx
index ec871f1d2..0fb75f015 100644
--- a/src/core/zustand/createNextSafeStore.tsx
+++ b/src/core/zustand/createNextSafeStore.tsx
@@ -42,9 +42,9 @@ export function createNextSafeStore(initialState: Type) {
function useStore() {
const store = useContext(Context);
- if (!store) {
- throw new Error('useStoreContext must be used within Provider');
- }
+
+ if (!store) throw new Error('useStore must be used within Provider');
+
return store;
}
diff --git a/src/stores/tankFilters.tsx b/src/stores/tankFilters.ts
similarity index 100%
rename from src/stores/tankFilters.tsx
rename to src/stores/tankFilters.ts
diff --git a/src/stores/tankPerformanceSort.ts b/src/stores/tankPerformanceSort.ts
deleted file mode 100644
index 28b245245..000000000
--- a/src/stores/tankPerformanceSort.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { produce } from 'immer';
-import { create } from 'zustand';
-
-export const tankPerformanceSortTypeNames = {
- winrate: 'Winrate',
- players: 'Players (30d)',
- battles: 'Battles (career)',
- damage: 'Damage',
- survival: 'Survival',
- xp: 'XP',
- kills: 'Kills',
- spots: 'Spots',
- accuracy: 'Accuracy',
- shots: 'Shots',
- hits: 'Hits',
- damageRatio: 'Dmg. ratio',
- damageTaken: 'Dmg. taken',
- capturePoints: 'Cap points',
-} as const;
-
-export const tankPerformanceSortTypeNamesArray = Object.keys(
- tankPerformanceSortTypeNames,
-) as TankPerformanceSortType[];
-
-type TankPerformanceSortType = keyof typeof tankPerformanceSortTypeNames;
-
-export interface TankPerformanceSort {
- type: TankPerformanceSortType;
- direction: -1 | 1;
-}
-
-export const useTankPerformanceSort = create()(() => ({
- type: 'winrate',
- direction: -1,
-}));
-
-export function mutateTankPerformanceSort(
- recipe: (draft: TankPerformanceSort) => void,
-) {
- useTankPerformanceSort.setState(produce(recipe));
-}
diff --git a/src/stores/tankPerformanceSort/constants.ts b/src/stores/tankPerformanceSort/constants.ts
new file mode 100644
index 000000000..461fd4a5c
--- /dev/null
+++ b/src/stores/tankPerformanceSort/constants.ts
@@ -0,0 +1,21 @@
+import { TankPerformanceSortType } from '.';
+
+export const tankPerformanceSortTypeNames = {
+ winrate: 'Winrate',
+ players: 'Players (30d)',
+ battles: 'Battles (career)',
+ damage: 'Damage',
+ survival: 'Survival',
+ xp: 'XP',
+ kills: 'Kills',
+ spots: 'Spots',
+ accuracy: 'Accuracy',
+ shots: 'Shots',
+ hits: 'Hits',
+ damageRatio: 'Dmg. ratio',
+ damageTaken: 'Dmg. taken',
+ capturePoints: 'Cap points',
+} as const;
+export const tankPerformanceSortTypeNamesArray = Object.keys(
+ tankPerformanceSortTypeNames,
+) as TankPerformanceSortType[];
diff --git a/src/stores/tankPerformanceSort/index.ts b/src/stores/tankPerformanceSort/index.ts
new file mode 100644
index 000000000..717815e57
--- /dev/null
+++ b/src/stores/tankPerformanceSort/index.ts
@@ -0,0 +1,17 @@
+'use client';
+
+import { createNextSafeStore } from '../../core/zustand/createNextSafeStore';
+import { tankPerformanceSortTypeNames } from './constants';
+
+export type TankPerformanceSortType = keyof typeof tankPerformanceSortTypeNames;
+
+export interface TankPerformanceSort {
+ type: TankPerformanceSortType;
+ direction: -1 | 1;
+}
+
+export const { Provider, use, useMutation, useStore } =
+ createNextSafeStore({
+ type: 'winrate',
+ direction: -1,
+ });