From 6ebced6f01747f42c4f14262a18c0364e0966589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sun, 28 Jul 2024 13:32:52 -0500 Subject: [PATCH] feat: segmented control mode --- bun.lockb | Bin 411380 -> 411748 bytes package.json | 4 +- .../[id]/components/Model/TankSandbox.tsx | 23 +- .../components/Model/components/Options.tsx | 56 +++-- .../components/Model/components/TankModel.tsx | 32 +-- .../[id]/components/QuickInputs/index.tsx | 225 +++++++----------- .../Armor/components/CoreArmorScene.tsx | 19 +- .../components/StaticArmorScene.tsx | 20 +- src/stores/tankopediaPersistent/constants.ts | 5 + src/stores/tankopediaPersistent/index.ts | 11 +- tsconfig.json | 2 +- 11 files changed, 160 insertions(+), 237 deletions(-) diff --git a/bun.lockb b/bun.lockb index dbab5e111ff861c02fc0e4b5afa6f45bc98067a4..8d88af90495bc2616ebcedcdc12ae8a47056094f 100644 GIT binary patch delta 17138 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 Y>Ic04X9fRvh5GB3Pq2ESSCs|-4_BOh{Qv*} delta 16805 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 state.armorMode); + const display = TankopediaPersistent.use((state) => state.display); function handlePointerDown() { window.addEventListener('pointermove', handlePointerMove); @@ -123,6 +124,20 @@ export function TankSandbox() { }); }, [protagonist.gun, protagonist.turret]); + useEffect(() => { + if (display !== TankopediaDisplay.DynamicArmor) { + mutateTankopediaEphemeral((draft) => { + draft.shot = undefined; + }); + } + + if (display !== TankopediaDisplay.StaticArmor) { + mutateTankopediaEphemeral((draft) => { + draft.highlightArmor = undefined; + }); + } + }, [display]); + return ( - + {display !== TankopediaDisplay.StaticArmor && } {/* idk why the shot display doesn't work without suspense here lol */} }> - {armorMode === 'blitz' && } - {armorMode === 'static' && ( + {display === TankopediaDisplay.DynamicArmor && } + {display === TankopediaDisplay.StaticArmor && ( )} 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 cac44b1b1..46d1f6d53 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx @@ -14,8 +14,8 @@ import { Heading, IconButton, Popover, + SegmentedControl, Strong, - Switch, Tabs, Text, } from '@radix-ui/themes'; @@ -25,6 +25,7 @@ import { SmallTankIcon } from '../../../../../../../components/SmallTankIcon'; import { resolveNearPenetration } from '../../../../../../../core/blitz/resolveNearPenetration'; import { resolvePenetrationCoefficient } from '../../../../../../../core/blitz/resolvePenetrationCoefficient'; import { asset } from '../../../../../../../core/blitzkit/asset'; +import { imgur } from '../../../../../../../core/blitzkit/imgur'; import { Pose, poseEvent } from '../../../../../../../core/blitzkit/pose'; import { SHELL_NAMES, @@ -38,6 +39,7 @@ import * as App from '../../../../../../../stores/app'; import * as Duel from '../../../../../../../stores/duel'; import * as TankopediaEphemeral from '../../../../../../../stores/tankopediaEphemeral'; import * as TankopediaPersistent from '../../../../../../../stores/tankopediaPersistent'; +import { TankopediaDisplay } from '../../../../../../../stores/tankopediaPersistent/constants'; import { TankSearch } from '../../../../components/TankSearch'; import { ENVIRONMENTS } from '../../Lighting'; import { RotationInputs } from '../../QuickInputs'; @@ -45,9 +47,10 @@ import { RotationInputs } from '../../QuickInputs'; export function Options() { const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); const mutateTankopediaPersistent = TankopediaPersistent.useMutation(); - const modeRaw = TankopediaPersistent.use((state) => state.mode); - const [mode, setMode] = - useState('model'); + const displayRaw = TankopediaPersistent.use((state) => state.display); + const [display, setDisplay] = useState( + TankopediaDisplay.Model, + ); const isFullScreen = useFullScreen(); const showGrid = TankopediaPersistent.use( (state) => state.model.visual.showGrid, @@ -81,7 +84,7 @@ export function Options() { const hasEnhancedArmor = useEquipment(110); const antagonistUniqueGuns = uniqueGuns(antagonistTank.turrets); - useEffect(() => setMode(modeRaw), [modeRaw]); + useEffect(() => setDisplay(displayRaw), [displayRaw]); return ( <> @@ -112,7 +115,7 @@ export function Options() { - {mode === 'armor' && ( + {display === TankopediaDisplay.DynamicArmor && ( - {mode === 'armor' && ( + {display === TankopediaDisplay.DynamicArmor && ( Shooter: @@ -470,25 +473,30 @@ export function Options() { )} - { + { mutateTankopediaPersistent((draft) => { - draft.mode = draft.mode === 'armor' ? 'model' : 'armor'; + draft.display = Number(value); }); }} - mr="1" > - - - Armor - - + + + + + + + + + + + + + + + + @@ -511,7 +519,6 @@ export function Options() { - @@ -520,7 +527,7 @@ export function Options() { - {mode === 'armor' && ( + {display !== TankopediaDisplay.Model && ( <> Armor @@ -622,7 +629,6 @@ export function Options() { - {fullScreenAvailable && ( { const mutateDuel = Duel.useMutation(); @@ -38,32 +39,6 @@ export const TankModel = memo(() => { const { gltf } = useModel(protagonist.tank.id); const nodes = Object.values(gltf.nodes); - useEffect(() => { - function handleVisibility() { - if (!hullContainer.current) return; - - const state = tankopediaPersistentStore.getState(); - - hullContainer.current.visible = - state.mode === 'model' || state.armorMode === 'blitz'; - } - - const unsubscribes = [ - tankopediaPersistentStore.subscribe( - (state) => state.mode, - handleVisibility, - ), - tankopediaPersistentStore.subscribe( - (state) => state.armorMode, - handleVisibility, - ), - ]; - - handleVisibility(); - - return () => unsubscribes.forEach((unsubscribe) => unsubscribe()); - }, []); - return ( {nodes.map((node) => { @@ -92,7 +67,8 @@ export const TankModel = memo(() => { function onPointerDown(event: ThreeEvent) { if ( isTrack && - tankopediaPersistentStore.getState().mode === 'model' + tankopediaPersistentStore.getState().display === + TankopediaDisplay.Model ) { position.set(event.clientX, event.clientY); event.stopPropagation(); diff --git a/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx b/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx index bc29f25e2..3c04fd8e7 100644 --- a/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx @@ -1,5 +1,5 @@ import { HeightIcon, WidthIcon } from '@radix-ui/react-icons'; -import { Box, Flex, TextField } from '@radix-ui/themes'; +import { Flex, TextField } from '@radix-ui/themes'; import { use, useEffect, useRef } from 'react'; import { degToRad, radToDeg } from 'three/src/math/MathUtils'; import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; @@ -27,8 +27,6 @@ export function RotationInputs() { const initialGunPitch = tankModelDefinition.turretRotation?.pitch ?? 0; const hasImprovedVerticalStabilizer = useEquipment(122); const isFullScreen = useFullScreen(); - const mode = TankopediaPersistent.use((state) => state.mode); - const armorMode = TankopediaPersistent.use((state) => state.armorMode); const mutateTankopediaPersistent = TankopediaPersistent.useMutation(); useEffect(() => { @@ -61,9 +59,7 @@ export function RotationInputs() { return ( - - { - const value = Number(yawInput.current!.value); - if (isNaN(value)) { - yawInput.current!.value = radToDeg(protagonist.yaw).toFixed(1); - return; - } - const [pitch, yaw] = applyPitchYawLimits( - protagonist.pitch, - degToRad(value), - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - ); - modelTransformEvent.emit({ pitch, yaw }); - mutateDuel((state) => { - state.protagonist.pitch = pitch; - state.protagonist.yaw = yaw; - }); + { + const value = Number(yawInput.current!.value); + if (isNaN(value)) { yawInput.current!.value = radToDeg(protagonist.yaw).toFixed(1); - }} - onKeyDown={(event) => { - if (event.key === 'Enter') { - yawInput.current?.blur(); - } - }} - onFocus={() => yawInput.current?.focus()} - ref={yawInput} - > - - - - ° - - - { + state.protagonist.pitch = pitch; + state.protagonist.yaw = yaw; + }); + yawInput.current!.value = radToDeg(protagonist.yaw).toFixed(1); + }} + onKeyDown={(event) => { + if (event.key === 'Enter') { + yawInput.current?.blur(); + } + }} + onFocus={() => yawInput.current?.focus()} + ref={yawInput} + > + { - const value = Number(pitchInput.current!.value); - if (isNaN(value)) { - pitchInput.current!.value = ( - -radToDeg(protagonist.pitch) + initialGunPitch - ).toFixed(1); - return; - } - const [pitch, yaw] = applyPitchYawLimits( - degToRad(-value + initialGunPitch), - protagonist.yaw, - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - ); - modelTransformEvent.emit({ pitch, yaw }); - mutateDuel((state) => { - state.protagonist.pitch = pitch; - state.protagonist.yaw = yaw; - }); + > + + + ° + + + { + const value = Number(pitchInput.current!.value); + if (isNaN(value)) { pitchInput.current!.value = ( -radToDeg(protagonist.pitch) + initialGunPitch ).toFixed(1); - }} - onKeyDown={(event) => { - if (event.key === 'Enter') { - pitchInput.current?.blur(); - } - }} - onFocus={() => pitchInput.current?.focus()} - ref={pitchInput} - > - - - - - ° - - - - - - { + state.protagonist.pitch = pitch; + state.protagonist.yaw = yaw; + }); + pitchInput.current!.value = ( + -radToDeg(protagonist.pitch) + initialGunPitch + ).toFixed(1); + }} + onKeyDown={(event) => { + if (event.key === 'Enter') { + pitchInput.current?.blur(); + } + }} + onFocus={() => pitchInput.current?.focus()} + ref={pitchInput} + > + { - mutateTankopediaPersistent((draft) => { - draft.armorMode = 'blitz'; - }); - }} - /> - { - mutateTankopediaPersistent((draft) => { - draft.armorMode = 'static'; - }); + userSelect: 'none', }} > - - - - + + + + ° + + ); } diff --git a/src/components/Armor/components/CoreArmorScene.tsx b/src/components/Armor/components/CoreArmorScene.tsx index 06e9b7cae..377294a63 100644 --- a/src/components/Armor/components/CoreArmorScene.tsx +++ b/src/components/Armor/components/CoreArmorScene.tsx @@ -1,4 +1,4 @@ -import { memo, useEffect, useRef } from 'react'; +import { memo, useRef } from 'react'; import { Group } from 'three'; import { correctZYTuple } from '../../../core/blitz/correctZYTuple'; import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId'; @@ -31,26 +31,11 @@ export const CoreArmorScene = memo(() => { const turretOrigin = correctZYTuple(tankModelDefinition.turretOrigin); const gunOrigin = correctZYTuple(turretModelDefinition.gunOrigin); const tankopediaPersistentStore = TankopediaPersistent.useStore(); - const initialTankopediaState = tankopediaPersistentStore.getState(); useTankTransform(protagonist, turretContainer, gunContainer); - useEffect(() => { - const unsubscribe = tankopediaPersistentStore.subscribe( - (state) => state.mode, - (mode) => { - if (wrapper.current) wrapper.current.visible = mode === 'armor'; - }, - ); - - return unsubscribe; - }); - return ( - + {armorNodes.map((node) => { const isHull = node.name.startsWith('hull_'); diff --git a/src/components/StaticArmor/components/StaticArmorScene.tsx b/src/components/StaticArmor/components/StaticArmorScene.tsx index 299dd5193..6e2c481f0 100644 --- a/src/components/StaticArmor/components/StaticArmorScene.tsx +++ b/src/components/StaticArmor/components/StaticArmorScene.tsx @@ -1,4 +1,4 @@ -import { memo, useEffect, useMemo, useRef } from 'react'; +import { memo, useMemo, useRef } from 'react'; import { Group, Plane, Scene, Vector3 } from 'three'; import { correctZYTuple } from '../../../core/blitz/correctZYTuple'; import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId'; @@ -9,7 +9,6 @@ import { useModel } from '../../../hooks/useModel'; import { useModelDefinitions } from '../../../hooks/useModelDefinitions'; import { useTankTransform } from '../../../hooks/useTankTransform'; import * as Duel from '../../../stores/duel'; -import * as TankopediaPersistent from '../../../stores/tankopediaPersistent'; import { ModelTankWrapper } from '../../Armor/components/ModelTankWrapper'; import { ArmorType } from '../../Armor/components/SpacedArmorScene'; import { SpacedArmorSceneComponent } from '../../Armor/components/SpacedArmorSceneComponent'; @@ -27,7 +26,6 @@ export interface ThicknessRange { export const StaticArmorScene = memo( ({ scene, awaitedTankDefinitions }) => { const wrapper = useRef(null); - const tankopediaPersistentStore = TankopediaPersistent.useStore(); const awaitedTankModelDefinitions = useModelDefinitions(); const turretContainer = useRef(null); const gunContainer = useRef(null); @@ -98,22 +96,6 @@ export const StaticArmorScene = memo( useTankTransform(protagonist, turretContainer, gunContainer); - useEffect(() => { - function handleMode(mode: TankopediaPersistent.TankopediaMode) { - if (!wrapper.current) return; - wrapper.current.visible = mode === 'armor'; - } - - const unsubscribe = tankopediaPersistentStore.subscribe( - (state) => state.mode, - handleMode, - ); - - handleMode(tankopediaPersistentStore.getState().mode); - - return unsubscribe; - }, []); - return ( diff --git a/src/stores/tankopediaPersistent/constants.ts b/src/stores/tankopediaPersistent/constants.ts index d0e039418..10d61cd54 100644 --- a/src/stores/tankopediaPersistent/constants.ts +++ b/src/stores/tankopediaPersistent/constants.ts @@ -58,3 +58,8 @@ export const SORT_NAMES = { 'maneuverability.weight': 'weight', 'maneuverability.traverseSpeed': 'traverse speed', } as const; +export enum TankopediaDisplay { + Model, + DynamicArmor, + StaticArmor, +} diff --git a/src/stores/tankopediaPersistent/index.ts b/src/stores/tankopediaPersistent/index.ts index 40b90dccc..3c036d878 100644 --- a/src/stores/tankopediaPersistent/index.ts +++ b/src/stores/tankopediaPersistent/index.ts @@ -7,14 +7,11 @@ import { ENVIRONMENTS } from '../../app/tools/tankopedia/[id]/components/Lightin import { TankClass, TreeType } from '../../components/Tanks'; import { Tier } from '../../core/blitzkit/tankDefinitions'; import { createNextSafeStore } from '../../core/zustand/createNextSafeStore'; -import { SORT_NAMES } from './constants'; +import { SORT_NAMES, TankopediaDisplay } from './constants'; export type TankopediaSortBy = keyof typeof SORT_NAMES; export type TankopediaSortDirection = 'ascending' | 'descending'; export type TankopediaTestTankDisplay = 'include' | 'exclude' | 'only'; -export type TankopediaMode = 'model' | 'armor'; -export type TankopediaArmorMode = 'blitz' | 'static'; - export interface TankopediaPersistent { model: { visual: { @@ -39,8 +36,7 @@ export interface TankopediaPersistent { test: TankopediaTestTankDisplay; page: number; }; - mode: TankopediaMode; - armorMode: TankopediaArmorMode; + display: TankopediaDisplay; } export const { Provider, use, useMutation, useStore } = createNextSafeStore( @@ -71,8 +67,7 @@ export const { Provider, use, useMutation, useStore } = createNextSafeStore( test: 'include', page: 0, }, - mode: 'model', - armorMode: 'blitz', + display: TankopediaDisplay.Model, })), { name: 'tankopedia', merge: (a, b) => merge(b, a) }, ), diff --git a/tsconfig.json b/tsconfig.json index c910f50ff..3cf8ab563 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,5 +21,5 @@ ] }, "include": ["src/**/*", "scripts/**/*", "dist/website/types/**/*.ts"], - "exclude": ["node_modules", "dist", "scripts"] + "exclude": ["node_modules/**/*", "dist"] }