mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-28 13:09:51 +01:00
well at least some of it is showing up i guess
This commit is contained in:
1 parent
43fc98e37d
commit
4694d495bb
4 files changed
+227
-201
No files matched your search
@@ -69,6 +69,13 @@
|
|||||||
|
|
||||||
.label {
|
.label {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg {
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:has(input:checked) {
|
&:has(input:checked) {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-4);
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
transition: var(--duration-brief);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: var(--space-4);
|
||||||
|
|
||||||
|
transform: translate(-50%, calc(100% + var(--space-4)) s);
|
||||||
|
|
||||||
|
&[data-visible="true"] {
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--space-4);
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { alias, romanize, uniqueGuns } from "@blitzkit/core";
|
import { uniqueGuns } from "@blitzkit/core";
|
||||||
import { literals } from "@blitzkit/i18n/src/literals";
|
import { ShadowInnerIcon, ShadowNoneIcon } from "@radix-ui/react-icons";
|
||||||
import { Flex, IconButton, Popover, Text } from "@radix-ui/themes";
|
|
||||||
import { useState, type RefObject } from "react";
|
import { useState, type RefObject } from "react";
|
||||||
import { DuelModule, useDuel } from "../../hooks/useDuel";
|
import { DuelModule, useDuel } from "../../hooks/useDuel";
|
||||||
import { useEquipment } from "../../hooks/useEquipment";
|
import { useEquipment } from "../../hooks/useEquipment";
|
||||||
@@ -11,26 +10,16 @@ import { useUnwrapper } from "../../hooks/useUnwrapper";
|
|||||||
import { Tankopedia } from "../../stores/tankopedia";
|
import { Tankopedia } from "../../stores/tankopedia";
|
||||||
import { TankopediaPersistent } from "../../stores/tankopediaPersistent";
|
import { TankopediaPersistent } from "../../stores/tankopediaPersistent";
|
||||||
import { TankopediaDisplay } from "../../stores/tankopediaPersistent/constants";
|
import { TankopediaDisplay } from "../../stores/tankopediaPersistent/constants";
|
||||||
import type { ComputedCharacteristics } from "../../types/characteristics";
|
|
||||||
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
||||||
import { EqualIcon } from "../EqualIcon";
|
import { IconButton } from "../IconButton";
|
||||||
import { ModuleButton } from "../ModuleButtons/ModuleButton";
|
import { SegmentedControl } from "../SegmentedControl";
|
||||||
import {
|
import styles from "./index.module.css";
|
||||||
SidebarIconButton,
|
|
||||||
SidebarIconGroup,
|
|
||||||
} from "../TankopediaSidebarIconButtons";
|
|
||||||
import { CustomShellButton } from "./components/CustomShellButton";
|
|
||||||
|
|
||||||
type OptionsProps = MaybeSkeletonComponentProps & {
|
type OptionsProps = MaybeSkeletonComponentProps & {
|
||||||
canvas: RefObject<HTMLCanvasElement>;
|
canvas: RefObject<HTMLCanvasElement>;
|
||||||
antagonistCharacteristics: ComputedCharacteristics;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function TankopediaOptions({
|
export function TankopediaOptions({ canvas, skeleton }: OptionsProps) {
|
||||||
canvas,
|
|
||||||
skeleton,
|
|
||||||
antagonistCharacteristics,
|
|
||||||
}: OptionsProps) {
|
|
||||||
const strings = useStrings();
|
const strings = useStrings();
|
||||||
const unwrap = useUnwrapper();
|
const unwrap = useUnwrapper();
|
||||||
|
|
||||||
@@ -59,215 +48,216 @@ export function TankopediaOptions({
|
|||||||
const equalize = Tankopedia.use((state) => state.environment.equalize);
|
const equalize = Tankopedia.use((state) => state.environment.equalize);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={styles.options}>
|
||||||
|
<div className={styles.controls}>
|
||||||
|
{disturbed && (
|
||||||
|
<>
|
||||||
|
{requestedDisplay === TankopediaDisplay.DynamicArmor && (
|
||||||
|
<IconButton
|
||||||
|
size="minor"
|
||||||
|
highContrast
|
||||||
|
onClick={() => {
|
||||||
|
TankopediaPersistent.mutate((draft) => {
|
||||||
|
draft.advancedHighlighting = !draft.advancedHighlighting;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
color={advancedHighlighting ? undefined : "gray"}
|
||||||
|
variant={advancedHighlighting ? "solid" : "surface"}
|
||||||
|
>
|
||||||
|
{advancedHighlighting ? (
|
||||||
|
<ShadowInnerIcon />
|
||||||
|
) : (
|
||||||
|
<ShadowNoneIcon />
|
||||||
|
)}
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* <DropdownMenu.Root>
|
||||||
{/* <Flex
|
<DropdownMenu.Trigger>
|
||||||
direction="column"
|
|
||||||
align="center"
|
|
||||||
position="absolute"
|
|
||||||
bottom={revealed ? "4" : "-100%"}
|
|
||||||
left="50%"
|
|
||||||
style={{ transform: "translateX(-50%)", transitionDuration: "200ms" }}
|
|
||||||
gap="2"
|
|
||||||
>
|
|
||||||
<Flex
|
|
||||||
gap="2"
|
|
||||||
align="center"
|
|
||||||
style={{ transitionDuration: "200ms" }}
|
|
||||||
position="relative"
|
|
||||||
>
|
|
||||||
{disturbed && (
|
|
||||||
<>
|
|
||||||
{requestedDisplay === TankopediaDisplay.DynamicArmor && (
|
|
||||||
<IconButton
|
<IconButton
|
||||||
size="2"
|
size="2"
|
||||||
|
variant="surface"
|
||||||
highContrast
|
highContrast
|
||||||
onClick={() => {
|
color="gray"
|
||||||
TankopediaPersistent.mutate((draft) => {
|
|
||||||
draft.advancedHighlighting = !draft.advancedHighlighting;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
color={advancedHighlighting ? undefined : "gray"}
|
|
||||||
variant={advancedHighlighting ? "solid" : "surface"}
|
|
||||||
>
|
>
|
||||||
{advancedHighlighting ? (
|
<EyeOpenIcon />
|
||||||
<ShadowInnerIcon />
|
|
||||||
) : (
|
|
||||||
<ShadowNoneIcon />
|
|
||||||
)}
|
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
</DropdownMenu.Trigger>
|
||||||
|
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Content>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Item
|
||||||
<IconButton
|
onClick={() => poseEvent.emit(Pose.HullDown)}
|
||||||
size="2"
|
>
|
||||||
variant="surface"
|
{strings.tanks.poses.hull_down}
|
||||||
highContrast
|
</DropdownMenu.Item>
|
||||||
color="gray"
|
|
||||||
>
|
|
||||||
<EyeOpenIcon />
|
|
||||||
</IconButton>
|
|
||||||
</DropdownMenu.Trigger>
|
|
||||||
|
|
||||||
<DropdownMenu.Content>
|
<DropdownMenu.Item onClick={() => poseEvent.emit(Pose.FaceHug)}>
|
||||||
<DropdownMenu.Item
|
{strings.tanks.poses.face_hug}
|
||||||
onClick={() => poseEvent.emit(Pose.HullDown)}
|
</DropdownMenu.Item>
|
||||||
>
|
|
||||||
{strings.tanks.poses.hull_down}
|
|
||||||
</DropdownMenu.Item>
|
|
||||||
|
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item onClick={() => poseEvent.emit(Pose.Default)}>
|
||||||
onClick={() => poseEvent.emit(Pose.FaceHug)}
|
{strings.tanks.poses.default}
|
||||||
>
|
</DropdownMenu.Item>
|
||||||
{strings.tanks.poses.face_hug}
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Root> */}
|
||||||
|
|
||||||
<DropdownMenu.Item
|
<IconButton
|
||||||
onClick={() => poseEvent.emit(Pose.Default)}
|
size="2"
|
||||||
>
|
highContrast
|
||||||
{strings.tanks.poses.default}
|
onClick={() => {
|
||||||
</DropdownMenu.Item>
|
TankopediaPersistent.mutate((draft) => {
|
||||||
</DropdownMenu.Content>
|
draft.highGraphics = !draft.highGraphics;
|
||||||
</DropdownMenu.Root>
|
});
|
||||||
|
}}
|
||||||
|
color={highGraphics ? undefined : "gray"}
|
||||||
|
variant={highGraphics ? "solid" : "surface"}
|
||||||
|
>
|
||||||
|
<SunIcon />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<ScreenshotButton
|
||||||
|
color="gray"
|
||||||
|
size="2"
|
||||||
|
variant="surface"
|
||||||
|
highContrast
|
||||||
|
canvas={canvas}
|
||||||
|
name={protagonistTank.slug}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{fullScreenAvailable && (
|
||||||
<IconButton
|
<IconButton
|
||||||
size="2"
|
size="2"
|
||||||
highContrast
|
highContrast
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
TankopediaPersistent.mutate((draft) => {
|
if (isFullScreen) {
|
||||||
draft.highGraphics = !draft.highGraphics;
|
document.exitFullscreen();
|
||||||
});
|
} else document.body.requestFullscreen();
|
||||||
}}
|
}}
|
||||||
color={highGraphics ? undefined : "gray"}
|
color={isFullScreen ? undefined : "gray"}
|
||||||
variant={highGraphics ? "solid" : "surface"}
|
variant={isFullScreen ? "solid" : "surface"}
|
||||||
>
|
>
|
||||||
<SunIcon />
|
{isFullScreen ? (
|
||||||
|
<ExitFullScreenIcon />
|
||||||
|
) : (
|
||||||
|
<EnterFullScreenIcon />
|
||||||
|
)}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<ScreenshotButton
|
<div gap="3" align="center" mt="2">
|
||||||
color="gray"
|
<SegmentedControl
|
||||||
size="2"
|
onValueChange={(value) => {
|
||||||
variant="surface"
|
Tankopedia.mutate((draft) => {
|
||||||
highContrast
|
draft.requestedDisplay = Number(value);
|
||||||
canvas={canvas}
|
});
|
||||||
name={protagonistTank.slug}
|
}}
|
||||||
/>
|
value={`${requestedDisplay}`}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: <img src="/assets/images/icons/tankopedia-model.png" />,
|
||||||
|
value: `${TankopediaDisplay.Model}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<img src="/assets/images/icons/tankopedia-dynamic-armor.png" />
|
||||||
|
),
|
||||||
|
value: `${TankopediaDisplay.DynamicArmor}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<img src="/assets/images/icons/tankopedia-static-armor.png" />
|
||||||
|
),
|
||||||
|
value: `${TankopediaDisplay.StaticArmor}`,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
{/* <SegmentedControl.Root
|
||||||
|
variant="classic"
|
||||||
|
value={`${disturbed ? requestedDisplay : -1}`}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
Tankopedia.mutate((draft) => {
|
||||||
|
draft.disturbed = true;
|
||||||
|
draft.requestedDisplay = Number(value);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SegmentedControl.Item value={`${TankopediaDisplay.Model}`}>
|
||||||
|
<Tooltip tooltip={strings.tanks.tabs.model}>
|
||||||
|
<div height="100%" align="center">
|
||||||
|
|
||||||
{fullScreenAvailable && (
|
</Tooltip>
|
||||||
<IconButton
|
</SegmentedControl.Item>
|
||||||
size="2"
|
<SegmentedControl.Item value={`${TankopediaDisplay.DynamicArmor}`}>
|
||||||
highContrast
|
<Tooltip tooltip={strings.tanks.tabs.dynamic_armor}>
|
||||||
onClick={() => {
|
<div height="100%" align="center">
|
||||||
if (isFullScreen) {
|
<img
|
||||||
document.exitFullscreen();
|
src="/assets/images/icons/tankopedia-dynamic-armor.png"
|
||||||
} else document.body.requestFullscreen();
|
style={{ height: "1.25em" }}
|
||||||
}}
|
/>
|
||||||
color={isFullScreen ? undefined : "gray"}
|
</div>
|
||||||
variant={isFullScreen ? "solid" : "surface"}
|
</Tooltip>
|
||||||
>
|
</SegmentedControl.Item>
|
||||||
{isFullScreen ? (
|
<SegmentedControl.Item value={`${TankopediaDisplay.StaticArmor}`}>
|
||||||
<ExitFullScreenIcon />
|
<Tooltip tooltip={strings.tanks.tabs.model}>
|
||||||
) : (
|
<div height="100%" align="center">
|
||||||
<EnterFullScreenIcon />
|
<img
|
||||||
)}
|
src="/assets/images/icons/tankopedia-static-armor.png"
|
||||||
</IconButton>
|
style={{ height: "1.25em" }}
|
||||||
)}
|
/>
|
||||||
</>
|
</div>
|
||||||
)}
|
</Tooltip>
|
||||||
</Flex>
|
</SegmentedControl.Item>
|
||||||
|
</SegmentedControl.Root> */}
|
||||||
|
|
||||||
<Flex gap="3" align="center" mt="2">
|
{requestedDisplay === TankopediaDisplay.DynamicArmor && (
|
||||||
<SegmentedControl.Root
|
<Dialog.Root
|
||||||
variant="classic"
|
open={antagonistSelectorOpen}
|
||||||
value={`${disturbed ? requestedDisplay : -1}`}
|
onOpenChange={setAntagonistSelectorOpen}
|
||||||
onValueChange={(value) => {
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
draft.disturbed = true;
|
|
||||||
draft.requestedDisplay = Number(value);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<SegmentedControl.Item value={`${TankopediaDisplay.Model}`}>
|
<Dialog.Trigger>
|
||||||
<Tooltip tooltip={strings.tanks.tabs.model}>
|
<Button variant="solid" highContrast>
|
||||||
<Flex height="100%" align="center">
|
<Crosshair1Icon />
|
||||||
<img
|
{unwrap(antagonistTank.name!)}
|
||||||
src="/assets/images/icons/tankopedia-model.png"
|
<SmallTankIcon id={antagonistTank.id} size={16} />
|
||||||
style={{ height: "1.25em" }}
|
</Button>
|
||||||
/>
|
</Dialog.Trigger>
|
||||||
</Flex>
|
|
||||||
</Tooltip>
|
|
||||||
</SegmentedControl.Item>
|
|
||||||
<SegmentedControl.Item value={`${TankopediaDisplay.DynamicArmor}`}>
|
|
||||||
<Tooltip tooltip={strings.tanks.tabs.dynamic_armor}>
|
|
||||||
<Flex height="100%" align="center">
|
|
||||||
<img
|
|
||||||
src="/assets/images/icons/tankopedia-dynamic-armor.png"
|
|
||||||
style={{ height: "1.25em" }}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Tooltip>
|
|
||||||
</SegmentedControl.Item>
|
|
||||||
<SegmentedControl.Item value={`${TankopediaDisplay.StaticArmor}`}>
|
|
||||||
<Tooltip tooltip={strings.tanks.tabs.model}>
|
|
||||||
<Flex height="100%" align="center">
|
|
||||||
<img
|
|
||||||
src="/assets/images/icons/tankopedia-static-armor.png"
|
|
||||||
style={{ height: "1.25em" }}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Tooltip>
|
|
||||||
</SegmentedControl.Item>
|
|
||||||
</SegmentedControl.Root>
|
|
||||||
|
|
||||||
{requestedDisplay === TankopediaDisplay.DynamicArmor && (
|
<Dialog.Content>
|
||||||
<Dialog.Root
|
<Dialog.Title align="center">
|
||||||
open={antagonistSelectorOpen}
|
{strings.website.common.tank_search.select_dialog_title}
|
||||||
onOpenChange={setAntagonistSelectorOpen}
|
</Dialog.Title>
|
||||||
>
|
|
||||||
<Dialog.Trigger>
|
|
||||||
<Button variant="solid" highContrast>
|
|
||||||
<Crosshair1Icon />
|
|
||||||
{unwrap(antagonistTank.name!)}
|
|
||||||
<SmallTankIcon id={antagonistTank.id} size={16} />
|
|
||||||
</Button>
|
|
||||||
</Dialog.Trigger>
|
|
||||||
|
|
||||||
<Dialog.Content>
|
<Tabs.Root
|
||||||
<Dialog.Title align="center">
|
value={tab}
|
||||||
{strings.website.common.tank_search.select_dialog_title}
|
onValueChange={setTab}
|
||||||
</Dialog.Title>
|
style={{ position: "relative" }}
|
||||||
|
>
|
||||||
|
<TankSearch
|
||||||
|
compact
|
||||||
|
onSelect={(tank) => {
|
||||||
|
Tankopedia.mutate((draft) => {
|
||||||
|
draft.antagonist.tank = tank.id;
|
||||||
|
draft.antagonist.engine = tank.engines.at(-1)!.id;
|
||||||
|
draft.antagonist.track = tank.tracks.at(-1)!.id;
|
||||||
|
|
||||||
<Tabs.Root
|
const turret = tank.turrets.at(-1)!;
|
||||||
value={tab}
|
const gun = turret.guns.at(-1)!;
|
||||||
onValueChange={setTab}
|
|
||||||
style={{ position: "relative" }}
|
|
||||||
>
|
|
||||||
<TankSearch
|
|
||||||
compact
|
|
||||||
onSelect={(tank) => {
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
draft.antagonist.tank = tank.id;
|
|
||||||
draft.antagonist.engine = tank.engines.at(-1)!.id;
|
|
||||||
draft.antagonist.track = tank.tracks.at(-1)!.id;
|
|
||||||
|
|
||||||
const turret = tank.turrets.at(-1)!;
|
draft.antagonist.turret = turret.id;
|
||||||
const gun = turret.guns.at(-1)!;
|
draft.antagonist.gun = gun.id;
|
||||||
|
draft.antagonist.shell = gun.shells[0].id;
|
||||||
draft.antagonist.turret = turret.id;
|
});
|
||||||
draft.antagonist.gun = gun.id;
|
setAntagonistSelectorOpen(false);
|
||||||
draft.antagonist.shell = gun.shells[0].id;
|
}}
|
||||||
});
|
/>
|
||||||
setAntagonistSelectorOpen(false);
|
</Tabs.Root>
|
||||||
}}
|
</Dialog.Content>
|
||||||
/>
|
</Dialog.Root>
|
||||||
</Tabs.Root>
|
)}
|
||||||
</Dialog.Content>
|
</div>
|
||||||
</Dialog.Root>
|
</div>
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Flex> */}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ import { SmartCanvas } from "../SmartCanvas";
|
|||||||
import { StaticArmor, type ThicknessRange } from "../StaticArmor";
|
import { StaticArmor, type ThicknessRange } from "../StaticArmor";
|
||||||
import { TankModel } from "../TankModel";
|
import { TankModel } from "../TankModel";
|
||||||
import { TankopediaAntagonistControl } from "../TankopediaAntagonistControl";
|
import { TankopediaAntagonistControl } from "../TankopediaAntagonistControl";
|
||||||
|
import { TankopediaOptions } from "../TankopediaOptions";
|
||||||
import { TankopediaSkinSwitcher } from "../TankopediaSkinSwitcher";
|
import { TankopediaSkinSwitcher } from "../TankopediaSkinSwitcher";
|
||||||
import styles from "./index.module.css";
|
import styles from "./index.module.css";
|
||||||
|
|
||||||
@@ -178,6 +179,7 @@ export function TankopediaSandbox({
|
|||||||
<TankopediaAntagonistControl
|
<TankopediaAntagonistControl
|
||||||
antagonistCharacteristics={antagonistCharacteristics}
|
antagonistCharacteristics={antagonistCharacteristics}
|
||||||
/>
|
/>
|
||||||
|
<TankopediaOptions />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user