feat: swap tanks

This commit is contained in:
TrèsAbhi committed 2024-01-12 20:55:42 -06:00
1 parent 0b697a94bd
commit 785e9650e5
3 files changed
+63 -60

No files matched your search

@@ -2,6 +2,7 @@ import {
CaretRightIcon, CaretRightIcon,
Cross1Icon, Cross1Icon,
MagnifyingGlassIcon, MagnifyingGlassIcon,
ShuffleIcon,
} from '@radix-ui/react-icons'; } from '@radix-ui/react-icons';
import { import {
Button, Button,
@@ -16,6 +17,7 @@ import {
} from '@radix-ui/themes'; } from '@radix-ui/themes';
import { go } from 'fuzzysort'; import { go } from 'fuzzysort';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { useRouter } from 'next/navigation';
import { use, useRef, useState } from 'react'; import { use, useRef, useState } from 'react';
import { ModuleButton } from '../../../../../components/ModuleButton'; import { ModuleButton } from '../../../../../components/ModuleButton';
import { SmallTankIcon } from '../../../../../components/SmallTankIcon'; import { SmallTankIcon } from '../../../../../components/SmallTankIcon';
@@ -28,25 +30,46 @@ import mutateTankopedia, {
useTankopedia, useTankopedia,
} from '../../../../../stores/tankopedia'; } from '../../../../../stores/tankopedia';
export function VersusBar() { export function AntagonistBar() {
const router = useRouter();
const awaitedTankDefinitions = use(tankDefinitions); const awaitedTankDefinitions = use(tankDefinitions);
const mode = useTankopedia((state) => state.mode); const mode = useTankopedia((state) => state.mode);
const awaitedTankNamesDiacritics = use(tankNamesDiacritics); const awaitedTankNamesDiacritics = use(tankNamesDiacritics);
const [versusTankTab, setVersusTankTab] = useState('search'); const [tab, setTab] = useState('search');
const versusTankSearchInput = useRef<HTMLInputElement>(null); const searchInput = useRef<HTMLInputElement>(null);
const antagonist = useTankopedia((state) => { const antagonist = useTankopedia((state) => {
if (!state.areTanksAssigned) return; if (!state.areTanksAssigned) return;
return state.antagonist; return state.antagonist;
}); });
const [versusTankSearchResults, setVersusTankSearchResults] = useState< const [searchResults, setSearchResults] = useState<number[]>([]);
number[]
>([]);
if (!antagonist || mode !== 'armor') return null; if (!antagonist || mode !== 'armor') return null;
return ( return (
<Card> <Card>
<Flex align="center" justify="between" gap="2"> <Flex align="center" justify="between" gap="2">
<Flex>
{antagonist.gun.shells.map((shell, index) => {
return (
<ModuleButton
selected={antagonist.shell.id === shell.id}
type="shell"
shell={shell.icon}
rowChild
first={index === 0}
key={shell.id}
last={index === antagonist.gun.shells.length - 1}
onClick={() => {
mutateTankopedia((draft) => {
if (!draft.areTanksAssigned) return;
draft.antagonist.shell = shell;
});
}}
/>
);
})}
</Flex>
<Flex align="center" gap="4"> <Flex align="center" gap="4">
<Text>Versus</Text> <Text>Versus</Text>
@@ -63,8 +86,8 @@ export function VersusBar() {
<Dialog.Content> <Dialog.Content>
<Tabs.Root <Tabs.Root
value={versusTankTab} value={tab}
onValueChange={setVersusTankTab} onValueChange={setTab}
style={{ position: 'relative' }} style={{ position: 'relative' }}
> >
<Dialog.Close> <Dialog.Close>
@@ -94,12 +117,12 @@ export function VersusBar() {
<MagnifyingGlassIcon /> <MagnifyingGlassIcon />
</TextField.Slot> </TextField.Slot>
<TextField.Input <TextField.Input
ref={versusTankSearchInput} ref={searchInput}
placeholder="Search tank..." placeholder="Search tank..."
onChange={debounce(() => { onChange={debounce(() => {
setVersusTankSearchResults( setSearchResults(
go( go(
versusTankSearchInput.current!.value, searchInput.current!.value,
awaitedTankNamesDiacritics, awaitedTankNamesDiacritics,
{ key: 'combined', limit: 8 }, { key: 'combined', limit: 8 },
).map((item) => item.obj.id), ).map((item) => item.obj.id),
@@ -109,10 +132,10 @@ export function VersusBar() {
</TextField.Root> </TextField.Root>
<Flex direction="column" gap="2"> <Flex direction="column" gap="2">
{(versusTankSearchResults.length > 0 || {(searchResults.length > 0 ||
versusTankSearchInput.current?.value) && ( searchInput.current?.value) && (
<Flex direction="column" gap="2"> <Flex direction="column" gap="2">
{versusTankSearchResults {searchResults
.map((id) => awaitedTankDefinitions[id]) .map((id) => awaitedTankDefinitions[id])
.map((tank) => ( .map((tank) => (
<Button <Button
@@ -137,18 +160,18 @@ export function VersusBar() {
draft.antagonist.shell = draft.antagonist.shell =
draft.antagonist.gun.shells[0]; draft.antagonist.gun.shells[0];
}); });
setVersusTankSearchResults([]); setSearchResults([]);
versusTankSearchInput.current!.value = ''; searchInput.current!.value = '';
setVersusTankTab('configure'); setTab('configure');
}} }}
> >
{tank.name} {tank.name}
</Button> </Button>
))} ))}
{versusTankSearchResults.length === 0 && {searchResults.length === 0 &&
(versusTankSearchInput.current (searchInput.current
? versusTankSearchInput.current.value.length > 0 ? searchInput.current.value.length > 0
: false) && ( : false) && (
<Button disabled variant="ghost"> <Button disabled variant="ghost">
No search results No search results
@@ -253,40 +276,21 @@ export function VersusBar() {
</Dialog.Root> </Dialog.Root>
</Flex> </Flex>
<Flex> <Button
{antagonist.gun.shells.map((shell, index) => { variant="ghost"
return ( onClick={() => {
<ModuleButton mutateTankopedia((draft) => {
selected={antagonist.shell.id === shell.id} if (!draft.areTanksAssigned) return;
type="shell"
shell={shell.icon} [draft.antagonist, draft.protagonist] = [
rowChild draft.protagonist,
first={index === 0} draft.antagonist,
key={shell.id} ];
last={index === antagonist.gun.shells.length - 1} });
onClick={() => { }}
mutateTankopedia((draft) => { >
if (!draft.areTanksAssigned) return; <ShuffleIcon /> Swap tanks
draft.antagonist.shell = shell; </Button>
});
}}
/>
);
})}
{/* <Button variant="solid" radius="small">
<img src={asset('icons/shells/ap.webp')} width={24} height={24} />
</Button>
<Button variant="soft" radius="small" color="gray">
<img
src={asset('icons/shells/hc_premium.webp')}
width={24}
height={24}
/>
</Button>
<Button variant="soft" radius="small" color="gray">
<img src={asset('icons/shells/he.webp')} width={24} height={24} />
</Button> */}
</Flex>
</Flex> </Flex>
</Card> </Card>
); );
+4 -6
View File
@@ -12,8 +12,8 @@ import {
tankDefinitions, tankDefinitions,
} from '../../../../core/blitzkrieg/tankDefinitions'; } from '../../../../core/blitzkrieg/tankDefinitions';
import mutateTankopedia, { useTankopedia } from '../../../../stores/tankopedia'; import mutateTankopedia, { useTankopedia } from '../../../../stores/tankopedia';
import { AntagonistBar } from './components/AntagonistBar';
import { TankDisplay } from './components/Model/TankDisplay'; import { TankDisplay } from './components/Model/TankDisplay';
import { VersusBar } from './components/VersusBar';
export default function Page({ params }: { params: { id: string } }) { export default function Page({ params }: { params: { id: string } }) {
const id = parseInt(params.id); const id = parseInt(params.id);
@@ -33,10 +33,8 @@ export default function Page({ params }: { params: { id: string } }) {
draft.protagonist.tank = awaitedTankDefinitions[id]; draft.protagonist.tank = awaitedTankDefinitions[id];
draft.protagonist.turret = draft.protagonist.tank.turrets.at(-1)!; draft.protagonist.turret = draft.protagonist.tank.turrets.at(-1)!;
draft.protagonist.gun = draft.protagonist.turret.guns.at(-1)!; draft.protagonist.gun = draft.protagonist.turret.guns.at(-1)!;
draft.antagonist = { draft.protagonist.shell = draft.protagonist.gun.shells[0];
...draft.protagonist, draft.antagonist = draft.protagonist;
shell: draft.protagonist.gun.shells[0],
};
}); });
function handleKeyDown(event: KeyboardEvent) { function handleKeyDown(event: KeyboardEvent) {
@@ -101,7 +99,7 @@ export default function Page({ params }: { params: { id: string } }) {
</Flex> </Flex>
<TankDisplay /> <TankDisplay />
<VersusBar /> <AntagonistBar />
<Theme radius="small"> <Theme radius="small">
<Flex gap="4"> <Flex gap="4">
+1
View File
@@ -42,6 +42,7 @@ type Tankopedia = {
tank: TankDefinition; tank: TankDefinition;
turret: TurretDefinition; turret: TurretDefinition;
gun: GunDefinition; gun: GunDefinition;
shell: ShellDefinition;
}; };
antagonist: { antagonist: {
tank: TankDefinition; tank: TankDefinition;