diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx index 815df2d02..be8c5c946 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx @@ -1,16 +1,15 @@ import { imgur, ShellType } from '@blitzkit/core'; import { Button, - Dialog, Flex, IconButton, + Popover, Select, Slider, Text, TextField, } from '@radix-ui/themes'; -import { invalidate } from '@react-three/fiber'; -import { useEffect, useState, type ChangeEvent } from 'react'; +import { type ChangeEvent } from 'react'; import { Duel } from '../../../../../../stores/duel'; import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; @@ -18,17 +17,18 @@ export function CustomShellButton() { const customShell = TankopediaEphemeral.use((state) => state.customShell); const antagonistShell = Duel.use((state) => state.antagonist.shell); const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); - const [customShellDraft, setCustomShellDraft] = useState( - customShell ?? antagonistShell, - ); - - useEffect(() => { - setCustomShellDraft(customShell ?? antagonistShell); - }, [antagonistShell, customShell]); return ( - - + { + if (!open) return; + + mutateTankopediaEphemeral((draft) => { + draft.customShell = antagonistShell; + }); + }} + > + - + - - Custom shell + + {/* Custom shell */} - - - Type - { - const type = Number(value) as ShellType; - const modified = { ...customShellDraft, type }; + {customShell && ( + <> + + + Type + { + const type = Number(value) as ShellType; + const modified = { ...customShell, type }; - switch (type) { - case ShellType.AP: { - modified.normalization = 5; - modified.ricochet = 70; - break; - } - case ShellType.APCR: { - modified.normalization = 2; - modified.ricochet = 70; - break; - } - case ShellType.HEAT: - case ShellType.HE: { - modified.normalization = undefined; - modified.ricochet = undefined; - break; - } - } - - setCustomShellDraft(modified); - }} - > - - - - AP - APCR - HEAT - HE - - - - - - Caliber - ) => { - setCustomShellDraft({ - ...customShellDraft, - caliber: event.target.valueAsNumber, - }); - }} - onFocus={(event) => event.target.select()} - onKeyDown={(event) => { - if (event.key === 'Enter') { - (event.target as HTMLInputElement).blur(); - } else if (event.key === 'Escape') { - (event.target as HTMLInputElement).valueAsNumber = - customShellDraft.caliber; - (event.target as HTMLInputElement).blur(); - } - }} - > - mm - - - - - Penetration - ) => { - setCustomShellDraft({ - ...customShellDraft, - penetration: { - near: event.target.valueAsNumber, - far: event.target.valueAsNumber, - }, - }); - }} - onFocus={(event) => event.target.select()} - onKeyDown={(event) => { - if (event.key === 'Enter') { - (event.target as HTMLInputElement).blur(); - } else if (event.key === 'Escape') { - (event.target as HTMLInputElement).valueAsNumber = - customShellDraft.penetration.near; - (event.target as HTMLInputElement).blur(); - } - }} - > - mm - - - - {(customShellDraft.type === ShellType.AP || - customShellDraft.type === ShellType.APCR) && ( - <> - - Normalization - - - - {customShellDraft.normalization ?? 0}° - - - setCustomShellDraft({ - ...customShellDraft, - normalization: value, - }) + switch (type) { + case ShellType.AP: { + modified.normalization = 5; + modified.ricochet = 70; + break; + } + case ShellType.APCR: { + modified.normalization = 2; + modified.ricochet = 70; + break; + } + case ShellType.HEAT: + case ShellType.HE: { + modified.normalization = undefined; + modified.ricochet = undefined; + break; + } } - /> - + + mutateTankopediaEphemeral((draft) => { + draft.customShell = modified; + }); + }} + > + + + + AP + APCR + HEAT + HE + + - - Ricochet - - - {customShellDraft.ricochet ?? 90}° - - setCustomShellDraft({ - ...customShellDraft, - ricochet: value, - }) + + Caliber + { + mutateTankopediaEphemeral((draft) => { + draft.customShell!.caliber = event.target.valueAsNumber; + }); + }} + onFocus={(event) => event.target.select()} + onKeyDown={(event) => { + if (event.key === 'Enter') { + (event.target as HTMLInputElement).blur(); + } else if (event.key === 'Escape') { + (event.target as HTMLInputElement).valueAsNumber = + customShell.caliber; + (event.target as HTMLInputElement).blur(); } - /> - + }} + > + mm + - - )} - - - - - - - - - - - - + + Penetration + ) => { + mutateTankopediaEphemeral((draft) => { + draft.customShell!.penetration.near = + event.target.valueAsNumber; + }); + }} + onFocus={(event) => event.target.select()} + onKeyDown={(event) => { + if (event.key === 'Enter') { + (event.target as HTMLInputElement).blur(); + } else if (event.key === 'Escape') { + (event.target as HTMLInputElement).valueAsNumber = + customShell.penetration.near; + (event.target as HTMLInputElement).blur(); + } + }} + > + mm + + + + {(customShell.type === ShellType.AP || + customShell.type === ShellType.APCR) && ( + <> + + Normalization + + + + {customShell.normalization ?? 0}° + + { + mutateTankopediaEphemeral((draft) => { + draft.customShell!.normalization = value; + }); + }} + /> + + + + + Ricochet + + + {customShell.ricochet ?? 90}° + { + mutateTankopediaEphemeral((draft) => { + draft.customShell!.ricochet = value; + }); + }} + /> + + + + )} + + + + + + + + + + )} + + ); } diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx index 584935368..1e3b52ad1 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx @@ -53,7 +53,9 @@ interface OptionsProps { } export function Options({ thicknessRange, canvas }: OptionsProps) { - const customShell = TankopediaEphemeral.use((state) => state.customShell); + const hasCustomShell = TankopediaEphemeral.use( + (state) => state.customShell !== undefined, + ); const display = TankopediaPersistent.useDeferred( (state) => state.display, TankopediaDisplay.Model, @@ -101,15 +103,17 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { style={{ position: 'absolute', transform: 'translateY(-50%)' }} align="end" > - - {( - resolvePenetrationCoefficient( - hasCalibratedShells, - antagonistShell.type, - ) * antagonistShell.penetration.near - ).toFixed(0)} - mm - + {!hasCustomShell && ( + + {( + resolvePenetrationCoefficient( + hasCalibratedShells, + antagonistShell.type, + ) * antagonistShell.penetration.near + ).toFixed(0)} + mm + + )} {antagonistUniqueGuns.length > 1 && ( @@ -189,7 +193,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { {antagonistGun.gun_type!.value.base.shells.map((thisShell) => (