From b965893bfc4279fbd4034e585dfbda072635b326 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Sat, 6 Jul 2024 20:07:46 -0500
Subject: [PATCH] feat: transition to next safe zustand
---
bun.lockb | Bin 385308 -> 385308 bytes
.../tank-performance/components/RowLoader.tsx | 3 +-
.../tank-performance/components/Tanks.tsx | 2 +-
src/app/tools/tank-performance/page.tsx | 13 ++--
.../tankopedia/components/FilterControl.tsx | 14 +++-
.../tankopedia/components/TierFilter.tsx | 11 ++-
src/app/tools/tankopedia/page.tsx | 11 ++-
src/stores/tankFilters.ts | 27 -------
src/stores/tankFilters.tsx | 73 ++++++++++++++++++
9 files changed, 109 insertions(+), 45 deletions(-)
delete mode 100644 src/stores/tankFilters.ts
create mode 100644 src/stores/tankFilters.tsx
diff --git a/bun.lockb b/bun.lockb
index 77df4ca1b8517f3965fdbb35cd343c653b7014c1..509c67288820579c1cd8c9b587b4acb38458ea85 100644
GIT binary patch
delta 27
jcmbPpNPNyA@rD-07N#xC!fzQ(+eO|oZx?yX!tn(Fn3D>o
delta 27
jcmbPpNPNyA@rD-07N#xC!fzQ3+eO|oZx?yX!tn(Fm}d&2
diff --git a/src/app/tools/tank-performance/components/RowLoader.tsx b/src/app/tools/tank-performance/components/RowLoader.tsx
index 41e5299b2..e35b0c295 100644
--- a/src/app/tools/tank-performance/components/RowLoader.tsx
+++ b/src/app/tools/tank-performance/components/RowLoader.tsx
@@ -1,5 +1,6 @@
import { Skeleton, Table } from '@radix-ui/themes';
import { times } from 'lodash';
+import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort';
export function RowLoader() {
return (
@@ -8,7 +9,7 @@ export function RowLoader() {
- {times(13, (index) => (
+ {times(tankPerformanceSortTypeNamesArray.length, (index) => (
diff --git a/src/app/tools/tank-performance/components/Tanks.tsx b/src/app/tools/tank-performance/components/Tanks.tsx
index 547a15c41..293874b36 100644
--- a/src/app/tools/tank-performance/components/Tanks.tsx
+++ b/src/app/tools/tank-performance/components/Tanks.tsx
@@ -108,7 +108,7 @@ export function Tanks() {
return tanksSorted.filter((tank) =>
filterTank(filters, awaitedTankDefinitions[tank.id]),
);
- }, [filters, tanksSorted]);
+ }, [filters, tanksSorted, sort]);
return (
diff --git a/src/app/tools/tank-performance/page.tsx b/src/app/tools/tank-performance/page.tsx
index 859dfe7b8..108dbb10c 100644
--- a/src/app/tools/tank-performance/page.tsx
+++ b/src/app/tools/tank-performance/page.tsx
@@ -1,14 +1,17 @@
import PageWrapper from '../../../components/PageWrapper';
+import { TankFiltersProvider } from '../../../stores/tankFilters';
import { FilterControl } from '../tankopedia/components/FilterControl';
import { Info } from './components/Info';
import { TankTable } from './components/Table';
export default function Page() {
return (
-
-
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/src/app/tools/tankopedia/components/FilterControl.tsx b/src/app/tools/tankopedia/components/FilterControl.tsx
index ba79cbb53..67086750a 100644
--- a/src/app/tools/tankopedia/components/FilterControl.tsx
+++ b/src/app/tools/tankopedia/components/FilterControl.tsx
@@ -15,8 +15,9 @@ import { gameDefinitions } from '../../../../core/blitzkit/gameDefinitions';
import { Tier } from '../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants';
import {
- mutateTankFilters,
useTankFilters,
+ useTankFiltersContext,
+ useTankFiltersMutation,
} from '../../../../stores/tankFilters';
interface FilterControlProps {
@@ -26,6 +27,8 @@ interface FilterControlProps {
export function FilterControl({ compact }: FilterControlProps) {
const awaitedGameDefinitions = use(gameDefinitions);
const filters = useTankFilters();
+ const mutateTankFilters = useTankFiltersMutation();
+ const tankFiltersContext = useTankFiltersContext();
return (
@@ -321,9 +324,12 @@ export function FilterControl({ compact }: FilterControlProps) {
- useTankFilters.setState(useTankFilters.getInitialState(), true)
- }
+ onClick={() => {
+ tankFiltersContext.setState(
+ tankFiltersContext.getInitialState(),
+ true,
+ );
+ }}
>
diff --git a/src/app/tools/tankopedia/components/TierFilter.tsx b/src/app/tools/tankopedia/components/TierFilter.tsx
index f13898604..074826494 100644
--- a/src/app/tools/tankopedia/components/TierFilter.tsx
+++ b/src/app/tools/tankopedia/components/TierFilter.tsx
@@ -4,8 +4,8 @@ import { memo } from 'react';
import { Tier } from '../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants';
import {
- mutateTankFilters,
useTankFilters,
+ useTankFiltersMutation,
} from '../../../../stores/tankFilters';
import { useTankopediaSort } from '../../../../stores/tankopediaSort';
@@ -13,6 +13,7 @@ export const TierFilter = memo(() => {
const tierFilter = useTankFilters((state) => state.tiers);
const sort = useTankopediaSort();
const search = useTankFilters((state) => state.search);
+ const mutateTankFilters = useTankFiltersMutation();
if (sort.by !== 'meta.none' || search) return null;
@@ -25,7 +26,7 @@ export const TierFilter = memo(() => {
>
{times(10, (index) => {
const tier = (10 - index) as Tier;
- const selected = tierFilter === tier;
+ const selected = tierFilter.includes(tier);
return (
{
highContrast
onClick={() =>
mutateTankFilters((draft) => {
- draft.tiers = tier;
+ if (draft.tiers?.includes(tier)) {
+ draft.tiers = draft.tiers?.filter((t) => t !== tier);
+ } else {
+ draft.tiers = [...(draft.tiers ?? []), tier];
+ }
})
}
>
diff --git a/src/app/tools/tankopedia/page.tsx b/src/app/tools/tankopedia/page.tsx
index 65732580d..5647d9edb 100644
--- a/src/app/tools/tankopedia/page.tsx
+++ b/src/app/tools/tankopedia/page.tsx
@@ -3,15 +3,18 @@
import { AdMidSectionResponsive } from '../../../components/AdMidSectionResponsive';
import PageWrapper from '../../../components/PageWrapper';
import { useAdExempt } from '../../../hooks/useAdExempt';
+import { TankFiltersProvider } from '../../../stores/tankFilters';
import { TankSearch } from './components/TankSearch';
export default function Page() {
const exempt = useAdExempt();
return (
-
-
- {!exempt && }
-
+
+
+
+ {!exempt && }
+
+
);
}
diff --git a/src/stores/tankFilters.ts b/src/stores/tankFilters.ts
deleted file mode 100644
index 586c2f228..000000000
--- a/src/stores/tankFilters.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { produce } from 'immer';
-import { create } from 'zustand';
-import { TankClass, TreeType } from '../components/Tanks';
-import { Tier } from '../core/blitzkit/tankDefinitions';
-
-export interface TankFilters {
- tiers: Tier[];
- nations: string[];
- classes: TankClass[];
- types: TreeType[];
- testing: 'include' | 'exclude' | 'only';
- search?: string;
- searching: boolean;
-}
-
-export const useTankFilters = create()(() => ({
- testing: 'include',
- searching: false,
- classes: [],
- nations: [],
- tiers: [],
- types: [],
-}));
-
-export function mutateTankFilters(recipe: (draft: TankFilters) => void) {
- useTankFilters.setState(produce(recipe));
-}
diff --git a/src/stores/tankFilters.tsx b/src/stores/tankFilters.tsx
new file mode 100644
index 000000000..c368391d7
--- /dev/null
+++ b/src/stores/tankFilters.tsx
@@ -0,0 +1,73 @@
+'use client';
+
+import { produce } from 'immer';
+import { createContext, ReactNode, useContext, useRef } from 'react';
+import { createStore, StoreApi, useStore } from 'zustand';
+import { TankClass, TreeType } from '../components/Tanks';
+import { Tier } from '../core/blitzkit/tankDefinitions';
+
+export interface TankFilters {
+ tiers: Tier[];
+ nations: string[];
+ classes: TankClass[];
+ types: TreeType[];
+ testing: 'include' | 'exclude' | 'only';
+ search?: string;
+ searching: boolean;
+}
+
+export const tankFiltersInitialState: TankFilters = {
+ testing: 'include',
+ searching: false,
+ classes: [],
+ nations: [],
+ tiers: [],
+ types: [],
+};
+
+const createTankFiltersStore = (
+ initialState: TankFilters = tankFiltersInitialState,
+) => createStore()(() => ({ ...initialState }));
+
+const TankFiltersContext = createContext | undefined>(
+ undefined,
+);
+
+interface TankFiltersProviderProps {
+ children: ReactNode;
+}
+
+export function TankFiltersProvider({ children }: TankFiltersProviderProps) {
+ const storeRef = useRef>();
+ if (!storeRef.current) storeRef.current = createTankFiltersStore();
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function useTankFiltersContext() {
+ const context = useContext(TankFiltersContext);
+ if (!context) {
+ throw new Error('useTankFilters must be used within TankFiltersContext');
+ }
+ return context;
+}
+
+export function useTankFilters(
+ selector: (store: TankFilters) => Type = (store) => store as Type,
+): Type {
+ const counterStoreContext = useTankFiltersContext();
+
+ return useStore(counterStoreContext, selector);
+}
+
+export function useTankFiltersMutation() {
+ const counterStoreContext = useTankFiltersContext();
+
+ return function (recipe: (draft: TankFilters) => void) {
+ counterStoreContext.setState(produce(recipe));
+ };
+}