From 581d889e9b4f6e31e43dad43c9b34171abb3bff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sat, 27 Dec 2025 19:21:22 -0600 Subject: [PATCH] feat: module selection --- .../src/pages/[...locale]/mixer/_index.tsx | 190 +++++++++++++----- 1 file changed, 138 insertions(+), 52 deletions(-) diff --git a/packages/website/src/pages/[...locale]/mixer/_index.tsx b/packages/website/src/pages/[...locale]/mixer/_index.tsx index d31d52962..72c1fcd13 100644 --- a/packages/website/src/pages/[...locale]/mixer/_index.tsx +++ b/packages/website/src/pages/[...locale]/mixer/_index.tsx @@ -1,16 +1,20 @@ -import { asset } from "@blitzkit/core"; -import { CaretRightIcon, UpdateIcon } from "@radix-ui/react-icons"; +import { asset, TIER_ROMAN_NUMERALS } from "@blitzkit/core"; +import { literals } from "@blitzkit/i18n"; +import { CaretRightIcon, CaretUpIcon, UpdateIcon } from "@radix-ui/react-icons"; import { Box, Button, Dialog, Flex, + IconButton, + Popover, Skeleton, Text, type ButtonProps, } from "@radix-ui/themes"; import { useRef, useState } from "react"; import { MixerScene } from "../../../components/MixerScene"; +import { ModuleButton } from "../../../components/ModuleButtons/ModuleButton"; import { PageWrapper } from "../../../components/PageWrapper"; import { ScreenshotButton } from "../../../components/ScreenshotButton"; import { @@ -18,6 +22,7 @@ import { type TankSearchProps, } from "../../../components/TankSearch"; import { awaitableModelDefinitions } from "../../../core/awaitables/modelDefinitions"; +import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions"; import { curateMixer } from "../../../core/blitzkit/curateMixer"; import { LocaleProvider, @@ -31,6 +36,7 @@ import type { MaybeSkeletonComponentProps } from "../../../types/maybeSkeletonCo const modelDefinition = await awaitableModelDefinitions.then( ({ models }) => models[1] ); +const tankDefinitions = await awaitableTankDefinitions; export function Page({ locale, @@ -50,57 +56,131 @@ export function Page({ ); } -function ModuleButton({ - skeleton, - tank, - onSelect, - ...props -}: Omit & +type ModuleButtonProps = Omit & MaybeSkeletonComponentProps & { tank: number; onSelect: TankSearchProps["onSelect"]; - }) { + turret?: number; + gun?: number; + }; + +function ModuleChooser({ + skeleton, + tank, + onSelect, + turret, + gun, + ...props +}: ModuleButtonProps) { const { strings } = useLocale(); const [open, setOpen] = useState(false); + const tankDefinition = tankDefinitions.tanks[tank]; + const turretDefinition = tankDefinition.turrets.find((t) => t.id === turret); + const gunDefinition = turretDefinition?.guns.find((g) => g.id === gun); + const subSelector = + turret !== undefined && + (tankDefinition.turrets.length > 1 || + (gun !== undefined && turretDefinition!.guns.length > 1)); return ( - - - + + + + + {strings.website.common.tank_search.select_dialog_title} + + + { + onSelect?.(tank); + setOpen(false); + }} + /> + + + + {subSelector && ( + + + - )} - - + {...props} + > + + + - - - {strings.website.common.tank_search.select_dialog_title} - + + + {tankDefinition.turrets.length > 1 && ( + + {tankDefinition.turrets.map((turret) => ( + + ))} + + )} - { - onSelect?.(tank); - setOpen(false); - }} - /> - - + {turretDefinition && turretDefinition.guns.length > 1 && ( + + {turretDefinition.guns.map((gun) => ( + + {literals(strings.common.units.mm, { + value: gun.shells[0].caliber.toFixed(0), + })} + + } + /> + ))} + + )} + + + + )} + ); } @@ -113,9 +193,12 @@ function ModuleSeparator() { } function Content({ skeleton }: MaybeSkeletonComponentProps) { - const hull = Mixer.use((state) => state.hull); - const turretId = Mixer.use((state) => state.turret.tank.id); - const gunId = Mixer.use((state) => state.gun.tank.id); + const hullTankId = Mixer.use((state) => state.hull); + const turretTankId = Mixer.use((state) => state.turret.tank.id); + const turretTurretId = Mixer.use((state) => state.turret.turret.id); + const gunTankId = Mixer.use((state) => state.gun.tank.id); + const gunTurretId = Mixer.use((state) => state.gun.turret.id); + const gunGunId = Mixer.use((state) => state.gun.gun.id); const canvas = useRef(null!); const { strings } = useLocale(); @@ -136,7 +219,7 @@ function Content({ skeleton }: MaybeSkeletonComponentProps) { > - { Mixer.mutate((draft) => { draft.hull = tank; @@ -170,9 +253,10 @@ function Content({ skeleton }: MaybeSkeletonComponentProps) { }} /> - { Mixer.mutate((draft) => { draft.turret = { @@ -183,9 +267,11 @@ function Content({ skeleton }: MaybeSkeletonComponentProps) { }} /> - { Mixer.mutate((draft) => { draft.gun = {