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) => (