feat: localize game assets

This commit is contained in:
tresabhi committed 2025-01-14 19:22:41 -06:00
1 parent d8459d373c
commit ef9778ea96
90 files changed
+336 -251

No files matched your search

@@ -27,6 +27,7 @@ import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/pr
import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits';
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
import { useEquipment } from '../../../../../hooks/useEquipment';
import { useLocale } from '../../../../../hooks/useLocale';
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
import { Duel } from '../../../../../stores/duel';
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
@@ -39,6 +40,7 @@ const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
]);
export function Characteristics() {
const { unwrap } = useLocale();
const mutateDuel = Duel.useMutation();
const crewSkills = TankopediaEphemeral.use((state) => state.skills);
const penetrationDistanceInput = useRef<HTMLInputElement>(null);
@@ -146,7 +148,7 @@ export function Characteristics() {
<Flex>
{gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => (
<Tooltip content={thisShell.name} key={thisShell.id}>
<Tooltip content={unwrap(thisShell.name)} key={thisShell.id}>
<IconButton
color={thisShell.id === shell.id ? undefined : 'gray'}
variant="soft"
@@ -172,7 +174,7 @@ export function Characteristics() {
}}
>
<img
alt={thisShell.name}
alt={unwrap(thisShell.name)}
width={16}
height={16}
src={asset(`icons/shells/${thisShell.icon}.webp`)}
@@ -103,7 +103,7 @@ function ModuleButton({
gap={isTank ? '1' : undefined}
>
<Text size="1" color="gray">
{formatCompact(unlock.cost.value)}
{formatCompact(locale, unlock.cost.value)}
</Text>
<img
@@ -3,6 +3,7 @@ import { Box, Flex, Heading, Text } from '@radix-ui/themes';
import { awaitableConsumableDefinitions } from '../../core/awaitables/consumableDefinitions';
import { awaitableGameDefinitions } from '../../core/awaitables/gameDefinitions';
import { awaitableProvisionDefinitions } from '../../core/awaitables/provisionDefinitions';
import { useLocale } from '../../hooks/useLocale';
import { Duel } from '../../stores/duel';
const [gameDefinitions, consumableDefinitions, provisionDefinitions] =
@@ -13,6 +14,7 @@ const [gameDefinitions, consumableDefinitions, provisionDefinitions] =
]);
export function GameModeSection() {
const { unwrap } = useLocale();
const tank = Duel.use((state) => state.protagonist.tank);
const roles = Object.entries(tank.roles);
@@ -67,7 +69,7 @@ export function GameModeSection() {
justify="center"
>
<Text size="4" weight="bold">
{gameMode.name}
{unwrap(gameMode.name)}
</Text>
<Flex direction="column">
@@ -84,9 +86,9 @@ export function GameModeSection() {
objectFit: 'contain',
}}
src={asset(`icons/provisions/${id}.webp`)}
alt={provisions.name}
alt={unwrap(provisions.name)}
/>
{provisions.name}
{unwrap(provisions.name)}
</Flex>
</Text>
);
@@ -104,9 +106,9 @@ export function GameModeSection() {
objectFit: 'contain',
}}
src={asset(`icons/consumables/${id}.webp`)}
alt={consumable.name}
alt={unwrap(consumable.name)}
/>
{consumable.name}
{unwrap(consumable.name)}
</Flex>
</Text>
);
@@ -89,7 +89,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
const antagonistUniqueGuns = uniqueGuns(antagonistTank.turrets);
const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const { strings } = useLocale();
const { strings, unwrap } = useLocale();
return (
<>
@@ -244,7 +244,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
}}
>
<img
alt={thisShell.name}
alt={unwrap(thisShell.name)}
src={asset(`icons/shells/${thisShell.icon}.webp`)}
style={{
width: '50%',
@@ -362,7 +362,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
<Button variant="ghost">
<Flex gap="2" align="center">
<SmallTankIcon id={antagonistTank.id} size={16} />
{antagonistTank.name}
{unwrap(antagonistTank.name)}
</Flex>
</Button>
</Dialog.Trigger>
@@ -6,6 +6,7 @@ import { NAVBAR_HEIGHT } from '../../../constants/navbar';
import { awaitableTankDefinitions } from '../../../core/awaitables/tankDefinitions';
import { Var } from '../../../core/radix/var';
import { useFullScreen } from '../../../hooks/useFullScreen';
import { useLocale } from '../../../hooks/useLocale';
import { Duel } from '../../../stores/duel';
import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral';
import type { MaybeSkeletonComponentProps } from '../../../types/maybeSkeletonComponentProps';
@@ -18,6 +19,7 @@ import { TankSandboxLoader } from './components/TankSandboxLoader';
const tankDefinitions = await awaitableTankDefinitions;
export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
const { unwrap } = useLocale();
const canvas = useRef<HTMLCanvasElement>(null);
const isFullScreen = useFullScreen();
const protagonist = Duel.use((state) => state.protagonist.tank);
@@ -117,7 +119,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
wrap="nowrap"
color={treeColor}
>
{protagonist.name}
{unwrap(protagonist.name)}
</Heading>
</Flex>
@@ -9,6 +9,7 @@ import {
Text,
} from '@radix-ui/themes';
import { useState } from 'react';
import { useLocale } from '../../../../../../hooks/useLocale';
import { App } from '../../../../../../stores/app';
import { Duel } from '../../../../../../stores/duel';
import { Stars } from '../../Stars';
@@ -24,6 +25,7 @@ export function VoteCaster() {
const [postVote, setPostVote] = useState<boolean | null>(null);
// true = open, false = closed, null = casting
const [showDialogue, setShowDialogue] = useState<boolean | null>(false);
const { unwrap } = useLocale();
return (
<>
@@ -35,7 +37,7 @@ export function VoteCaster() {
</Dialog.Trigger>
<Dialog.Content maxWidth="23rem">
<Dialog.Title>Voting for {tank.name}</Dialog.Title>
<Dialog.Title>Voting for {unwrap(tank.name)}</Dialog.Title>
<Flex direction="column" mt="4">
<Flex align="center" justify="between">
@@ -1,6 +1,7 @@
import { formatCompact } from '@blitzkit/core';
import { Flex, Heading, Skeleton, Text } from '@radix-ui/themes';
import { memo } from 'react';
import { useLocale } from '../../../../../hooks/useLocale';
import { useTankVotes } from '../../../../../hooks/useTankVotes';
import { App } from '../../../../../stores/app';
import { Duel } from '../../../../../stores/duel';
@@ -13,13 +14,14 @@ export const Votes = memo(
const id = Duel.use((state) => state.protagonist.tank.id);
const votes = useTankVotes(id);
const wargaming = App.use((state) => state.logins.wargaming);
const { locale } = useLocale();
return (
<Flex direction="column" gap="3">
<Flex justify="between" align="center">
<Heading size="4">
{!votes && <Skeleton height="1em" width="4rem" />}
{votes && formatCompact(votes.votes)}{' '}
{votes && formatCompact(locale, votes.votes)}{' '}
{votes && (votes.votes > 1 ? 'votes' : 'vote')}
</Heading>
@@ -38,7 +38,7 @@ export function MetaSection() {
const mutateDuel = Duel.useMutation();
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const [showSwapDialog, setShowSwapDialog] = useState(false);
const { locale, strings } = useLocale();
const { locale, strings, unwrap } = useLocale();
return (
<Flex justify="center" align="center">
@@ -124,7 +124,7 @@ export function MetaSection() {
<Flex direction="column" width="100%">
{protagonist.name_full && (
<Listing label={strings.website.tools.tankopedia.meta.full_name}>
{protagonist.name_full}
{unwrap(protagonist.name_full)}
</Listing>
)}
<Listing label={strings.website.tools.tankopedia.meta.nation}>
@@ -20,7 +20,7 @@ const [tankDefinitions, averageDefinitions] = await Promise.all([
]);
export function Node({ id, highlight, nextIds, skeleton }: NodeProps) {
const { locale, strings } = useLocale();
const { locale, strings, unwrap } = useLocale();
const xpMultiplier = TankopediaEphemeral.use((state) => state.xpMultiplier);
const tank = tankDefinitions.tanks[id];
const nextTanks = nextIds?.map((id) => tankDefinitions.tanks[id]);
@@ -78,7 +78,7 @@ export function Node({ id, highlight, nextIds, skeleton }: NodeProps) {
}}
>
<img
alt={tank.name}
alt={unwrap(tank.name)}
src={asset(`icons/tanks/big/${id}.webp`)}
width={64}
height={64}
@@ -92,7 +92,7 @@ export function Node({ id, highlight, nextIds, skeleton }: NodeProps) {
<Text color="gray" size="1">
{TIER_ROMAN_NUMERALS[tank.tier]}
</Text>
<Text wrap="nowrap">{tank.name}</Text>
<Text wrap="nowrap">{unwrap(tank.name)}</Text>
</Flex>
<Flex gap="2" align="center">
<Text color="gray" size="1" wrap="nowrap">