From 179ce62a55b4edaa30421cce94636f962ebc2972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sun, 25 May 2025 15:18:22 -0500 Subject: [PATCH] feat: strings --- packages/bot/tsconfig.json | 9 +- packages/core/src/blitzkit/index.ts | 1 + packages/core/src/blitzkit/slugify.ts | 16 ++ packages/core/tsconfig.json | 5 +- .../scripts/src/buildAssets/definitions.ts | 14 +- packages/scripts/tsconfig.json | 5 +- .../website/src/components/ClassIcon/index.ts | 25 ++- .../components/Tankopedia_ue/MetaSection.tsx | 181 ++++++++++++++++++ packages/website/src/core/i18n/getStrings.ts | 4 +- .../website/src/pages/[...locale]/index.astro | 26 ++- .../[...locale]/tanks-ue/[id]/_index.tsx | 29 +++ .../[...locale]/tanks-ue/[id]/index.astro | 43 +++++ .../pages/[...locale]/tanks-ue/index.astro | 46 +++++ .../src/stores/tankopediaEphemeral_ue.ts | 18 ++ packages/website/tsconfig.json | 3 +- submodules/blitzkit-closed | 2 +- tsconfig.json | 8 +- 17 files changed, 400 insertions(+), 35 deletions(-) create mode 100644 packages/core/src/blitzkit/slugify.ts create mode 100644 packages/website/src/components/Tankopedia_ue/MetaSection.tsx create mode 100644 packages/website/src/pages/[...locale]/tanks-ue/[id]/_index.tsx create mode 100644 packages/website/src/pages/[...locale]/tanks-ue/[id]/index.astro create mode 100644 packages/website/src/pages/[...locale]/tanks-ue/index.astro create mode 100644 packages/website/src/stores/tankopediaEphemeral_ue.ts diff --git a/packages/bot/tsconfig.json b/packages/bot/tsconfig.json index d24722b0d..902639a19 100644 --- a/packages/bot/tsconfig.json +++ b/packages/bot/tsconfig.json @@ -1,4 +1,11 @@ { "extends": "../../tsconfig.json", - "include": ["src/**/*", "../core/src/blitzkit/supportedLocales.ts", "../i18n/src/unwrapper.ts"] + "include": [ + "src/**/*", + "../core/src/blitzkit/supportedLocales.ts", + "../i18n/src/unwrapper.ts" + ], + "compilerOptions": { + "baseUrl": "../../" + } } diff --git a/packages/core/src/blitzkit/index.ts b/packages/core/src/blitzkit/index.ts index c5c879837..459b2e08c 100644 --- a/packages/core/src/blitzkit/index.ts +++ b/packages/core/src/blitzkit/index.ts @@ -46,4 +46,5 @@ export * from './gallery'; export * from './metaSortTank'; export * from './popularTanks'; export * from './romanize'; +export * from './slugify'; export * from './youtubers'; diff --git a/packages/core/src/blitzkit/slugify.ts b/packages/core/src/blitzkit/slugify.ts new file mode 100644 index 000000000..8f9c366eb --- /dev/null +++ b/packages/core/src/blitzkit/slugify.ts @@ -0,0 +1,16 @@ +import { deburr } from 'lodash-es'; + +const nonAlphanumericRegex = /[^a-z0-9]/g; +const multipleDashesRegex = /--+/g; +const trailingDashRegex = /-$/g; +const leadingDashRegex = /^-/g; + +export function slugify(name: string) { + let slug = deburr(name).toLowerCase(); + slug = slug.replaceAll(nonAlphanumericRegex, '-'); + slug = slug.replaceAll(multipleDashesRegex, '-'); + slug = slug.replaceAll(trailingDashRegex, ''); + slug = slug.replaceAll(leadingDashRegex, ''); + + return slug; +} diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 2ee5d8b21..f2ca1d8d9 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,4 +1,7 @@ { "extends": "../../tsconfig.json", - "include": ["src/**/*", "../i18n/src/strings.ts"] + "include": ["src/**/*", "../i18n/src/strings.ts"], + "compilerOptions": { + "baseUrl": "../../" + } } diff --git a/packages/scripts/src/buildAssets/definitions.ts b/packages/scripts/src/buildAssets/definitions.ts index f794d50cf..759959b69 100644 --- a/packages/scripts/src/buildAssets/definitions.ts +++ b/packages/scripts/src/buildAssets/definitions.ts @@ -22,6 +22,7 @@ import { ResearchCost, ShellType, SkillDefinitions, + slugify, TankClass, TankDefinitions, TankPrice, @@ -37,7 +38,6 @@ import { SUPPORTED_LOCALES, } from '@blitzkit/i18n'; import { readdir } from 'fs/promises'; -import { deburr } from 'lodash-es'; import { parse as parsePath } from 'path'; import { Vector3Tuple } from 'three'; import { parse as parseYaml } from 'yaml'; @@ -49,11 +49,6 @@ import { DATA } from './constants'; import { Avatar } from './skillIcons'; import { TankParameters } from './tankIcons'; -const nonAlphanumericRegex = /[^a-z0-9]/g; -const multipleDashesRegex = /--+/g; -const trailingDashRegex = /-$/g; -const leadingDashRegex = /^-/g; - const nationSlugDiscriminators = { china: 'cn', european: 'eu', @@ -740,12 +735,7 @@ export async function definitions() { ? getString(tank.shortUserString) : undefined) ?? getString(tank.userString) ).locales.en; - - let slug = deburr(name).toLowerCase(); - slug = slug.replaceAll(nonAlphanumericRegex, '-'); - slug = slug.replaceAll(multipleDashesRegex, '-'); - slug = slug.replaceAll(trailingDashRegex, ''); - slug = slug.replaceAll(leadingDashRegex, ''); + const slug = slugify(name); idToNation[tankId] = nation; diff --git a/packages/scripts/tsconfig.json b/packages/scripts/tsconfig.json index 52d43eaaa..70747e7dc 100644 --- a/packages/scripts/tsconfig.json +++ b/packages/scripts/tsconfig.json @@ -1,4 +1,7 @@ { "extends": "../../tsconfig.json", - "include": ["src/**/*"] + "include": ["src/**/*"], + "compilerOptions": { + "baseUrl": "../../" + } } diff --git a/packages/website/src/components/ClassIcon/index.ts b/packages/website/src/components/ClassIcon/index.ts index 018ee4cde..423cdb584 100644 --- a/packages/website/src/components/ClassIcon/index.ts +++ b/packages/website/src/components/ClassIcon/index.ts @@ -1,16 +1,29 @@ -import { TankClass } from '@blitzkit/core'; +import { TankClass as TankClass_dava } from '@blitzkit/core'; +import { TankClass } from '@protos/blitz_static_tank_component'; +import { QuestionMarkIcon } from '@radix-ui/react-icons'; import type { ComponentProps, ReactNode } from 'react'; import { ClassHeavy } from './components/ClassHeavy'; import { ClassLight } from './components/ClassLight'; import { ClassMedium } from './components/ClassMedium'; import { ClassTankDestroyer } from './components/ClassTankDestroyer'; -export const classIcons: Record< +export const classIcons_ue: Record< TankClass, + ((props: ComponentProps<'svg'>) => ReactNode) | typeof QuestionMarkIcon +> = { + [TankClass.TANK_CLASS_UNSPECIFIED]: QuestionMarkIcon, + [TankClass.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer, + [TankClass.TANK_CLASS_HEAVY]: ClassHeavy, + [TankClass.TANK_CLASS_LIGHT]: ClassLight, + [TankClass.TANK_CLASS_MEDIUM]: ClassMedium, +}; + +export const classIcons: Record< + TankClass_dava, (props: ComponentProps<'svg'>) => ReactNode > = { - [TankClass.TANK_DESTROYER]: ClassTankDestroyer, - [TankClass.HEAVY]: ClassHeavy, - [TankClass.LIGHT]: ClassLight, - [TankClass.MEDIUM]: ClassMedium, + [TankClass_dava.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer, + [TankClass_dava.TANK_CLASS_HEAVY]: ClassHeavy, + [TankClass_dava.TANK_CLASS_LIGHT]: ClassLight, + [TankClass_dava.TANK_CLASS_MEDIUM]: ClassMedium, }; diff --git a/packages/website/src/components/Tankopedia_ue/MetaSection.tsx b/packages/website/src/components/Tankopedia_ue/MetaSection.tsx new file mode 100644 index 000000000..52f9b884f --- /dev/null +++ b/packages/website/src/components/Tankopedia_ue/MetaSection.tsx @@ -0,0 +1,181 @@ +import { + Nation, + TankClass, + TankType, + Tier, +} from '@protos/blitz_static_tank_component'; +import { Box, Code, Flex } from '@radix-ui/themes'; +import { asset } from 'packages/core/src'; +import { Var } from '../../core/radix/var'; +import { useLocale } from '../../hooks/useLocale'; +import { App } from '../../stores/app'; +import { TankopediaEphemeral_ue } from '../../stores/tankopediaEphemeral_ue'; +import { classIcons_ue } from '../ClassIcon'; +import { Listing } from '../Tankopedia/MetaSection/components/Listing'; + +const NATIONAL_BANNER_POSITION_OVERRIDES: Record = { + germany: '50% 35%', + france: '50% 35%', + other: '50% 35%', +}; + +export function MetaSection() { + const developerMode = App.useDeferred((state) => state.developerMode, false); + const tank = TankopediaEphemeral_ue.use((state) => state.tank); + const ClassIcon = classIcons_ue[tank.tank_class]; + const { locale, strings } = useLocale(); + + return ( + + + + + + + + + + {Nation[tank.nation]} + {Nation[tank.nation]} + + + + + + {TankClass[tank.tank_class]} + + + + {Tier[tank.tier]} + + + {TankType[tank.tank_type]} + + + + + {developerMode && ( + + TANK_ID + + )} + {tank.tank_type === TankType.TANK_TYPE_PREMIUM && ( + + + {tank.price.value / 400} + gold + + + )} + + + {protagonist.price.value.toLocaleString(locale)} + {TankPriceType[protagonist.price.type]} + + + + + {(protagonist.price.value / 2).toLocaleString(locale)} + {TankPriceType[protagonist.price.type]} + + + {protagonist.research_cost && ( + + + {( + protagonist.research_cost.research_cost_type! + .value as number + ).toLocaleString(locale)} + xp + + + )} + + + + + + + + ); +} diff --git a/packages/website/src/core/i18n/getStrings.ts b/packages/website/src/core/i18n/getStrings.ts index ccd3480bc..64b7395ab 100644 --- a/packages/website/src/core/i18n/getStrings.ts +++ b/packages/website/src/core/i18n/getStrings.ts @@ -1,6 +1,6 @@ -import { DEFAULT_LOCALE, STRINGS, type SupportedLocale } from '@blitzkit/i18n'; +import { STRINGS, type SupportedLocale } from '@blitzkit/i18n'; -export function getStrings(locale: string = DEFAULT_LOCALE) { +export function getStrings(locale: string) { if (locale in STRINGS) return STRINGS[locale as SupportedLocale]; throw new Error(`Unsupported locale: ${locale}`); } diff --git a/packages/website/src/pages/[...locale]/index.astro b/packages/website/src/pages/[...locale]/index.astro index 1bb98cfb1..c3d89906b 100644 --- a/packages/website/src/pages/[...locale]/index.astro +++ b/packages/website/src/pages/[...locale]/index.astro @@ -1,7 +1,8 @@ --- import { AstroSeo } from '@astrolib/seo'; import { assertSecret } from '@blitzkit/core'; -import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@blitzkit/i18n'; +import { DEFAULT_LOCALE } from '@blitzkit/i18n'; +import locales from '@blitzkit/i18n/locales.json'; import { literals } from '@blitzkit/i18n/src/literals'; import { Box, Flex, Heading, Link } from '@radix-ui/themes'; import type { GetStaticPaths } from 'astro'; @@ -25,15 +26,20 @@ import BaseLayout from '../../layouts/BaseLayout.astro'; const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH); const locale = Astro.params.locale ?? DEFAULT_LOCALE; -const strings = getStrings(Astro.params.locale); +const strings = getStrings(Astro.props.locale); export const getStaticPaths = (() => { - return [ - ...SUPPORTED_LOCALES.filter((locale) => locale !== DEFAULT_LOCALE).map( - (locale) => ({ params: { locale } }), - ), - { params: { locale: undefined } }, - ]; + // return [ + // ...SUPPORTED_LOCALES.filter((locale) => locale !== DEFAULT_LOCALE).map( + // (locale) => ({ params: { locale } }), + // ), + // { params: { locale: undefined } }, + // ]; + + return locales.supported.map(({ locale, blitz }) => ({ + params: { locale: locale === locales.default ? undefined : locale }, + props: { locale, blitzLocale: blitz ?? locale }, + })); }) satisfies GetStaticPaths; --- @@ -79,7 +85,9 @@ export const getStaticPaths = (() => { > {literals(strings.website.home.help_translate, [ 'BlitzKit', - strings.common.locales[locale], + strings.common.locales[ + locale as keyof typeof strings.common.locales + ], ])} diff --git a/packages/website/src/pages/[...locale]/tanks-ue/[id]/_index.tsx b/packages/website/src/pages/[...locale]/tanks-ue/[id]/_index.tsx new file mode 100644 index 000000000..1cc36d7b7 --- /dev/null +++ b/packages/website/src/pages/[...locale]/tanks-ue/[id]/_index.tsx @@ -0,0 +1,29 @@ +import type { CompensationComponent } from '@protos/blitz_static_compensation_component'; +import { type TankCatalogComponent } from '@protos/blitz_static_tank_component'; +import { PageWrapper } from 'packages/website/src/components/PageWrapper'; +import { MetaSection } from 'packages/website/src/components/Tankopedia_ue/MetaSection'; +import { + LocaleProvider, + type LocaleAcceptorProps, +} from 'packages/website/src/hooks/useLocale'; +import { App } from 'packages/website/src/stores/app'; +import { TankopediaEphemeral_ue } from 'packages/website/src/stores/tankopediaEphemeral_ue'; + +interface PageProps extends LocaleAcceptorProps { + tank: TankCatalogComponent; + compensation: CompensationComponent; +} + +export function Page({ tank, compensation, locale }: PageProps) { + return ( + + + + + + + + + + ); +} diff --git a/packages/website/src/pages/[...locale]/tanks-ue/[id]/index.astro b/packages/website/src/pages/[...locale]/tanks-ue/[id]/index.astro new file mode 100644 index 000000000..a6e5a80e8 --- /dev/null +++ b/packages/website/src/pages/[...locale]/tanks-ue/[id]/index.astro @@ -0,0 +1,43 @@ +--- +import type { + CatalogItemsComponent, + TankCatalogComponent, +} from '@blitzkit/closed/src/unreal/protos'; +import type { GetStaticPaths } from 'astro'; +import { metadata } from '../../../../core/blitz/metadata'; +import BaseLayout from '../../../../layouts/BaseLayout.astro'; +import { getStaticPaths as parentGetStaticPaths } from '../index.astro'; +import { Page } from './_index'; + +export const getStaticPaths = (async () => { + const tanks = await metadata + .get('CatalogItemsGroupEntity.all_tanks') + .then((components) => + components.get('catalogItemsGroupComponent'), + ); + const parentPaths = parentGetStaticPaths(); + + return tanks.catalog_items + .map((item) => { + const id = item.replace('TankEntity.', ''); + + return parentPaths.map((parent) => ({ + params: { ...parent.params, id }, + props: { item }, + })); + }) + .flat(); +}) satisfies GetStaticPaths; + +const { id, locale } = Astro.params; +const { item } = Astro.props; +const tank = await metadata + .get(item) + .then((components) => + components.get('tankCatalogComponent'), + ); +--- + + + + diff --git a/packages/website/src/pages/[...locale]/tanks-ue/index.astro b/packages/website/src/pages/[...locale]/tanks-ue/index.astro new file mode 100644 index 000000000..0aac83088 --- /dev/null +++ b/packages/website/src/pages/[...locale]/tanks-ue/index.astro @@ -0,0 +1,46 @@ +--- +import { slugify } from '@blitzkit/core'; +import locales from '@blitzkit/i18n/locales.json'; +import type { CatalogItemsComponent } from '@protos/blitz_static_catalog_items_group_component'; +import { TankCatalogComponent } from '@protos/blitz_static_tank_component'; +import { metadata } from '../../../core/blitz/metadata'; + +export { getStaticPaths } from '../index.astro'; + +const { blitzLocale } = Astro.props; +const allTanks = await metadata + .get('CatalogItemsGroupEntity.all_tanks') + .then((components) => + components.get('catalogItemsGroupComponent'), + ); +const gameStrings = await metadata + .strings(blitzLocale) + .then((strings) => strings.subset(['TankEntity'])); +const gameStringsDefault = await metadata + .strings(locales.default) + .then((strings) => strings.subset(['TankEntity'])); +const tanks: { tank: TankCatalogComponent; slug: string; id: string }[] = []; + +for (const tankComponentId of allTanks.catalog_items) { + const tank = await metadata.get(tankComponentId).then((components) => { + return components.get('tankCatalogComponent'); + }); + const nameEn = gameStringsDefault[tank.name!.value]; + const slug = slugify(nameEn); + + tanks.push({ tank, slug, id: tankComponentId }); +} +--- + +{ + tanks.map(({ tank, slug, id }) => { + return ( + <> + + {gameStrings[tank.name!.value] ?? `MISSING NAME (${id})`} + +
+ + ); + }) +} diff --git a/packages/website/src/stores/tankopediaEphemeral_ue.ts b/packages/website/src/stores/tankopediaEphemeral_ue.ts new file mode 100644 index 000000000..2d1b279fb --- /dev/null +++ b/packages/website/src/stores/tankopediaEphemeral_ue.ts @@ -0,0 +1,18 @@ +import type { CompensationComponent } from '@protos/blitz_static_compensation_component'; +import type { TankCatalogComponent } from '@protos/blitz_static_tank_component'; +import { create } from 'zustand'; +import { subscribeWithSelector } from 'zustand/middleware'; +import { createContextualStore } from '../core/zustand/createContextualStore'; + +interface TankopediaEphemeral_ue { + tank: TankCatalogComponent; + compensation: CompensationComponent; +} + +export const TankopediaEphemeral_ue = createContextualStore( + (data: TankopediaEphemeral_ue) => { + return create()( + subscribeWithSelector(() => data), + ); + }, +); diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json index db4d5dcac..8a7b14cd6 100644 --- a/packages/website/tsconfig.json +++ b/packages/website/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "react", - "types": ["vite/client"] + "types": ["vite/client"], + "baseUrl": "../../" } } diff --git a/submodules/blitzkit-closed b/submodules/blitzkit-closed index 6ee56809b..25f8838ba 160000 --- a/submodules/blitzkit-closed +++ b/submodules/blitzkit-closed @@ -1 +1 @@ -Subproject commit 6ee56809b8a9c85fb98f68d81efbd55b454f9d32 +Subproject commit 25f8838ba5968c437099a01e53c35ade912f1a03 diff --git a/tsconfig.json b/tsconfig.json index f5912f4e8..5b47a5223 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,11 +14,17 @@ "allowJs": true, "incremental": true, "isolatedModules": true, + "plugins": [ { "name": "next" } - ] + ], + + "baseUrl": "./", + "paths": { + "@protos/*": ["submodules/blitzkit-closed/src/unreal/protos/*"] + } }, "exclude": ["node_modules/**/*", "dist", ".next"] }