feat: more hot garbage

This commit is contained in:
TrèsAbhi committed 2025-05-26 18:29:29 -05:00
1 parent d0170d53e4
commit 788edf5bdf
30 files changed
+196 -238

No files matched your search

BIN
View File
Binary file not shown.
+6
View File
@@ -45,14 +45,20 @@
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"protobufjs": "^7.5.2", "protobufjs": "^7.5.2",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"quicklime": "^1.2.0", "quicklime": "^1.2.0",
"sharp": "^0.33.5" "sharp": "^0.33.5"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/react": "^4.3.0",
"@types/bun": "latest", "@types/bun": "latest",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/react": "^19.1.5",
"@types/react-dom": "^19.1.5",
"@types/node": "^22.14.1", "@types/node": "^22.14.1",
"astro": "^5.8.0",
"prettier": "^3.5.3", "prettier": "^3.5.3",
"prisma": "^6.6.0", "prisma": "^6.6.0",
"typescript": "^5.8.3" "typescript": "^5.8.3"
-1
View File
@@ -9,7 +9,6 @@
"satori": "^0.10.14", "satori": "^0.10.14",
"@resvg/resvg-js": "^2.6.2", "@resvg/resvg-js": "^2.6.2",
"discord.js": "^14.16.3", "discord.js": "^14.16.3",
"react": "^18.3.1",
"@radix-ui/colors": "^3.0.0", "@radix-ui/colors": "^3.0.0",
"fuzzysort": "^2.0.4", "fuzzysort": "^2.0.4",
"bepaint": "^0.1.0-beta.3", "bepaint": "^0.1.0-beta.3",
@@ -0,0 +1,28 @@
import { CatalogItem } from '@protos/blitz_items';
import { Any } from '@protos/google/protobuf/any';
import { MessageFns } from '../protos';
export class CatalogItemAccessor {
private components: Record<string, Any> = {};
constructor(item: CatalogItem) {
for (const component of item.components) {
if (
component.value === undefined ||
component.value.component === undefined
) {
continue;
}
this.components[component.key] = component.value.component;
}
}
get<Type>(Message: MessageFns<Type>, component: string) {
if (component in this.components) {
return Message.decode(this.components[component].value);
}
throw new Error(`Unknown component: ${component}`);
}
}
+1
View File
@@ -1,4 +1,5 @@
export * from './canSplash'; export * from './canSplash';
export * from './catalogItemAccessor';
export * from './clans'; export * from './clans';
export * from './classes'; export * from './classes';
export * from './constants'; export * from './constants';
+32 -4
View File
@@ -1,10 +1,38 @@
import { CatalogItem } from '@protos/blitz_items';
import { Metadata } from '@protos/blitz_metadata'; import { Metadata } from '@protos/blitz_metadata';
import { CatalogItemAccessor } from './catalogItemAccessor';
export class MetadataAccessor { export class UnpackedMetadataAccessor {
constructor() {} private items: Record<string, CatalogItemAccessor> = {};
loadMetadata(metadata: Metadata) { constructor(metadata: Metadata) {
for (const catalogItem of metadata.catalog_items) { for (const item of metadata.catalog_items) {
if (item.catalog_id in this.items) {
throw new Error(`Duplicate catalog ID: ${item.catalog_id}`);
}
this.items[item.catalog_id] = new CatalogItemAccessor(item);
} }
} }
get(item: string) {
if (item in this.items) return this.items[item];
throw new Error(`Unknown catalog ID: ${item}`);
}
}
export class DiscreteMetadataAccessor {
constructor(private base: string) {}
async get(item: string) {
const response = await fetch(`${this.base}/${item}.pb`);
if (!response.ok) throw new Error(`Unknown catalog ID: ${item}`);
const buffer = await response.arrayBuffer();
const catalogItem = CatalogItem.decode(new Uint8Array(buffer));
return new CatalogItemAccessor(catalogItem);
}
} }
+7 -5
View File
@@ -1,5 +1,5 @@
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { deburr } from 'lodash-es'; import { deburr } from 'lodash-es';
import { SUPPORTED_LOCALES } from '../../../i18n/src/strings';
import { I18nString } from '../protos'; import { I18nString } from '../protos';
import { fetchCamouflageDefinitions } from './camouflageDefinitions'; import { fetchCamouflageDefinitions } from './camouflageDefinitions';
import { fetchTankDefinitions } from './tankDefinitions'; import { fetchTankDefinitions } from './tankDefinitions';
@@ -26,8 +26,8 @@ export async function fetchTankNames() {
searchableNameDeburr, searchableNameDeburr,
camouflages: tank.camouflages camouflages: tank.camouflages
?.map((id) => ?.map((id) =>
SUPPORTED_LOCALES.map( locales.supported.map(
(locale) => ({ locale }) =>
camouflageDefinitions.camouflages[id]?.name.locales[locale], camouflageDefinitions.camouflages[id]?.name.locales[locale],
), ),
) )
@@ -42,9 +42,11 @@ export async function fetchTankNames() {
} }
export const SEARCH_KEYS = [ export const SEARCH_KEYS = [
...SUPPORTED_LOCALES.map((locale) => [ ...locales.supported
.map(({ locale }) => [
`searchableName.locales.${locale}`, `searchableName.locales.${locale}`,
`searchableNameDeburr.locales.${locale}`, `searchableNameDeburr.locales.${locale}`,
]).flat(), ])
.flat(),
'camouflages', 'camouflages',
]; ];
+2 -87
View File
@@ -1,89 +1,8 @@
import { merge } from 'ts-deepmerge'; import type en from '../strings/en.json';
import en from '../strings/en.json';
import es from '../strings/es.json';
import fr from '../strings/fr.json';
import ja from '../strings/ja.json';
import pl from '../strings/pl.json';
import pt from '../strings/pt.json';
import ru from '../strings/ru.json';
import uk from '../strings/uk.json';
import zh from '../strings/zh.json';
export type BlitzKitStrings = typeof en; export type BlitzKitStrings = typeof en;
const stringsRaw = { en, es, fr, ja, pl, pt, ru, uk, zh }; export const SUPPORTED_LOCALE_FLAGS: Record<string, string> = {
export const SUPPORTED_LOCALES = Object.keys(stringsRaw) as SupportedLocale[];
export const DEFAULT_LOCALE = SUPPORTED_LOCALES[0];
function redact(string: string) {
const matches = [...string.matchAll(/%s\d+/g)];
const characters = string
.split('')
.map((char) => (char === ' ' ? ' ' : '█')) as string[];
matches.forEach((match) => {
const start = match.index;
const matchText = match[0];
for (let i = 0; i < matchText.length; i++) {
characters[start + i] = matchText[i];
}
});
return characters.join('');
}
function nuke(object: TranslationTree) {
for (const key in object) {
const typedKey = key as keyof typeof object;
if (typeof object[typedKey] === 'string') {
const value = object[typedKey];
object[typedKey] = redact(value as string);
} else nuke(object[typedKey] as TranslationTree);
}
}
const stringsPartial: Partial<Record<SupportedLocale, TranslationTree>> = {};
for (const locale in stringsRaw) {
if (locale === DEFAULT_LOCALE) {
stringsPartial[DEFAULT_LOCALE] = stringsRaw[DEFAULT_LOCALE];
continue;
}
const localeStrings = stringsRaw[locale as SupportedLocale];
stringsPartial[locale as SupportedLocale] = merge(
stringsRaw[DEFAULT_LOCALE],
localeStrings,
);
if (import.meta.env.PUBLIC_DEBUG_MISSING_I18N === 'true') {
nuke(stringsPartial[locale as SupportedLocale]!);
}
}
export const STRINGS = stringsPartial as Record<
SupportedLocale,
BlitzKitStrings
>;
export type SupportedLocale = keyof typeof stringsRaw;
export const SUPPORTED_LOCALE_BLITZ_MAP: Record<SupportedLocale, string> = {
en: 'en',
es: 'es',
fr: 'fr',
ja: 'ja',
pt: 'pt',
ru: 'ru',
uk: 'uk',
zh: 'zh-Hans',
pl: 'pl',
};
export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
en: '🇺🇸', en: '🇺🇸',
es: '🇪🇸', es: '🇪🇸',
fr: '🇫🇷', fr: '🇫🇷',
@@ -94,7 +13,3 @@ export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
zh: '🇨🇳', zh: '🇨🇳',
pl: '🇵🇱', pl: '🇵🇱',
}; };
export type TranslationTree = { [key: string]: TranslationNode };
export type TranslationNode = string | TranslationTree;
+2 -2
View File
@@ -1,5 +1,5 @@
import { I18nString } from '@blitzkit/core'; import { I18nString } from '@blitzkit/core';
import { DEFAULT_LOCALE } from './strings'; import locales from '../locales.json' with { type: 'json' };
export function unwrapper(locale: string) { export function unwrapper(locale: string) {
return function (i18nString: I18nString) { return function (i18nString: I18nString) {
@@ -7,6 +7,6 @@ export function unwrapper(locale: string) {
return i18nString.locales[locale]; return i18nString.locales[locale];
} }
return i18nString.locales[DEFAULT_LOCALE]; return i18nString.locales[locales.default];
}; };
} }
+1 -1
View File
@@ -1,5 +1,5 @@
import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core'; import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core';
import locales from '@blitzkit/i18n/locales.json'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { extname } from 'path'; import { extname } from 'path';
import ProgressBar from 'progress'; import ProgressBar from 'progress';
import { commitAssets } from '../core/github/commitAssets'; import { commitAssets } from '../core/github/commitAssets';
+3 -3
View File
@@ -3,13 +3,13 @@
import partytown from '@astrojs/partytown'; import partytown from '@astrojs/partytown';
import react from '@astrojs/react'; import react from '@astrojs/react';
import sitemap from '@astrojs/sitemap'; import sitemap from '@astrojs/sitemap';
import { SUPPORTED_LOCALES } from '@blitzkit/i18n'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
export default defineConfig({ export default defineConfig({
i18n: { i18n: {
defaultLocale: 'en', defaultLocale: locales.default,
locales: [...SUPPORTED_LOCALES], locales: locales.supported.map(({ locale }) => locale),
routing: { routing: {
prefixDefaultLocale: false, prefixDefaultLocale: false,
}, },
+6 -11
View File
@@ -12,19 +12,19 @@
"dependencies": { "dependencies": {
"@astrojs/partytown": "^2.1.4", "@astrojs/partytown": "^2.1.4",
"@astrolib/seo": "^1.0.0-beta.8", "@astrolib/seo": "^1.0.0-beta.8",
"@blitzkit/closed": "workspace:*",
"@blitzkit/core": "workspace:*", "@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*", "@blitzkit/i18n": "workspace:*",
"@blitzkit/closed": "workspace:*",
"@fontsource/inter": "^5.2.5", "@fontsource/inter": "^5.2.5",
"@nanostores/persistent": "^0.10.2", "@nanostores/persistent": "^0.10.2",
"@nanostores/react": "^0.7.3", "@nanostores/react": "^0.7.3",
"@nivo/bar": "^0.87.0", "@nivo/bar": "^0.87.0",
"@nivo/line": "^0.88.0", "@nivo/line": "^0.88.0",
"@radix-ui/colors": "^3.0.0", "@radix-ui/colors": "^3.0.0",
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.2",
"@radix-ui/themes": "^3.1.4", "@radix-ui/themes": "^3.2.1",
"@react-three/drei": "^9.115.0", "@react-three/drei": "^10.0.8",
"@react-three/fiber": "^8.17.10", "@react-three/fiber": "^9.1.2",
"compare-versions": "^6.1.1", "compare-versions": "^6.1.1",
"echarts": "^5.5.1", "echarts": "^5.5.1",
"immer": "^10.1.1", "immer": "^10.1.1",
@@ -32,9 +32,7 @@
"markdown-to-jsx": "^7.5.0", "markdown-to-jsx": "^7.5.0",
"nanostores": "^0.11.3", "nanostores": "^0.11.3",
"quicklime": "^1.2.0", "quicklime": "^1.2.0",
"react": "^18.3.1",
"react-device-detect": "^2.2.3", "react-device-detect": "^2.2.3",
"react-dom": "^18.3.1",
"react-promise-suspense": "^0.3.4", "react-promise-suspense": "^0.3.4",
"three": "^0.169.0", "three": "^0.169.0",
"urlon": "^3.1.0", "urlon": "^3.1.0",
@@ -47,10 +45,7 @@
"@playform/compress": "^0.1.9", "@playform/compress": "^0.1.9",
"@playform/inline": "^0.1.2", "@playform/inline": "^0.1.2",
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/three": "^0.160.0", "@types/three": "^0.160.0",
"astro": "^4.16.7", "astro": "^4.16.7"
"astro-compressor": "^1.0.0"
} }
} }
@@ -1,4 +1,4 @@
import locales from '@blitzkit/i18n/locales.json'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { literals } from '@blitzkit/i18n/src/literals'; import { literals } from '@blitzkit/i18n/src/literals';
import { Flex, Text } from '@radix-ui/themes'; import { Flex, Text } from '@radix-ui/themes';
import fuzzysort from 'fuzzysort'; import fuzzysort from 'fuzzysort';
@@ -7,10 +7,10 @@ import type { BlitzKitStrings } from 'packages/i18n/src';
interface Props { interface Props {
locale: string; locale: string;
strings: BlitzKitStrings;
} }
const { strings, locale } = Astro.props; const { locale } = Astro.props;
const strings = await getStrings(locale);
const branchName = resolveBranchName(locale); const branchName = resolveBranchName(locale);
const isBranchNamed = branchName !== undefined; const isBranchNamed = branchName !== undefined;
--- ---
@@ -6,7 +6,6 @@ import {
type CompositeStats, type CompositeStats,
type CompositeStatsKey, type CompositeStatsKey,
} from '@blitzkit/core'; } from '@blitzkit/core';
import strings from '@blitzkit/i18n/strings/en.json';
import { amberDark, blueDark } from '@radix-ui/colors'; import { amberDark, blueDark } from '@radix-ui/colors';
import { Flex, Text, type FlexProps } from '@radix-ui/themes'; import { Flex, Text, type FlexProps } from '@radix-ui/themes';
import { times } from 'lodash-es'; import { times } from 'lodash-es';
@@ -53,7 +52,7 @@ export function BreakdownEmbedCard({
}: BreakdownEmbedCardProps) { }: BreakdownEmbedCardProps) {
const { useEmbedState, useRichText } = const { useEmbedState, useRichText } =
useEmbedStateCurry<typeof breakdownConfig>(); useEmbedStateCurry<typeof breakdownConfig>();
const { unwrap } = useLocale(); const { unwrap, strings } = useLocale();
return ( return (
<Flex <Flex
@@ -1,3 +1,9 @@
import { useEffect } from 'react';
export function TestComponent({ data }: { data: any }) { export function TestComponent({ data }: { data: any }) {
useEffect(() => {
console.log(data);
}, []);
return 'TestComponent'; return 'TestComponent';
} }
@@ -0,0 +1,3 @@
import { DiscreteMetadataAccessor } from 'packages/core/src';
export const discreteMetadata = new DiscreteMetadataAccessor('/api/catalog');
@@ -1,11 +1,8 @@
import { import { requestAutoProxyClient, unpackMetadata } from '@blitzkit/closed';
MetadataAccessor,
requestAutoProxyClient,
unpackMetadata,
} from '@blitzkit/closed';
import type { GetPackedMetadataAsyncResponse } from '@blitzkit/closed/src/unreal/protos/auto_legacy_proxy_client'; import type { GetPackedMetadataAsyncResponse } from '@blitzkit/closed/src/unreal/protos/auto_legacy_proxy_client';
import { UnpackedMetadataAccessor } from 'packages/core/src';
export const metadata = new MetadataAccessor( export const unpackedMetadata = new UnpackedMetadataAccessor(
await requestAutoProxyClient<GetPackedMetadataAsyncResponse>( await requestAutoProxyClient<GetPackedMetadataAsyncResponse>(
'GetPackedMetadataAsyncRequest', 'GetPackedMetadataAsyncRequest',
).then(unpackMetadata), ).then(unpackMetadata),
+6 -4
View File
@@ -1,6 +1,8 @@
import { STRINGS, type SupportedLocale } from '@blitzkit/i18n'; import en from '@strings/en.json' with { type: 'json' };
import { merge } from 'lodash-es';
import type { BlitzKitStrings } from 'packages/i18n/src';
export function getStrings(locale: string) { export async function getStrings(locale: string) {
if (locale in STRINGS) return STRINGS[locale as SupportedLocale]; const strings = await import(`../../../../i18n/strings/${locale}.json`);
throw new Error(`Unsupported locale: ${locale}`); return merge({}, en, strings) as BlitzKitStrings;
} }
+19 -30
View File
@@ -1,41 +1,30 @@
import { type BlitzKitStrings } from '@blitzkit/i18n'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { createContext, useContext, type ReactNode } from 'react'; import type { BlitzKitStrings } from 'packages/i18n/src';
import { createContext, use, useContext } from 'react';
interface LocaleContextContent { const LocaleContext = createContext<string | null>(null);
locale: string;
strings: BlitzKitStrings;
gameStrings: Record<string, string>;
}
type LocaleContextData = Omit<LocaleContextContent, 'gameStrings'> & {
gameStrings?: Record<string, string>;
};
const LocaleContext = createContext<LocaleContextContent | null>(null);
interface LocaleProviderProps { interface LocaleProviderProps {
data: LocaleContextData; locale: string;
children: ReactNode; children: React.ReactNode;
} }
export function LocaleProvider({ data, children }: LocaleProviderProps) { export function LocaleProvider({ locale, children }: LocaleProviderProps) {
const isSupported = locales.supported.some(
(supported) => supported.locale === locale,
);
if (!isSupported) throw new Error(`Unsupported locale: ${locale}`);
return ( return (
<LocaleContext.Provider value={{ gameStrings: {}, ...data }}> <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
{children}
</LocaleContext.Provider>
); );
} }
export function useLocale() { export function useLocale() {
const context = useContext(LocaleContext); const locale = useContext(LocaleContext);
const strings = use<BlitzKitStrings>(
fetch(`/api/strings/${locale}.json`).then((response) => response.json()),
);
if (!context) { return { locale, strings };
throw new Error('useLocale must be used within a LocaleProvider');
}
return context;
}
export interface LocaleAcceptorProps {
localeContext: LocaleContextContent;
} }
@@ -7,16 +7,17 @@ import Navbar from '../components/Navbar.astro';
import Party3 from '../components/Party3.astro'; import Party3 from '../components/Party3.astro';
import './base.css'; import './base.css';
import type { BlitzKitStrings } from 'packages/i18n/src'; import type { BlitzKitStrings } from 'packages/i18n/src';
import { getStrings } from '../core/i18n/getStrings';
export interface Props { export interface Props {
noFooter?: boolean; noFooter?: boolean;
noNavbar?: boolean; noNavbar?: boolean;
integrated?: boolean; integrated?: boolean;
locale: string; locale: string;
strings: BlitzKitStrings;
} }
const { noFooter, noNavbar, integrated, locale, strings } = Astro.props; const { noFooter, noNavbar, integrated, locale } = Astro.props;
const strings = await getStrings(locale);
--- ---
<html lang={locale}> <html lang={locale}>
@@ -30,25 +31,26 @@ const { noFooter, noNavbar, integrated, locale, strings } = Astro.props;
<Party3 /> <Party3 />
<script> <script>
import { SUPPORTED_LOCALES } from '@blitzkit/i18n'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { getBestLocale } from '../core/i18n/getBestLocale'; import { getBestLocale } from '../core/i18n/getBestLocale';
const isAPI = window.location.pathname.startsWith('/api'); const isAPI = window.location.pathname.startsWith('/api');
const isI18nPath = SUPPORTED_LOCALES.some((locale) => const isI18nPath = locales.supported.some(({ locale }) =>
window.location.pathname.startsWith(`/${locale}`), window.location.pathname.startsWith(`/${locale}`),
); );
const bestLocale = getBestLocale(); const bestLocale = getBestLocale();
const currentPathLocale = SUPPORTED_LOCALES.find((locale) => const currentPathLocale = locales.supported.find(({ locale }) =>
window.location.pathname.startsWith(`/${locale}`), window.location.pathname.startsWith(`/${locale}`),
); );
if ( if (
!isAPI && // not an api, duh! !isAPI && // not an api, duh!
localStorage.getItem('preferred-locale') !== null && // no preference, so probably google's crawler localStorage.getItem('preferred-locale') !== null && // no preference, so probably google's crawler
bestLocale !== currentPathLocale // we need to redirect currentPathLocale &&
bestLocale !== currentPathLocale.locale // we need to redirect
) { ) {
window.location.pathname = isI18nPath window.location.pathname = isI18nPath
? window.location.pathname.replace( ? window.location.pathname.replace(
`/${currentPathLocale}`, `/${currentPathLocale.locale}`,
bestLocale === undefined ? '' : `/${bestLocale}`, bestLocale === undefined ? '' : `/${bestLocale}`,
) )
: `/${bestLocale}${window.location.pathname}`; : `/${bestLocale}${window.location.pathname}`;
@@ -1,8 +1,7 @@
--- ---
import { AstroSeo } from '@astrolib/seo'; import { AstroSeo } from '@astrolib/seo';
import { assertSecret } from '@blitzkit/core'; import { assertSecret } from '@blitzkit/core';
import { DEFAULT_LOCALE, STRINGS, type SupportedLocale } from '@blitzkit/i18n'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import locales from '@blitzkit/i18n/locales.json';
import { literals } from '@blitzkit/i18n/src/literals'; import { literals } from '@blitzkit/i18n/src/literals';
import { Box, Flex, Heading, Link } from '@radix-ui/themes'; import { Box, Flex, Heading, Link } from '@radix-ui/themes';
import type { GetStaticPaths } from 'astro'; import type { GetStaticPaths } from 'astro';
@@ -21,20 +20,18 @@ import {
tankopediaTool, tankopediaTool,
tierListTool, tierListTool,
} from '../../constants/tools'; } from '../../constants/tools';
import { getStrings } from '../../core/i18n/getStrings';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH); const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
const { strings, locale } = Astro.props; const { locale } = Astro.props;
const strings = await getStrings(locale);
export const getStaticPaths = (() => { export const getStaticPaths = (() => {
return locales.supported.map(({ locale, blitz }) => { return locales.supported.map(({ locale, blitz }) => {
return { return {
params: { locale: locale === locales.default ? undefined : locale }, params: { locale: locale === locales.default ? undefined : locale },
props: { props: { locale, blitzLocale: blitz ?? locale },
locale,
strings: STRINGS[locale as SupportedLocale],
blitzLocale: blitz ?? locale,
},
}; };
}); });
}) satisfies GetStaticPaths; }) satisfies GetStaticPaths;
@@ -53,8 +50,8 @@ export const getStaticPaths = (() => {
twitter={{ cardType: 'summary_large_image' }} twitter={{ cardType: 'summary_large_image' }}
/> />
<BaseLayout {locale} {strings}> <BaseLayout {locale}>
<HomeHero {locale} {strings} /> <HomeHero {locale} />
<!-- <Flex justify="center" py="6" px="4" justify="center"> <!-- <Flex justify="center" py="6" px="4" justify="center">
<Flex <Flex
@@ -73,7 +70,7 @@ export const getStaticPaths = (() => {
</Flex> --> </Flex> -->
{ {
locale !== DEFAULT_LOCALE && ( locale !== locales.default && (
<Flex justify="center" mb="4"> <Flex justify="center" mb="4">
<Link <Link
href="https://crowdin.com/project/blitzkrieg" href="https://crowdin.com/project/blitzkrieg"
@@ -5,29 +5,30 @@ import type {
TankCatalogComponent, TankCatalogComponent,
} from '@blitzkit/closed/src/unreal/protos'; } from '@blitzkit/closed/src/unreal/protos';
import { slugify } from '@blitzkit/core'; import { slugify } from '@blitzkit/core';
import locales from '@blitzkit/i18n/locales.json'; import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import type { GetStaticPaths } from 'astro'; import type { GetStaticPaths } from 'astro';
import { tankToSet } from 'packages/website/src/core/blitz/tankToSet'; import { tankToSet } from 'packages/website/src/core/blitz/tankToSet';
import type { TankopediaEphemeral_ue } from 'packages/website/src/stores/tankopediaEphemeral_ue'; import type { TankopediaEphemeral_ue } from 'packages/website/src/stores/tankopediaEphemeral_ue';
import { metadata } from '../../../../core/blitz/metadata'; import { unpackedMetadata } from '../../../../core/blitz/unpackedMetadata';
import BaseLayout from '../../../../layouts/BaseLayout.astro'; import BaseLayout from '../../../../layouts/BaseLayout.astro';
import { getStaticPaths as parentGetStaticPaths } from '../index.astro'; import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
import { Page } from './_index'; import { Page } from './_index';
export const getStaticPaths = (async () => { export const getStaticPaths = (async () => {
const tanks = await metadata.getComponent<CatalogItemsComponent>( const tanks = await unpackedMetadata.getComponent<CatalogItemsComponent>(
'CatalogItemsGroupEntity.all_tanks', 'CatalogItemsGroupEntity.all_tanks',
'catalogItemsGroupComponent', 'catalogItemsGroupComponent',
); );
const gameStringsDefault = await metadata.stringsSubset(locales.default, [ const gameStringsDefault = await unpackedMetadata.stringsSubset(
'TankEntity', locales.default,
]); ['TankEntity'],
);
const parentPaths = parentGetStaticPaths(); const parentPaths = parentGetStaticPaths();
return ( return (
await Promise.all( await Promise.all(
tanks.catalog_items.map(async (item) => { tanks.catalog_items.map(async (item) => {
const tank = await metadata.get(item).then((components) => { const tank = await unpackedMetadata.get(item).then((components) => {
return components.get<TankCatalogComponent>('tankCatalogComponent'); return components.get<TankCatalogComponent>('tankCatalogComponent');
}); });
const nameEn = gameStringsDefault[tank.name!.value]; const nameEn = gameStringsDefault[tank.name!.value];
@@ -45,11 +46,11 @@ export const getStaticPaths = (async () => {
}) satisfies GetStaticPaths; }) satisfies GetStaticPaths;
const { entity, locale, strings, blitzLocale } = Astro.props; const { entity, locale, strings, blitzLocale } = Astro.props;
const set = await tankToSet(metadata, entity); const set = await tankToSet(unpackedMetadata, entity);
const gameStrings = await metadata.stringsSubset(blitzLocale, [ const gameStrings = await unpackedMetadata.stringsSubset(blitzLocale, [
set.tank_set_ui!.tank_set_displayed_name, set.tank_set_ui!.tank_set_displayed_name,
]); ]);
const tankEntity = await metadata.get(entity); const tankEntity = await unpackedMetadata.get(entity);
const tank = await tankEntity.get<TankCatalogComponent>('tankCatalogComponent'); const tank = await tankEntity.get<TankCatalogComponent>('tankCatalogComponent');
const compensation = await tankEntity.get<CompensationComponent>( const compensation = await tankEntity.get<CompensationComponent>(
'compensationComponent', 'compensationComponent',
@@ -0,0 +1,21 @@
---
import { CatalogItemsComponent } from '@protos/blitz_static_catalog_items_group_component';
import { Link } from '@radix-ui/themes';
import { PageWrapper } from 'packages/website/src/components/PageWrapper';
import { unpackedMetadata } from 'packages/website/src/core/blitz/unpackedMetadata';
import BaseLayout from 'packages/website/src/layouts/BaseLayout.astro';
export { getStaticPaths } from '../index.astro';
const { locale } = Astro.props;
const allTanks = unpackedMetadata
.get('CatalogItemsGroupEntity.all_tanks')
.get(CatalogItemsComponent, 'catalogItemsGroupComponent');
---
<BaseLayout {locale}>
<PageWrapper>
{allTanks.catalog_items.map((tank) => <Link>{tank}</Link>)}
</PageWrapper>
</BaseLayout>
@@ -1,52 +1,17 @@
--- ---
import { slugify } from '@blitzkit/core'; import { CatalogItemsComponent } from '@protos/blitz_static_catalog_items_group_component';
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 { TestComponent } from 'packages/website/src/components/TestComponent'; import { TestComponent } from 'packages/website/src/components/TestComponent';
import { metadata } from '../../../core/blitz/metadata'; import { unpackedMetadata } from 'packages/website/src/core/blitz/unpackedMetadata';
import { getStrings } from 'packages/website/src/core/i18n/getStrings';
export { getStaticPaths } from '../index.astro'; export { getStaticPaths } from '../index.astro';
const { blitzLocale } = Astro.props; const { locale } = Astro.props;
const allTanks = await metadata.getComponent<CatalogItemsComponent>( const strings = await getStrings(locale);
'CatalogItemsGroupEntity.all_tanks',
'catalogItemsGroupComponent',
);
const gameStrings = await metadata.stringsSubset(blitzLocale, ['TankEntity']);
const gameStringsDefault = await metadata.stringsSubset(locales.default, [
'TankEntity',
]);
const tanks: { tank: TankCatalogComponent; slug: string; id: string }[] = [];
for (const tankComponentId of allTanks.catalog_items) { const allTanks = unpackedMetadata
const tank = await metadata.getComponent<TankCatalogComponent>( .get('CatalogItemsGroupEntity.all_tanks')
tankComponentId, .get(CatalogItemsComponent, 'catalogItemsGroupComponent');
'tankCatalogComponent',
);
if (tank.name === undefined) {
continue;
}
const nameEn = gameStringsDefault[tank.name.value];
const slug = slugify(nameEn);
tanks.push({ tank, slug, id: tankComponentId });
}
--- ---
<TestComponent client:load data={metadata} /> <TestComponent client:load data={allTanks} />
{
tanks.map(({ tank, slug, id }) => {
return (
<>
<a href={`/tanks-ue/${slug}`}>
{gameStrings[tank.name!.value] ?? `MISSING NAME (${id})`}
</a>
<br />
</>
);
})
}
@@ -1,4 +1,4 @@
import en from '@blitzkit/i18n/strings/en.json'; import en from '@blitzkit/i18n/strings/en.json' with { type: 'json' };
import type { TankPerformanceSortType } from '.'; import type { TankPerformanceSortType } from '.';
export const TankPerformanceSortTypeNamesArray = Object.keys( export const TankPerformanceSortTypeNamesArray = Object.keys(
@@ -1,9 +1,9 @@
import type en from '@blitzkit/i18n/strings/en.json'; import type { BlitzKitStrings } from 'packages/i18n/src';
import { create } from 'zustand'; import { create } from 'zustand';
import { createContextualStore } from '../../core/zustand/createContextualStore'; import { createContextualStore } from '../../core/zustand/createContextualStore';
export type TankPerformanceSortType = export type TankPerformanceSortType =
keyof typeof en.website.tools.performance.table.stats; keyof BlitzKitStrings['website']['tools']['performance']['table']['stats'];
export interface TankPerformanceSort { export interface TankPerformanceSort {
type: TankPerformanceSortType; type: TankPerformanceSortType;
@@ -1,10 +1,11 @@
import type en from '@blitzkit/i18n/strings/en.json';
import * as lodash from 'lodash-es'; import * as lodash from 'lodash-es';
import type { BlitzKitStrings } from 'packages/i18n/src';
import { create } from 'zustand'; import { create } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware'; import { persist, subscribeWithSelector } from 'zustand/middleware';
import { createContextualStore } from '../../core/zustand/createContextualStore'; import { createContextualStore } from '../../core/zustand/createContextualStore';
export type TankopediaSortBy = keyof typeof en.website.common.tank_search.sort; export type TankopediaSortBy =
keyof BlitzKitStrings['website']['common']['tank_search']['sort'];
export type TankopediaSortDirection = 'ascending' | 'descending'; export type TankopediaSortDirection = 'ascending' | 'descending';
export type TankopediaTestTankDisplay = 'include' | 'exclude' | 'only'; export type TankopediaTestTankDisplay = 'include' | 'exclude' | 'only';
+2 -1
View File
@@ -23,7 +23,8 @@
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {
"@protos/*": ["submodules/blitzkit-closed/src/unreal/protos/*"] "@protos/*": ["submodules/blitzkit-closed/src/unreal/protos/*"],
"@strings/*": ["packages/i18n/strings/*"]
} }
}, },
"exclude": ["node_modules/**/*", "dist", ".next"] "exclude": ["node_modules/**/*", "dist", ".next"]