mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: shells
This commit is contained in:
1 parent
57efde83df
commit
86e080aae9
1 file changed
+103
-1
@@ -8,7 +8,16 @@ import {
|
|||||||
TIER_ROMAN_NUMERALS,
|
TIER_ROMAN_NUMERALS,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
import { TrashIcon } from "@radix-ui/react-icons";
|
import { TrashIcon } from "@radix-ui/react-icons";
|
||||||
import { Box, Button, DropdownMenu, Flex, Text } from "@radix-ui/themes";
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
DropdownMenu,
|
||||||
|
Flex,
|
||||||
|
IconButton,
|
||||||
|
Inset,
|
||||||
|
Popover,
|
||||||
|
Text,
|
||||||
|
} from "@radix-ui/themes";
|
||||||
import { times } from "lodash-es";
|
import { times } from "lodash-es";
|
||||||
import type { ComponentProps, ReactNode } from "react";
|
import type { ComponentProps, ReactNode } from "react";
|
||||||
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
|
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
|
||||||
@@ -18,6 +27,7 @@ import { classIcons } from "../../ClassIcon";
|
|||||||
import { GunAutoloaderIcon } from "../../GunAutoloaderIcon";
|
import { GunAutoloaderIcon } from "../../GunAutoloaderIcon";
|
||||||
import { GunAutoreloaderIcon } from "../../GunAutoreloaderIcon";
|
import { GunAutoreloaderIcon } from "../../GunAutoreloaderIcon";
|
||||||
import { GunRegularIcon } from "../../GunRegularIcon";
|
import { GunRegularIcon } from "../../GunRegularIcon";
|
||||||
|
import { MissingShellIcon } from "../../MissingShellIcon";
|
||||||
import { ResearchedIcon } from "../../ResearchedIcon";
|
import { ResearchedIcon } from "../../ResearchedIcon";
|
||||||
|
|
||||||
const gameDefinitions = await awaitableGameDefinitions;
|
const gameDefinitions = await awaitableGameDefinitions;
|
||||||
@@ -60,6 +70,7 @@ export function FilterControl() {
|
|||||||
<TypeFilter />
|
<TypeFilter />
|
||||||
<ClassFilter />
|
<ClassFilter />
|
||||||
<GunTypeFilter />
|
<GunTypeFilter />
|
||||||
|
<ShellFilter />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -478,3 +489,94 @@ function TypeFilter() {
|
|||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ShellFilter() {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
overflow="hidden"
|
||||||
|
style={{
|
||||||
|
borderRadius: "var(--radius-full)",
|
||||||
|
boxShadow: "var(--shadow-1)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IndividualShellFilter index={0} />
|
||||||
|
<IndividualShellFilter index={1} premium />
|
||||||
|
<IndividualShellFilter index={2} />
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function IndividualShellFilter({
|
||||||
|
index,
|
||||||
|
premium,
|
||||||
|
}: {
|
||||||
|
index: number;
|
||||||
|
premium?: boolean;
|
||||||
|
}) {
|
||||||
|
const shells = TankFilters.use((state) => state.shells);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover.Root>
|
||||||
|
<Popover.Trigger>
|
||||||
|
<IconButton variant="soft" radius="none" color="gray" highContrast>
|
||||||
|
{shells[index] === null && (
|
||||||
|
<Text color="gray" style={{ display: "contents" }}>
|
||||||
|
<MissingShellIcon width="1em" height="1em" />
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
{shells[index] !== null && (
|
||||||
|
<img
|
||||||
|
style={{ width: "1em", height: "1em" }}
|
||||||
|
src={asset(
|
||||||
|
`icons/shells/${shellTypeIcons[shells[index]]}${
|
||||||
|
premium ? "_premium" : ""
|
||||||
|
}.webp`
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</IconButton>
|
||||||
|
</Popover.Trigger>
|
||||||
|
|
||||||
|
<Popover.Content>
|
||||||
|
<Inset>
|
||||||
|
<Flex direction="column">
|
||||||
|
{Object.values(ShellType).map((shellType) => {
|
||||||
|
if (typeof shellType === "string") return null;
|
||||||
|
|
||||||
|
const selected = shells[index] === shellType;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
key={shellType}
|
||||||
|
value={`${shellType}`}
|
||||||
|
radius="none"
|
||||||
|
variant={selected ? "solid" : "soft"}
|
||||||
|
onClick={() => {
|
||||||
|
const mutated = [...shells] as TankFilters["shells"];
|
||||||
|
|
||||||
|
mutated[index] = selected ? null : shellType;
|
||||||
|
|
||||||
|
TankFilters.mutate((draft) => {
|
||||||
|
draft.shells = mutated;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
highContrast={selected}
|
||||||
|
color={selected ? undefined : "gray"}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={asset(
|
||||||
|
`icons/shells/${shellTypeIcons[shellType]}${
|
||||||
|
premium ? "_premium" : ""
|
||||||
|
}.webp`
|
||||||
|
)}
|
||||||
|
style={{ width: "1em", height: "1em" }}
|
||||||
|
/>
|
||||||
|
</IconButton>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
</Inset>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user