feat: better meta
No files matched your search
|
After Width: | Height: | Size: 242 KiB |
|
After Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 365 KiB |
|
After Width: | Height: | Size: 771 KiB |
|
After Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 379 KiB |
|
After Width: | Height: | Size: 371 KiB |
@@ -1,4 +1,5 @@
|
|||||||
import { Flex, Text, type TextProps } from '@radix-ui/themes';
|
import { Flex, Text, type TextProps } from '@radix-ui/themes';
|
||||||
|
import { Var } from '../../../../core/radix/var';
|
||||||
|
|
||||||
type ListingProps = TextProps & {
|
type ListingProps = TextProps & {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -6,9 +7,15 @@ type ListingProps = TextProps & {
|
|||||||
|
|
||||||
export function Listing({ label, ...props }: ListingProps) {
|
export function Listing({ label, ...props }: ListingProps) {
|
||||||
return (
|
return (
|
||||||
<Flex minWidth="15rem" justify="between" gap="4">
|
<Flex
|
||||||
<Text color="gray">{label}</Text>
|
minWidth="17rem"
|
||||||
<Text align="right" {...props} />
|
justify="between"
|
||||||
|
gap="4"
|
||||||
|
px="1"
|
||||||
|
style={{ borderBottom: `1px solid ${Var('gray-11')}` }}
|
||||||
|
>
|
||||||
|
<Text size="4">{label}</Text>
|
||||||
|
<Text align="right" size="4" weight="medium" {...props} />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,171 +1,178 @@
|
|||||||
import {
|
import {
|
||||||
assertSecret,
|
|
||||||
asset,
|
asset,
|
||||||
TankPriceType,
|
TankPriceType,
|
||||||
TankType,
|
TankType,
|
||||||
TIER_ROMAN_NUMERALS,
|
TIER_ROMAN_NUMERALS,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
import { ChevronLeftIcon, MixIcon, UpdateIcon } from '@radix-ui/react-icons';
|
import { Box, Code, Flex } from '@radix-ui/themes';
|
||||||
import { Button, Code, Dialog, Flex, Link } from '@radix-ui/themes';
|
import { Var } from '../../../core/radix/var';
|
||||||
import { useState } from 'react';
|
|
||||||
import { awaitableModelDefinitions } from '../../../core/awaitables/modelDefinitions';
|
|
||||||
import { awaitableProvisionDefinitions } from '../../../core/awaitables/provisionDefinitions';
|
|
||||||
import { tankToDuelMember } from '../../../core/blitzkit/tankToDuelMember';
|
|
||||||
import { useLocale } from '../../../hooks/useLocale';
|
import { useLocale } from '../../../hooks/useLocale';
|
||||||
import { App } from '../../../stores/app';
|
import { App } from '../../../stores/app';
|
||||||
import { Duel } from '../../../stores/duel';
|
import { Duel } from '../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral';
|
|
||||||
import { classIcons } from '../../ClassIcon';
|
import { classIcons } from '../../ClassIcon';
|
||||||
import { LinkI18n } from '../../LinkI18n';
|
|
||||||
import { ScienceIcon } from '../../ScienceIcon';
|
|
||||||
import { TankSearch } from '../../TankSearch';
|
|
||||||
import { Listing } from './components/Listing';
|
import { Listing } from './components/Listing';
|
||||||
|
|
||||||
const [provisionDefinitions, modelDefinitions] = await Promise.all([
|
const NATIONAL_BANNER_POSITION_OVERRIDES: Record<string, string> = {
|
||||||
awaitableProvisionDefinitions,
|
germany: '50% 35%',
|
||||||
awaitableModelDefinitions,
|
france: '50% 35%',
|
||||||
]);
|
other: '50% 35%',
|
||||||
|
};
|
||||||
|
|
||||||
export function MetaSection() {
|
export function MetaSection() {
|
||||||
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
||||||
const protagonist = Duel.use((state) => state.protagonist.tank);
|
const protagonist = Duel.use((state) => state.protagonist.tank);
|
||||||
const antagonist = Duel.use((state) => state.antagonist.tank);
|
|
||||||
const ClassIcon = classIcons[protagonist.class];
|
const ClassIcon = classIcons[protagonist.class];
|
||||||
const compareTanks =
|
const { locale, strings } = useLocale();
|
||||||
protagonist.id === antagonist.id
|
|
||||||
? [protagonist.id]
|
console.log(protagonist.nation);
|
||||||
: [protagonist.id, antagonist.id];
|
|
||||||
const mutateDuel = Duel.useMutation();
|
|
||||||
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
|
||||||
const [showSwapDialog, setShowSwapDialog] = useState(false);
|
|
||||||
const { locale, strings, unwrap } = useLocale();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex justify="center" align="center">
|
<Box
|
||||||
<Flex direction="column" align="center" gap="6">
|
style={{
|
||||||
|
background: `url(/assets/images/national-wallpapers/${protagonist.nation}.jpg)`,
|
||||||
|
backgroundPosition:
|
||||||
|
NATIONAL_BANNER_POSITION_OVERRIDES[protagonist.nation] ?? 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
background: `url(${asset(`flags/scratched/${protagonist.nation}.webp`)})`,
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundSize: '53rem',
|
||||||
|
backgroundPosition: '-25% 50%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Flex
|
<Flex
|
||||||
gap={{ initial: '0', sm: '6' }}
|
justify="center"
|
||||||
direction={{ initial: 'column', sm: 'row' }}
|
align="center"
|
||||||
|
py="6rem"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(${Var('gray-1')}, ${Var('black-a8')}, ${Var('black-a8')}, ${Var('gray-1')})`,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Flex direction="column" width="100%">
|
<Flex direction="column" align="center" gap="6">
|
||||||
{protagonist.name_full && (
|
<Flex
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.full_name}>
|
gap={{ initial: '0', sm: '8' }}
|
||||||
{unwrap(protagonist.name_full)}
|
direction={{ initial: 'column', sm: 'row' }}
|
||||||
</Listing>
|
|
||||||
)}
|
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.nation}>
|
|
||||||
<Flex align="center" gap="1">
|
|
||||||
<img
|
|
||||||
style={{ width: '1em', height: '1em' }}
|
|
||||||
alt={protagonist.nation}
|
|
||||||
src={asset(`flags/circle/${protagonist.nation}.webp`)}
|
|
||||||
/>
|
|
||||||
{
|
|
||||||
strings.common.nations[
|
|
||||||
protagonist.nation as keyof typeof strings.common.nations
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</Flex>
|
|
||||||
</Listing>
|
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.class}>
|
|
||||||
<Flex align="center" gap="1">
|
|
||||||
<ClassIcon width="1em" height="1em" />
|
|
||||||
{strings.common.tank_class_short[protagonist.class]}
|
|
||||||
</Flex>
|
|
||||||
</Listing>
|
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.tier}>
|
|
||||||
{TIER_ROMAN_NUMERALS[protagonist.tier]}
|
|
||||||
</Listing>
|
|
||||||
<Listing
|
|
||||||
label={strings.website.tools.tankopedia.meta.type}
|
|
||||||
color={
|
|
||||||
protagonist.type === TankType.COLLECTOR
|
|
||||||
? 'blue'
|
|
||||||
: protagonist.type === TankType.PREMIUM
|
|
||||||
? 'amber'
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{strings.common.tree_type[protagonist.type]}
|
<Flex direction="column" width="100%" gap="2">
|
||||||
</Listing>
|
<Listing label={strings.website.tools.tankopedia.meta.nation}>
|
||||||
</Flex>
|
<Flex align="center" gap="1">
|
||||||
|
<img
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
alt={protagonist.nation}
|
||||||
|
src={asset(`flags/circle/${protagonist.nation}.webp`)}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
strings.common.nations[
|
||||||
|
protagonist.nation as keyof typeof strings.common.nations
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.class}>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
<ClassIcon width="1em" height="1em" />
|
||||||
|
{strings.common.tank_class_short[protagonist.class]}
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.tier}>
|
||||||
|
{TIER_ROMAN_NUMERALS[protagonist.tier]}
|
||||||
|
</Listing>
|
||||||
|
<Listing
|
||||||
|
label={strings.website.tools.tankopedia.meta.type}
|
||||||
|
color={
|
||||||
|
protagonist.type === TankType.COLLECTOR
|
||||||
|
? 'blue'
|
||||||
|
: protagonist.type === TankType.PREMIUM
|
||||||
|
? 'amber'
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{strings.common.tree_type[protagonist.type]}
|
||||||
|
</Listing>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
<Flex direction="column" width="100%">
|
<Flex direction="column" width="100%" gap="2">
|
||||||
{developerMode && (
|
{developerMode && (
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.dev_id}>
|
<Listing label={strings.website.tools.tankopedia.meta.dev_id}>
|
||||||
<Code>{protagonist.id}</Code>
|
<Code>{protagonist.id}</Code>
|
||||||
</Listing>
|
</Listing>
|
||||||
)}
|
)}
|
||||||
{protagonist.type === TankType.PREMIUM && (
|
{protagonist.type === TankType.PREMIUM && (
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.purchase}>
|
<Listing
|
||||||
<Flex align="center" gap="1">
|
label={strings.website.tools.tankopedia.meta.purchase}
|
||||||
{protagonist.price.value / 400}
|
>
|
||||||
<img
|
<Flex align="center" gap="1">
|
||||||
style={{ width: '1em', height: '1em' }}
|
{protagonist.price.value / 400}
|
||||||
alt="gold"
|
<img
|
||||||
src={asset('icons/currencies/gold.webp')}
|
style={{ width: '1em', height: '1em' }}
|
||||||
/>
|
alt="gold"
|
||||||
</Flex>
|
src={asset('icons/currencies/gold.webp')}
|
||||||
</Listing>
|
/>
|
||||||
)}
|
</Flex>
|
||||||
<Listing
|
</Listing>
|
||||||
label={
|
)}
|
||||||
protagonist.type === TankType.RESEARCHABLE
|
<Listing
|
||||||
? strings.website.tools.tankopedia.meta.purchase
|
label={
|
||||||
: strings.website.tools.tankopedia.meta.restoration
|
protagonist.type === TankType.RESEARCHABLE
|
||||||
}
|
? strings.website.tools.tankopedia.meta.purchase
|
||||||
>
|
: strings.website.tools.tankopedia.meta.restoration
|
||||||
<Flex align="center" gap="1">
|
}
|
||||||
{protagonist.price.value.toLocaleString(locale)}
|
>
|
||||||
<img
|
<Flex align="center" gap="1">
|
||||||
style={{ width: '1em', height: '1em' }}
|
{protagonist.price.value.toLocaleString(locale)}
|
||||||
alt={TankPriceType[protagonist.price.type]}
|
<img
|
||||||
src={asset(
|
style={{ width: '1em', height: '1em' }}
|
||||||
`icons/currencies/${
|
alt={TankPriceType[protagonist.price.type]}
|
||||||
protagonist.price.type === TankPriceType.GOLD
|
src={asset(
|
||||||
? 'gold'
|
`icons/currencies/${
|
||||||
: 'silver'
|
protagonist.price.type === TankPriceType.GOLD
|
||||||
}.webp`,
|
? 'gold'
|
||||||
)}
|
: 'silver'
|
||||||
/>
|
}.webp`,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.sale}>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
{(protagonist.price.value / 2).toLocaleString(locale)}
|
||||||
|
<img
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
alt={TankPriceType[protagonist.price.type]}
|
||||||
|
src={asset(
|
||||||
|
`icons/currencies/${
|
||||||
|
protagonist.price.type === TankPriceType.GOLD
|
||||||
|
? 'gold'
|
||||||
|
: 'silver'
|
||||||
|
}.webp`,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
{protagonist.research_cost && (
|
||||||
|
<Listing
|
||||||
|
label={strings.website.tools.tankopedia.meta.research}
|
||||||
|
>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
{(
|
||||||
|
protagonist.research_cost.research_cost_type!
|
||||||
|
.value as number
|
||||||
|
).toLocaleString(locale)}
|
||||||
|
<img
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
alt="xp"
|
||||||
|
src={asset('icons/currencies/xp.webp')}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Listing>
|
</Flex>
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.sale}>
|
|
||||||
<Flex align="center" gap="1">
|
|
||||||
{(protagonist.price.value / 2).toLocaleString(locale)}
|
|
||||||
<img
|
|
||||||
style={{ width: '1em', height: '1em' }}
|
|
||||||
alt={TankPriceType[protagonist.price.type]}
|
|
||||||
src={asset(
|
|
||||||
`icons/currencies/${
|
|
||||||
protagonist.price.type === TankPriceType.GOLD
|
|
||||||
? 'gold'
|
|
||||||
: 'silver'
|
|
||||||
}.webp`,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Listing>
|
|
||||||
{protagonist.research_cost && (
|
|
||||||
<Listing label={strings.website.tools.tankopedia.meta.research}>
|
|
||||||
<Flex align="center" gap="1">
|
|
||||||
{(
|
|
||||||
protagonist.research_cost.research_cost_type!
|
|
||||||
.value as number
|
|
||||||
).toLocaleString(locale)}
|
|
||||||
<img
|
|
||||||
style={{ width: '1em', height: '1em' }}
|
|
||||||
alt="xp"
|
|
||||||
src={asset('icons/currencies/xp.webp')}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Listing>
|
|
||||||
)}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Box>
|
||||||
</Flex>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||