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