mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: swap button
This commit is contained in:
1 parent
ee9dbdaf74
commit
13faad0977
3 files changed
+81
-31
No files matched your search
@@ -12,11 +12,7 @@ import { TankSandbox } from './TankSandbox';
|
||||
import { TankSandboxLoader } from './TankSandboxLoader';
|
||||
import { Options } from './components/Options';
|
||||
|
||||
interface HeroSectionProps {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export function HeroSection({ id }: HeroSectionProps) {
|
||||
export function HeroSection() {
|
||||
const canvas = useRef<HTMLCanvasElement>(null);
|
||||
const isFullScreen = useFullScreen();
|
||||
const protagonist = Duel.use((state) => state.protagonist.tank);
|
||||
@@ -29,10 +25,11 @@ export function HeroSection({ id }: HeroSectionProps) {
|
||||
? 'amber'
|
||||
: undefined;
|
||||
const awaitedTankDefinitions = use(tankDefinitions);
|
||||
const tank = awaitedTankDefinitions[id];
|
||||
const thicknessRange = useMemo(() => {
|
||||
const entries = Object.values(awaitedTankDefinitions);
|
||||
const filtered = entries.filter((thisTank) => thisTank.tier === tank.tier);
|
||||
const filtered = entries.filter(
|
||||
(thisTank) => thisTank.tier === protagonist.tier,
|
||||
);
|
||||
const value =
|
||||
(filtered.reduce((accumulator, thisTank) => {
|
||||
return (
|
||||
@@ -46,7 +43,7 @@ export function HeroSection({ id }: HeroSectionProps) {
|
||||
(3 / 4);
|
||||
|
||||
return { value } satisfies ThicknessRange;
|
||||
}, [tank.tier]);
|
||||
}, [protagonist]);
|
||||
|
||||
useEffect(() => {
|
||||
setDummyLoader(false);
|
||||
@@ -90,7 +87,7 @@ export function HeroSection({ id }: HeroSectionProps) {
|
||||
>
|
||||
<Flex align="center" gap="3">
|
||||
<Icon width="0.8em" height="0.8em" />
|
||||
{tank.name}
|
||||
{protagonist.name}
|
||||
</Flex>
|
||||
</Heading>
|
||||
|
||||
@@ -114,14 +111,14 @@ export function HeroSection({ id }: HeroSectionProps) {
|
||||
<Box width="100%" height="100%" position="absolute">
|
||||
<Box width="100%" height="100%">
|
||||
<TankSandboxLoader
|
||||
id={id}
|
||||
id={protagonist.id}
|
||||
display={dummyLoader ? 'flex' : 'none'}
|
||||
/>
|
||||
|
||||
<Suspense
|
||||
fallback={
|
||||
<TankSandboxLoader
|
||||
id={id}
|
||||
id={protagonist.id}
|
||||
display={dummyLoader ? 'none' : 'flex'}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { ChevronLeftIcon, MixIcon } from '@radix-ui/react-icons';
|
||||
import { Button, Code, Flex } from '@radix-ui/themes';
|
||||
import { ChevronLeftIcon, MixIcon, UpdateIcon } from '@radix-ui/react-icons';
|
||||
import { Button, Code, Dialog, Flex } from '@radix-ui/themes';
|
||||
import { use, useState } from 'react';
|
||||
import { classIcons } from '../../../../../../../components/ClassIcon';
|
||||
import { Link } from '../../../../../../../components/Link';
|
||||
import { asset } from '../../../../../../../core/blitzkit/asset';
|
||||
import { modelDefinitions } from '../../../../../../../core/blitzkit/modelDefinitions';
|
||||
import { provisionDefinitions } from '../../../../../../../core/blitzkit/provisionDefinitions';
|
||||
import { tankToDuelMember } from '../../../../../../../core/blitzkit/tankToDuelMember';
|
||||
import strings from '../../../../../../../lang/en-US.json';
|
||||
import * as App from '../../../../../../../stores/app';
|
||||
import * as Duel from '../../../../../../../stores/duel';
|
||||
import * as TankopediaEphemeral from '../../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankSearch } from '../../../../components/TankSearch';
|
||||
import { Listing } from './components/Listing';
|
||||
import { Votes } from './components/Votes';
|
||||
|
||||
@@ -18,6 +24,11 @@ export function MetaSection() {
|
||||
protagonist.id === antagonist.id
|
||||
? [protagonist.id]
|
||||
: [protagonist.id, antagonist.id];
|
||||
const mutateDuel = Duel.useMutation();
|
||||
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
||||
const awaitedProvisionDefinitions = use(provisionDefinitions);
|
||||
const [showSwapDialog, setShowSwapDialog] = useState(false);
|
||||
const awaitedModelDefinitions = use(modelDefinitions);
|
||||
|
||||
return (
|
||||
<Flex justify="center" align="center">
|
||||
@@ -31,11 +42,44 @@ export function MetaSection() {
|
||||
</Link>
|
||||
|
||||
<Link href={`/tools/compare?tanks=${compareTanks.join('%2C')}`}>
|
||||
<Button>
|
||||
<Button variant="outline">
|
||||
<MixIcon />
|
||||
Compare
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
<Dialog.Root open={showSwapDialog} onOpenChange={setShowSwapDialog}>
|
||||
<Dialog.Trigger>
|
||||
<Button>
|
||||
<UpdateIcon />
|
||||
Swap
|
||||
</Button>
|
||||
</Dialog.Trigger>
|
||||
|
||||
<Dialog.Content>
|
||||
<TankSearch
|
||||
compact
|
||||
onSelect={(tank) => {
|
||||
setShowSwapDialog(false);
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
draft.model = awaitedModelDefinitions[tank.id];
|
||||
});
|
||||
mutateDuel((draft) => {
|
||||
draft.protagonist = tankToDuelMember(
|
||||
tank,
|
||||
awaitedProvisionDefinitions,
|
||||
);
|
||||
});
|
||||
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
`/tools/tankopedia/${tank.id}`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
</Flex>
|
||||
|
||||
<Flex
|
||||
|
||||
@@ -4,7 +4,9 @@ import { invalidate } from '@react-three/fiber';
|
||||
import { useEffect } from 'react';
|
||||
import { AdMidSectionResponsive } from '../../../../components/AdMidSectionResponsive';
|
||||
import PageWrapper from '../../../../components/PageWrapper';
|
||||
import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants';
|
||||
import { useAdExempt } from '../../../../hooks/useAdExempt';
|
||||
import strings from '../../../../lang/en-US.json';
|
||||
import * as Duel from '../../../../stores/duel';
|
||||
import * as TankopediaEphemeral from '../../../../stores/tankopediaEphemeral';
|
||||
import { CalloutsSection } from './components/CalloutsSection';
|
||||
@@ -14,14 +16,18 @@ import { GameModeSection } from './components/Model/GameModeSection';
|
||||
import { HeroSection } from './components/Model/HeroSection';
|
||||
import { MetaSection } from './components/Model/MetaSection';
|
||||
import { TechTreeSection } from './components/Model/TechTreeSection';
|
||||
import { ShotDisplaySection } from './components/ShotDisplaySection';
|
||||
import { VideoSection } from './components/VideoSection';
|
||||
|
||||
export default function Page({ params }: { params: { id: string } }) {
|
||||
const id = Number(params.id);
|
||||
export default function Page() {
|
||||
const exempt = useAdExempt();
|
||||
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
||||
const mutateDuel = Duel.useMutation();
|
||||
const duelStore = Duel.useStore();
|
||||
const tank = Duel.use((state) => state.protagonist.tank);
|
||||
const title = `${tank.name} - Tier ${TIER_ROMAN_NUMERALS[tank.tier]} ${
|
||||
(strings.common.nations_adjectives as Record<string, string>)[tank.nation]
|
||||
} ${strings.common.tank_class_short[tank.class]}`;
|
||||
|
||||
useEffect(() => {
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
@@ -79,20 +85,23 @@ export default function Page({ params }: { params: { id: string } }) {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageWrapper p="0" noMaxWidth color="purple" size={1600} gap="9">
|
||||
<HeroSection id={id} />
|
||||
<CalloutsSection />
|
||||
<MetaSection />
|
||||
{/* <VotingSection /> */}
|
||||
{/* <ShotDisplaySection /> */}
|
||||
<TechTreeSection />
|
||||
{!exempt && <AdMidSectionResponsive />}
|
||||
<CharacteristicsSection />
|
||||
{!exempt && <AdMidSectionResponsive />}
|
||||
<GameModeSection />
|
||||
<VideoSection />
|
||||
<HistorySection />
|
||||
{!exempt && <AdMidSectionResponsive mb="6" />}
|
||||
</PageWrapper>
|
||||
<>
|
||||
<title>{title}</title>
|
||||
|
||||
<PageWrapper p="0" noMaxWidth color="purple" size={1600} gap="9">
|
||||
<HeroSection />
|
||||
<MetaSection />
|
||||
<ShotDisplaySection />
|
||||
<TechTreeSection />
|
||||
{!exempt && <AdMidSectionResponsive />}
|
||||
<CalloutsSection />
|
||||
<CharacteristicsSection />
|
||||
{!exempt && <AdMidSectionResponsive />}
|
||||
<GameModeSection />
|
||||
<VideoSection />
|
||||
<HistorySection />
|
||||
{!exempt && <AdMidSectionResponsive mb="6" />}
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user