diff --git a/src/app/tools/tankopedia/[id]/components/AntagonistBar/index.tsx b/src/app/tools/tankopedia/[id]/components/AntagonistBar/index.tsx index a60a163c3..bd3893070 100644 --- a/src/app/tools/tankopedia/[id]/components/AntagonistBar/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/AntagonistBar/index.tsx @@ -25,7 +25,7 @@ import { SHELL_NAMES, tankNamesDiacritics, } from '../../../../../../core/blitzkrieg/tankDefinitions'; -import { useTankopedia } from '../../../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../../../stores/tankopedia'; import { Duel } from '../../page'; import { SearchResults } from './components/SearchResults'; @@ -38,7 +38,7 @@ export function AntagonistBar({ duel: { antagonist }, setDuel, }: AntagonistBarProps) { - const mode = useTankopedia((state) => state.mode); + const mode = useTankopediaTemporary((state) => state.mode); const awaitedTankNamesDiacritics = use(tankNamesDiacritics); const [tab, setTab] = useState('search'); const searchInput = useRef(null); diff --git a/src/app/tools/tankopedia/[id]/components/Configure.tsx b/src/app/tools/tankopedia/[id]/components/Configure.tsx index 55a2aacaa..71d192e25 100644 --- a/src/app/tools/tankopedia/[id]/components/Configure.tsx +++ b/src/app/tools/tankopedia/[id]/components/Configure.tsx @@ -3,8 +3,9 @@ import { produce } from 'immer'; import { Dispatch, SetStateAction, use } from 'react'; import { ModuleButton } from '../../../../../components/ModuleButton'; import { equipmentDefinitions } from '../../../../../core/blitzkrieg/equipmentDefinitions'; -import mutateTankopedia, { - useTankopedia, +import { + mutateTankopediaTemporary, + useTankopediaTemporary, } from '../../../../../stores/tankopedia'; import { Duel } from '../page'; @@ -17,7 +18,9 @@ export function Configure({ duel, setDuel }: ConfigureProps) { const awaitedEquipmentDefinitions = use(equipmentDefinitions); const equipmentRows = awaitedEquipmentDefinitions.presets[duel.protagonist.tank.equipment]; - const equipmentMatrix = useTankopedia((state) => state.equipmentMatrix); + const equipmentMatrix = useTankopediaTemporary( + (state) => state.equipmentMatrix, + ); return ( @@ -97,7 +100,7 @@ export function Configure({ duel, setDuel }: ConfigureProps) { rowChild selected={equipmentMatrix[rowIndex][columnIndex] === 0} onClick={() => { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.equipmentMatrix[rowIndex][columnIndex] = 0; }); }} @@ -109,7 +112,7 @@ export function Configure({ duel, setDuel }: ConfigureProps) { rowChild selected={equipmentMatrix[rowIndex][columnIndex] === 1} onClick={() => { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.equipmentMatrix[rowIndex][columnIndex] = 1; }); }} diff --git a/src/app/tools/tankopedia/[id]/components/Control.tsx b/src/app/tools/tankopedia/[id]/components/Control.tsx index 39879f697..b869d6073 100644 --- a/src/app/tools/tankopedia/[id]/components/Control.tsx +++ b/src/app/tools/tankopedia/[id]/components/Control.tsx @@ -7,7 +7,7 @@ import { OrbitControls as OrbitControlsClass } from 'three-stdlib'; import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits'; import { modelDefinitions } from '../../../../../core/blitzkrieg/modelDefinitions'; import { Pose, poseEvent } from '../../../../../core/blitzkrieg/pose'; -import { useTankopedia } from '../../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../../stores/tankopedia'; import { Duel } from '../page'; const poseDistances: Record = { @@ -55,7 +55,7 @@ export function Controls({ duel }: ControlsProps) { camera.position.set(-4, 4, -16); orbitControls.current?.target.set(0, antagonistGunHeight / 2, 0); - const unsubscribeTankopedia = useTankopedia.subscribe( + const unsubscribeTankopedia = useTankopediaTemporary.subscribe( (state) => state.model.visual.controlsEnabled, (enabled) => { if (orbitControls.current) orbitControls.current.enabled = enabled; @@ -144,7 +144,7 @@ export function Controls({ duel }: ControlsProps) { return ( diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx index 8d5f8e83e..6c61607f3 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx @@ -7,9 +7,10 @@ import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinit import { modelTransformEvent } from '../../../../../../core/blitzkrieg/modelTransform'; import { Pose, poseEvent } from '../../../../../../core/blitzkrieg/pose'; import { theme } from '../../../../../../stitches.config'; -import mutateTankopedia, { +import { TankopediaMode, - useTankopedia, + mutateTankopediaTemporary, + useTankopediaTemporary, } from '../../../../../../stores/tankopedia'; import { Loader } from '../../../../components/Loader'; import { Duel } from '../../page'; @@ -30,7 +31,7 @@ export function TankSandbox({ duel }: TankSandboxProps) { const awaitedModelDefinitions = use(modelDefinitions); const canvasWrapper = useRef(null); const [isFullScreen, setIsFullScreen] = useState(false); - const mode = useTankopedia((state) => state.mode); + const mode = useTankopediaTemporary((state) => state.mode); const tankModelDefinition = awaitedModelDefinitions[duel.protagonist.tank.id]; const turretModelDefinition = tankModelDefinition.turrets[duel.protagonist.turret.id]; @@ -59,7 +60,7 @@ export function TankSandbox({ duel }: TankSandboxProps) { function handlePoseEvent(pose: Pose) { switch (pose) { case Pose.HullDown: { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { const [pitch, yaw] = applyPitchYawLimits( -Infinity, 0, @@ -76,7 +77,7 @@ export function TankSandbox({ duel }: TankSandboxProps) { } case Pose.FaceHug: { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { const [pitch, yaw] = applyPitchYawLimits( Infinity, 0, @@ -109,7 +110,7 @@ export function TankSandbox({ duel }: TankSandboxProps) { useEffect(() => { if (!duel.protagonist) return void 0; - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { [draft.model.physical.pitch, draft.model.physical.yaw] = applyPitchYawLimits( draft.model.physical.pitch, @@ -141,7 +142,7 @@ export function TankSandbox({ duel }: TankSandboxProps) { { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.mode = mode as TankopediaMode; }); }} diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx index 28eb16a2e..471fa7b6f 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx @@ -7,8 +7,9 @@ import { import { Button, DropdownMenu, Flex } from '@radix-ui/themes'; import { RefObject } from 'react'; import { Pose, poseEvent } from '../../../../../../../core/blitzkrieg/pose'; -import mutateTankopedia, { - useTankopedia, +import { + mutateTankopediaTemporary, + useTankopediaTemporary, } from '../../../../../../../stores/tankopedia'; interface OptionsProps { @@ -17,8 +18,10 @@ interface OptionsProps { } export function Options({ isFullScreen, canvas }: OptionsProps) { - const showGrid = useTankopedia((state) => state.model.visual.showGrid); - const greenPenetration = useTankopedia( + const showGrid = useTankopediaTemporary( + (state) => state.model.visual.showGrid, + ); + const greenPenetration = useTankopediaTemporary( (state) => state.model.visual.greenPenetration, ); const fullScreenAvailable = document.fullscreenEnabled; @@ -65,7 +68,7 @@ export function Options({ isFullScreen, canvas }: OptionsProps) { { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.visual.showGrid = checked; }); }} @@ -76,7 +79,7 @@ export function Options({ isFullScreen, canvas }: OptionsProps) { { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.visual.greenPenetration = checked; }); }} diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx index 88ee2effd..229240c39 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx @@ -15,7 +15,7 @@ import { nameToArmorId } from '../../../../../../../../../core/blitzkrieg/nameTo import { resolveArmor } from '../../../../../../../../../core/blitzkrieg/resolveThickness'; import { useArmor } from '../../../../../../../../../hooks/useArmor'; import { useModelDefinitions } from '../../../../../../../../../hooks/useModelDefinitions'; -import { useTankopedia } from '../../../../../../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../../../../../../stores/tankopedia'; import { Duel } from '../../../../../page'; interface ArmorHighlightingProps { @@ -27,7 +27,7 @@ export function ArmorHighlighting({ duel }: ArmorHighlightingProps) { const modelDefinitions = useModelDefinitions(); const turretContainer = useRef(null); const gunContainer = useRef(null); - const initialTankopediaState = useTankopedia.getState(); + const initialTankopediaState = useTankopediaTemporary.getState(); useEffect(() => { const turretOrigin = new Vector3( @@ -86,7 +86,7 @@ export function ArmorHighlighting({ duel }: ArmorHighlightingProps) { turretContainer.current?.rotation.copy(turretRotation); } - handleModelTransform(useTankopedia.getState().model.physical); + handleModelTransform(useTankopediaTemporary.getState().model.physical); modelTransformEvent.on(handleModelTransform); return () => { @@ -95,7 +95,7 @@ export function ArmorHighlighting({ duel }: ArmorHighlightingProps) { }); useEffect(() => { - const unsubscribe = useTankopedia.subscribe( + const unsubscribe = useTankopediaTemporary.subscribe( (state) => state.mode, (mode) => { if (wrapper.current) wrapper.current.visible = mode === 'armor'; diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ExternalModuleMask.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ExternalModuleMask.tsx index 43a6d1791..0bd8b95a7 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ExternalModuleMask.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ExternalModuleMask.tsx @@ -16,7 +16,7 @@ import { resolveArmor } from '../../../../../../../../../core/blitzkrieg/resolve import { useArmor } from '../../../../../../../../../hooks/useArmor'; import { useModel } from '../../../../../../../../../hooks/useModel'; import { useModelDefinitions } from '../../../../../../../../../hooks/useModelDefinitions'; -import { useTankopedia } from '../../../../../../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../../../../../../stores/tankopedia'; import { Duel } from '../../../../../page'; interface ExternalModuleMaskProps { @@ -35,7 +35,7 @@ export const ExternalModuleMask = memo(({ duel }) => { const modelDefinitions = useModelDefinitions(); const turretContainer = useRef(null); const gunContainer = useRef(null); - const initialTankopediaState = useTankopedia.getState(); + const initialTankopediaState = useTankopediaTemporary.getState(); useEffect(() => { const turretOrigin = new Vector3( @@ -94,7 +94,7 @@ export const ExternalModuleMask = memo(({ duel }) => { turretContainer.current?.rotation.copy(turretRotation); } - handleModelTransform(useTankopedia.getState().model.physical); + handleModelTransform(useTankopediaTemporary.getState().model.physical); modelTransformEvent.on(handleModelTransform); return () => { @@ -103,7 +103,7 @@ export const ExternalModuleMask = memo(({ duel }) => { }); useEffect(() => { - const unsubscribe = useTankopedia.subscribe( + const unsubscribe = useTankopediaTemporary.subscribe( (state) => state.mode, (mode) => { if (wrapper.current) wrapper.current.visible = mode === 'armor'; diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx index 28210cdc6..f554da5e7 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx @@ -16,7 +16,7 @@ import { resolveArmor } from '../../../../../../../../../core/blitzkrieg/resolve import { useArmor } from '../../../../../../../../../hooks/useArmor'; import { useModel } from '../../../../../../../../../hooks/useModel'; import { useModelDefinitions } from '../../../../../../../../../hooks/useModelDefinitions'; -import { useTankopedia } from '../../../../../../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../../../../../../stores/tankopedia'; import { Duel } from '../../../../../page'; interface SpacedArmorDepthProps { @@ -39,7 +39,7 @@ export const SpacedArmorDepth = memo(({ duel }) => { const modelDefinitions = useModelDefinitions(); const turretContainer = useRef(null); const gunContainer = useRef(null); - const initialTankopediaState = useTankopedia.getState(); + const initialTankopediaState = useTankopediaTemporary.getState(); useEffect(() => { if (!modelDefinitions) return; @@ -100,7 +100,7 @@ export const SpacedArmorDepth = memo(({ duel }) => { turretContainer.current?.rotation.copy(turretRotation); } - handleModelTransform(useTankopedia.getState().model.physical); + handleModelTransform(useTankopediaTemporary.getState().model.physical); modelTransformEvent.on(handleModelTransform); return () => { @@ -109,7 +109,7 @@ export const SpacedArmorDepth = memo(({ duel }) => { }); useEffect(() => { - const unsubscribe = useTankopedia.subscribe( + const unsubscribe = useTankopediaTemporary.subscribe( (state) => state.mode, (mode) => { if (wrapper.current) wrapper.current.visible = mode === 'armor'; diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx index e26075bba..a25ca4c9e 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx @@ -22,8 +22,9 @@ import { import { resolveJsxTree } from '../../../../../../../core/blitzkrieg/resolveJsxTree'; import { normalizeAnglePI } from '../../../../../../../core/math/normalizeAngle180'; import { useModel } from '../../../../../../../hooks/useModel'; -import mutateTankopedia, { - useTankopedia, +import { + mutateTankopediaTemporary, + useTankopediaTemporary, } from '../../../../../../../stores/tankopedia'; import { Duel } from '../../../page'; @@ -37,7 +38,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { >(undefined); const canvas = useThree((state) => state.gl.domElement); - const physical = useTankopedia((state) => state.model.physical); + const physical = useTankopediaTemporary((state) => state.model.physical); const hullContainer = useRef(null); const turretContainer = useRef(null); const gunContainer = useRef(null); @@ -136,7 +137,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { event.stopPropagation(); if (isTrack) { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.visual.controlsEnabled = false; }); @@ -158,7 +159,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { material.normalMap?.offset.add(offset); } function handlePointerUp() { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.visual.controlsEnabled = true; }); window.removeEventListener('pointermove', handlePointerMove); @@ -200,7 +201,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { yaw = physical.yaw; pitch = physical.pitch; - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.visual.controlsEnabled = false; }); window.addEventListener('pointermove', handlePointerMove); @@ -217,7 +218,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { modelTransformEvent.emit({ pitch, yaw }); } function handlePointerUp() { - mutateTankopedia((state) => { + mutateTankopediaTemporary((state) => { state.model.visual.controlsEnabled = true; state.model.physical.pitch = normalizeAnglePI(pitch); state.model.physical.yaw = normalizeAnglePI(yaw); @@ -262,7 +263,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { function handlePointerDown(event: ThreeEvent) { event.stopPropagation(); - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.visual.controlsEnabled = false; }); pitch = physical.pitch; @@ -280,7 +281,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { modelTransformEvent.emit({ pitch, yaw }); } function handlePointerUp() { - mutateTankopedia((state) => { + mutateTankopediaTemporary((state) => { state.model.visual.controlsEnabled = true; state.model.physical.pitch = normalizeAnglePI(pitch); state.model.physical.yaw = normalizeAnglePI(yaw); diff --git a/src/app/tools/tankopedia/[id]/components/RotationInputs.tsx b/src/app/tools/tankopedia/[id]/components/RotationInputs.tsx index 180f441e9..8a6bcfcfa 100644 --- a/src/app/tools/tankopedia/[id]/components/RotationInputs.tsx +++ b/src/app/tools/tankopedia/[id]/components/RotationInputs.tsx @@ -3,8 +3,9 @@ import { use, useEffect, useRef } from 'react'; import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits'; import { modelDefinitions } from '../../../../../core/blitzkrieg/modelDefinitions'; import { modelTransformEvent } from '../../../../../core/blitzkrieg/modelTransform'; -import mutateTankopedia, { - useTankopedia, +import { + mutateTankopediaTemporary, + useTankopediaTemporary, } from '../../../../../stores/tankopedia'; import { Duel } from '../page'; @@ -13,7 +14,7 @@ interface RotationInputsProps { } export function RotationInputs({ duel: { protagonist } }: RotationInputsProps) { - const physical = useTankopedia((state) => state.model.physical); + const physical = useTankopediaTemporary((state) => state.model.physical); const awaitedModelDefinitions = use(modelDefinitions); const turretYawInput = useRef(null); const gunPitchInput = useRef(null); @@ -67,7 +68,7 @@ export function RotationInputs({ duel: { protagonist } }: RotationInputsProps) { turretModelDefinition.yaw, ); modelTransformEvent.emit({ pitch, yaw }); - mutateTankopedia((state) => { + mutateTankopediaTemporary((state) => { state.model.physical.pitch = pitch; state.model.physical.yaw = yaw; }); @@ -103,7 +104,7 @@ export function RotationInputs({ duel: { protagonist } }: RotationInputsProps) { turretModelDefinition.yaw, ); modelTransformEvent.emit({ pitch, yaw }); - mutateTankopedia((state) => { + mutateTankopediaTemporary((state) => { state.model.physical.pitch = pitch; state.model.physical.yaw = yaw; }); diff --git a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx index dc9f36c03..527254d2c 100644 --- a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx +++ b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx @@ -1,9 +1,11 @@ import { Color } from 'three'; import InfiniteGridHelper from '../../../../../components/InfiniteGridHelper'; -import { useTankopedia } from '../../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../../stores/tankopedia'; export function SceneProps() { - const showGrid = useTankopedia((state) => state.model.visual.showGrid); + const showGrid = useTankopediaTemporary( + (state) => state.model.visual.showGrid, + ); if (!showGrid) return null; diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index b6bf87f56..80f79acd3 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -5,7 +5,10 @@ import { produce } from 'immer'; import { use, useEffect, useState } from 'react'; import PageWrapper from '../../../../components/PageWrapper'; import { tankDefinitions } from '../../../../core/blitzkrieg/tankDefinitions'; -import mutateTankopedia, { DuelMember } from '../../../../stores/tankopedia'; +import { + DuelMember, + mutateTankopediaTemporary, +} from '../../../../stores/tankopedia'; import { AntagonistBar } from './components/AntagonistBar'; import { Configure } from './components/Configure'; import { TankSandbox } from './components/Model/TankSandbox'; @@ -35,7 +38,7 @@ export default function Page({ params }: { params: { id: string } }) { }); useEffect(() => { - mutateTankopedia((draft) => { + mutateTankopediaTemporary((draft) => { draft.model.physical.yaw = 0; draft.model.physical.pitch = 0; draft.mode = 'model'; diff --git a/src/app/tools/tankopedia/components/Options/index.tsx b/src/app/tools/tankopedia/components/Options/index.tsx index 39e4c71f3..a44979bd8 100644 --- a/src/app/tools/tankopedia/components/Options/index.tsx +++ b/src/app/tools/tankopedia/components/Options/index.tsx @@ -16,15 +16,15 @@ import { TIERS, TIER_ROMAN_NUMERALS, } from '../../../../../core/blitzkrieg/tankDefinitions'; -import mutateTankopedia, { +import mutateTankopediaPersistent, { TankopediaTestTankDisplay, - useTankopedia, + useTankopediaPersistent, } from '../../../../../stores/tankopedia'; import * as styles from './index.css'; export function Options() { const nations = use(NATIONS); - const filters = useTankopedia((state) => state.filters); + const filters = useTankopediaPersistent((state) => state.filters); return ( @@ -32,13 +32,14 @@ export function Options() { @@ -41,15 +42,15 @@ export function PageTurner({ max={Math.floor(searchedList.length / tanksPerPage) + 1} style={{ width: 64, textAlign: 'center' }} onBlur={(event) => { - setPage( - Math.max( + mutateTankopediaPersistent((draft) => { + draft.filters.page = Math.max( 0, Math.min( Math.floor(searchedList.length / tanksPerPage), event.target.valueAsNumber - 1, ), - ), - ); + ); + }); }} onKeyDown={(event) => { if (event.key === 'Enter') { @@ -64,11 +65,14 @@ export function PageTurner({ diff --git a/src/app/tools/tankopedia/page.tsx b/src/app/tools/tankopedia/page.tsx index 4c85183f1..cafc0ed3c 100644 --- a/src/app/tools/tankopedia/page.tsx +++ b/src/app/tools/tankopedia/page.tsx @@ -26,10 +26,10 @@ import { } from '../../../core/blitzkrieg/tankDefinitions'; import { tankIcon } from '../../../core/blitzkrieg/tankIcon'; import { theme } from '../../../stitches.config'; -import mutateTankopedia, { +import mutateTankopediaPersistent, { TankopediaSortBy, TankopediaSortDirection, - useTankopedia, + useTankopediaPersistent, } from '../../../stores/tankopedia'; import { Options } from './components/Options'; import { PageTurner } from './components/PageTurner'; @@ -38,8 +38,8 @@ import * as styles from './page.css'; const TANKS_PER_PAGE = 3 * 2 ** 3; export default function Page() { - const filters = useTankopedia((state) => state.filters); - const sort = useTankopedia((state) => state.sort); + const filters = useTankopediaPersistent((state) => state.filters); + const sort = useTankopediaPersistent((state) => state.sort); const awaitedTanks = use(tanksDefinitionsArray); const input = useRef(null); const searchableTanks = useMemo( @@ -80,7 +80,7 @@ export default function Page() { [filters, sort], ); const [searchedList, setSearchedList] = useState(searchableTanks); - const [page, setPage] = useState(0); + const page = useTankopediaPersistent((state) => state.filters.page); useEffect(() => { setSearchedList(searchableTanks); @@ -88,12 +88,12 @@ export default function Page() { }, [searchableTanks]); useEffect(() => { - setPage( - Math.min( + mutateTankopediaPersistent((draft) => { + draft.filters.page = Math.min( Math.max(0, page), Math.ceil(searchedList.length / TANKS_PER_PAGE) - 1, - ), - ); + ); + }); }, [searchedList]); return ( @@ -134,7 +134,7 @@ export default function Page() { - mutateTankopedia((draft) => { + mutateTankopediaPersistent((draft) => { draft.sort.by = value as TankopediaSortBy; }) } @@ -153,7 +153,7 @@ export default function Page() { - mutateTankopedia((draft) => { + mutateTankopediaPersistent((draft) => { draft.sort.direction = value as TankopediaSortDirection; }) } @@ -176,12 +176,7 @@ export default function Page() { - + {searchedList @@ -302,12 +297,7 @@ export default function Page() { .slice(page * TANKS_PER_PAGE, (page + 1) * TANKS_PER_PAGE)} - + ); diff --git a/src/components/ArmorMesh/components/Armor/index.tsx b/src/components/ArmorMesh/components/Armor/index.tsx index a4c5a0358..b194c32cd 100644 --- a/src/components/ArmorMesh/components/Armor/index.tsx +++ b/src/components/ArmorMesh/components/Armor/index.tsx @@ -7,7 +7,7 @@ import { Duel } from '../../../../app/tools/tankopedia/[id]/page'; import { canSplash } from '../../../../core/blitz/canSplash'; import { isExplosive } from '../../../../core/blitz/isExplosive'; import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration'; -import { useTankopedia } from '../../../../stores/tankopedia'; +import { useTankopediaTemporary } from '../../../../stores/tankopedia'; import { externalModuleMaskRenderTarget } from '../ExternalModuleMask'; import { spacedArmorDepthRenderTarget } from '../SpacedArmorDepth'; import fragmentShader from './shaders/fragment.glsl'; @@ -27,7 +27,7 @@ export function ArmorMesh({ }: ArmorMeshProps) { const camera = useThree((state) => state.camera); const { shell } = duel.antagonist; - const greenPenetration = useTankopedia( + const greenPenetration = useTankopediaTemporary( (state) => state.model.visual.greenPenetration, ); const material = useRef(null); diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index 3675861da..df37008f3 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -1,6 +1,6 @@ import { produce } from 'immer'; import { create } from 'zustand'; -import { subscribeWithSelector } from 'zustand/middleware'; +import { persist, subscribeWithSelector } from 'zustand/middleware'; import { TankType, TreeTypeString } from '../components/Tanks'; import { GunDefinition, @@ -20,7 +20,7 @@ export interface DuelMember { gun: GunDefinition; shell: ShellDefinition; } -interface Tankopedia { +interface TankopediaPersistent { sort: { by: TankopediaSortBy; direction: TankopediaSortDirection; @@ -31,7 +31,11 @@ interface Tankopedia { treeTypes: TreeTypeString[]; nations: string[]; test: TankopediaTestTankDisplay; + page: number; }; +} + +interface TankopediaTemporary { model: { physical: { yaw: number; @@ -47,19 +51,28 @@ interface Tankopedia { mode: TankopediaMode; } -export const useTankopedia = create()( - subscribeWithSelector(() => ({ - sort: { - by: 'tier', - direction: 'descending', - }, - filters: { - tiers: [], - types: [], - treeTypes: [], - nations: [], - test: 'include', - }, +export const useTankopediaPersistent = create()( + persist( + subscribeWithSelector(() => ({ + sort: { + by: 'tier', + direction: 'descending', + }, + filters: { + tiers: [], + types: [], + treeTypes: [], + nations: [], + test: 'include', + page: 0, + }, + })), + { name: 'tankopedia' }, + ), +); + +export const useTankopediaTemporary = create()( + subscribeWithSelector(() => ({ model: { physical: { yaw: 0, @@ -80,6 +93,14 @@ export const useTankopedia = create()( })), ); -export default function mutateTankopedia(recipe: (draft: Tankopedia) => void) { - useTankopedia.setState(produce(recipe)); +export default function mutateTankopediaPersistent( + recipe: (draft: TankopediaPersistent) => void, +) { + useTankopediaPersistent.setState(produce(recipe)); +} + +export function mutateTankopediaTemporary( + recipe: (draft: TankopediaTemporary) => void, +) { + useTankopediaTemporary.setState(produce(recipe)); }