mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: game strings context
This commit is contained in:
1 parent
9bf1554c30
commit
1eca71d28c
21 files changed
+208
-137
No files matched your search
@@ -25,9 +25,9 @@ type Extension =
|
||||
status: 'error';
|
||||
};
|
||||
|
||||
export function Checks({ locale }: LocaleAcceptorProps) {
|
||||
export function Checks({ localeData }: LocaleAcceptorProps) {
|
||||
return (
|
||||
<LocaleProvider locale={locale}>
|
||||
<LocaleProvider localeData={localeData}>
|
||||
<App.Provider>
|
||||
<Content />
|
||||
</App.Provider>
|
||||
@@ -39,7 +39,7 @@ export function Checks({ locale }: LocaleAcceptorProps) {
|
||||
* Wargaming: 14 (refresh: 7)
|
||||
*/
|
||||
function Content() {
|
||||
const { locale } = useLocale();
|
||||
const localeData = useLocale();
|
||||
const logins = App.use((state) => state.logins);
|
||||
const mutateApp = App.useMutation();
|
||||
const appStore = App.useStore();
|
||||
@@ -128,11 +128,17 @@ function Content() {
|
||||
<Text>
|
||||
This website utilizes cookies to perform analytics and personalize
|
||||
your experience. You can learn more through{' '}
|
||||
<LinkI18n locale={locale} href="/docs/legal/privacy-policy">
|
||||
<LinkI18n
|
||||
localeData={localeData}
|
||||
href="/docs/legal/privacy-policy"
|
||||
>
|
||||
our privacy policy
|
||||
</LinkI18n>
|
||||
. By using BlitzKit, you also agree to our{' '}
|
||||
<LinkI18n locale={locale} href="/docs/legal/terms-of-service">
|
||||
<LinkI18n
|
||||
localeData={localeData}
|
||||
href="/docs/legal/terms-of-service"
|
||||
>
|
||||
terms of service
|
||||
</LinkI18n>
|
||||
.
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
---
|
||||
import { assertSecret, fetchGameDefinitions } from '@blitzkit/core';
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import { Box, Code, Flex, Heading, Link, Text } from '@radix-ui/themes';
|
||||
import packageJson from '../../../../package.json';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
import { LinkI18n } from './LinkI18n';
|
||||
import { LocaleSwitcherThemeWrapper } from './LocaleSwitcher';
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const gameDefinitions = await fetchGameDefinitions();
|
||||
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
||||
const locale = Astro.params.locale ?? locales.default;
|
||||
const { locale } = Astro.props;
|
||||
const localeData = { locale };
|
||||
const strings = await getStrings(locale);
|
||||
---
|
||||
|
||||
@@ -44,7 +48,7 @@ const strings = await getStrings(locale);
|
||||
</Text>
|
||||
|
||||
<Box mt="2">
|
||||
<LocaleSwitcherThemeWrapper {locale} client:load />
|
||||
<LocaleSwitcherThemeWrapper {localeData} client:load />
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
@@ -79,7 +83,7 @@ const strings = await getStrings(locale);
|
||||
sm: 'start',
|
||||
}}
|
||||
>
|
||||
<LinkI18n {locale} href="/docs/about/credits" color="gray">
|
||||
<LinkI18n {localeData} href="/docs/about/credits" color="gray">
|
||||
{strings.website.footer.about.credits}
|
||||
</LinkI18n>
|
||||
<Link
|
||||
@@ -96,7 +100,7 @@ const strings = await getStrings(locale);
|
||||
>
|
||||
{strings.website.footer.about.github}
|
||||
</Link>
|
||||
<LinkI18n {locale} href="/docs/patches" color="gray">
|
||||
<LinkI18n {localeData} href="/docs/patches" color="gray">
|
||||
{strings.website.footer.about.patches}
|
||||
</LinkI18n>
|
||||
</Flex>
|
||||
@@ -116,10 +120,14 @@ const strings = await getStrings(locale);
|
||||
>
|
||||
<Heading size="3">{strings.website.footer.legal.title}</Heading>
|
||||
<Flex direction="column">
|
||||
<LinkI18n {locale} href="/docs/legal/privacy-policy" color="gray">
|
||||
<LinkI18n {localeData} href="/docs/legal/privacy-policy" color="gray">
|
||||
{strings.website.footer.legal.privacy}
|
||||
</LinkI18n>
|
||||
<LinkI18n {locale} href="/docs/legal/terms-of-service" color="gray">
|
||||
<LinkI18n
|
||||
{localeData}
|
||||
href="/docs/legal/terms-of-service"
|
||||
color="gray"
|
||||
>
|
||||
{strings.website.footer.legal.terms}
|
||||
</LinkI18n>
|
||||
</Flex>
|
||||
|
||||
@@ -3,11 +3,12 @@ import { Link, type LinkProps } from '@radix-ui/themes';
|
||||
import type { LocaleAcceptorProps } from '../hooks/useLocale';
|
||||
|
||||
export function LinkI18n({
|
||||
locale,
|
||||
localeData,
|
||||
href,
|
||||
...props
|
||||
}: LinkProps & LocaleAcceptorProps) {
|
||||
const prefix = locale === locales.default ? '' : `/${locale}`;
|
||||
const prefix =
|
||||
localeData.locale === locales.default ? '' : `/${localeData.locale}`;
|
||||
|
||||
return (
|
||||
<Link href={href?.startsWith('/') ? `${prefix}${href}` : href} {...props} />
|
||||
|
||||
@@ -4,18 +4,20 @@ import { LOCALE_NAMES, SUPPORTED_LOCALE_FLAGS } from 'packages/i18n/src';
|
||||
import type { LocaleAcceptorProps } from '../hooks/useLocale';
|
||||
import { BlitzKitTheme } from './BlitzKitTheme';
|
||||
|
||||
export function LocaleSwitcherThemeWrapper({ locale }: LocaleAcceptorProps) {
|
||||
export function LocaleSwitcherThemeWrapper({
|
||||
localeData,
|
||||
}: LocaleAcceptorProps) {
|
||||
return (
|
||||
<BlitzKitTheme style={{ background: 'transparent' }}>
|
||||
<LocaleSwitcher locale={locale} />
|
||||
<LocaleSwitcher localeData={localeData} />
|
||||
</BlitzKitTheme>
|
||||
);
|
||||
}
|
||||
|
||||
export function LocaleSwitcher({ locale }: LocaleAcceptorProps) {
|
||||
export function LocaleSwitcher({ localeData }: LocaleAcceptorProps) {
|
||||
return (
|
||||
<Select.Root
|
||||
defaultValue={locale}
|
||||
defaultValue={localeData.locale}
|
||||
onValueChange={(locale) => {
|
||||
localStorage.setItem('preferred-locale', locale);
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
import { assertSecret } from '@blitzkit/core';
|
||||
import {
|
||||
Cross1Icon,
|
||||
DiscordLogoIcon,
|
||||
@@ -19,8 +18,9 @@ export interface Props {
|
||||
}
|
||||
|
||||
const { integrated, locale } = Astro.props;
|
||||
const localeData = { locale };
|
||||
const toolsFiltered = tools.filter((tool) => tool.enabled);
|
||||
const branchName = resolveBranchName(locale);
|
||||
const branchName = resolveBranchName();
|
||||
const isBranchNamed = branchName !== undefined;
|
||||
const strings = await getStrings(locale);
|
||||
---
|
||||
@@ -107,7 +107,7 @@ const strings = await getStrings(locale);
|
||||
<Flex gap="4" direction="column" maxWidth="80rem" width="100%">
|
||||
<Flex align="center">
|
||||
<LinkI18n
|
||||
{locale}
|
||||
{localeData}
|
||||
color="gray"
|
||||
highContrast
|
||||
href="/"
|
||||
@@ -146,7 +146,7 @@ const strings = await getStrings(locale);
|
||||
|
||||
return (
|
||||
<LinkI18n
|
||||
{locale}
|
||||
{localeData}
|
||||
weight={selected ? 'medium' : 'regular'}
|
||||
color="gray"
|
||||
highContrast={selected}
|
||||
@@ -175,7 +175,7 @@ const strings = await getStrings(locale);
|
||||
</Link>
|
||||
|
||||
<LinkI18n
|
||||
{locale}
|
||||
{localeData}
|
||||
style={{ display: 'flex', alignContent: 'center' }}
|
||||
color="gray"
|
||||
href="/settings"
|
||||
@@ -184,8 +184,6 @@ const strings = await getStrings(locale);
|
||||
<GearIcon width="1em" height="1em" />
|
||||
</LinkI18n>
|
||||
|
||||
<!-- <NavbarAccount client:idle /> -->
|
||||
|
||||
<Flex align="center" display={{ initial: 'flex', sm: 'none' }}>
|
||||
<IconButton variant="ghost" color="gray" className="hamburger">
|
||||
<Cross1Icon data-expanded />
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import {
|
||||
LocaleProvider,
|
||||
useLocale,
|
||||
type LocaleAcceptorProps,
|
||||
} from '../hooks/useLocale';
|
||||
|
||||
function Content() {
|
||||
const { locale, strings } = useLocale();
|
||||
const content = JSON.stringify(strings, null, 2);
|
||||
|
||||
return <span>{strings.common.units.deg_s}</span>;
|
||||
}
|
||||
|
||||
export function TestComponent({ locale }: LocaleAcceptorProps) {
|
||||
return (
|
||||
<LocaleProvider locale={locale}>
|
||||
<Content />
|
||||
</LocaleProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,25 +1,39 @@
|
||||
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||
import { createContext, use, useContext } from 'react';
|
||||
const LocaleContext = createContext<string | null>(null);
|
||||
|
||||
const LocaleContext = createContext<{
|
||||
locale: string;
|
||||
gameStrings: Record<string, string>;
|
||||
} | null>(null);
|
||||
|
||||
export interface LocaleAcceptorProps {
|
||||
locale: string;
|
||||
localeData: {
|
||||
locale: string;
|
||||
gameStrings?: Record<string, string>;
|
||||
};
|
||||
}
|
||||
|
||||
interface LocaleProviderProps extends LocaleAcceptorProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function LocaleProvider({ locale, children }: LocaleProviderProps) {
|
||||
export function LocaleProvider({ localeData, children }: LocaleProviderProps) {
|
||||
const isSupported = locales.supported.some(
|
||||
(supported) => supported.locale === locale,
|
||||
(supported) => supported.locale === localeData.locale,
|
||||
);
|
||||
|
||||
if (!isSupported) throw new Error(`Unsupported locale: ${locale}`);
|
||||
if (!isSupported) throw new Error(`Unsupported locale: ${localeData.locale}`);
|
||||
|
||||
return (
|
||||
<LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
|
||||
<LocaleContext.Provider
|
||||
value={{
|
||||
locale: localeData.locale,
|
||||
gameStrings: localeData.gameStrings ?? {},
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</LocaleContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,13 +55,13 @@ function loadLocale(locale: string) {
|
||||
}
|
||||
|
||||
export function useLocale() {
|
||||
const locale = useContext(LocaleContext);
|
||||
const localeData = useContext(LocaleContext);
|
||||
|
||||
if (locale === null) {
|
||||
if (localeData === null) {
|
||||
throw new Error('useLocale must be used within a LocaleProvider');
|
||||
}
|
||||
|
||||
const strings = use(loadLocale(locale));
|
||||
const strings = use(loadLocale(localeData.locale));
|
||||
|
||||
return { locale, strings };
|
||||
return { ...localeData, strings };
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
const { noFooter, noNavbar, integrated, locale } = Astro.props;
|
||||
const localeData = { locale };
|
||||
---
|
||||
|
||||
<html lang={locale}>
|
||||
@@ -69,11 +70,11 @@ const { noFooter, noNavbar, integrated, locale } = Astro.props;
|
||||
<Flex direction="column" minHeight="100vh">
|
||||
<Navbar {locale} {integrated} />
|
||||
|
||||
<Checks {locale} client:only="react" />
|
||||
<Checks {localeData} client:only="react" />
|
||||
|
||||
<slot />
|
||||
|
||||
{!noFooter && <Footer />}
|
||||
{!noFooter && <Footer {locale} />}
|
||||
</Flex>
|
||||
</BlitzKitTheme>
|
||||
</body>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { PageWrapper } from '../components/PageWrapper';
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
|
||||
const locale = locales.default;
|
||||
const localeData = { locale };
|
||||
---
|
||||
|
||||
<BaseLayout {locale}>
|
||||
@@ -15,7 +16,7 @@ const locale = locales.default;
|
||||
<Text color="gray">Where would you like to go?</Text>
|
||||
|
||||
<Flex mt="4" gap="2">
|
||||
<LinkI18n {locale} href="/">
|
||||
<LinkI18n {localeData} href="/">
|
||||
<Button>
|
||||
<HomeIcon /> Home
|
||||
</Button>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Flex, Text } from '@radix-ui/themes';
|
||||
import { CatalogItemAccessor } from 'packages/core/src/blitz/catalogItemAccessor';
|
||||
import { metadata } from 'packages/website-ue/src/core/blitz/metadata';
|
||||
import { Var } from 'packages/website-ue/src/core/radix/var';
|
||||
import type { LocaleAcceptorProps } from 'packages/website-ue/src/hooks/useLocale';
|
||||
|
||||
const allAvatars = await metadata
|
||||
.get('BlitzkitAllAvatarsEntity.blitzkit_all_avatars')
|
||||
@@ -14,7 +15,7 @@ const allAvatars = await metadata
|
||||
.avatars,
|
||||
);
|
||||
|
||||
export function Page() {
|
||||
export function Page({ localeData }: LocaleAcceptorProps) {
|
||||
return (
|
||||
<Flex wrap="wrap" gapX="4" gapY="6" justify="center" p="9">
|
||||
{allAvatars.map((avatar) => {
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
---
|
||||
import { metadata } from 'packages/website-ue/src/core/blitz/metadata';
|
||||
import BaseLayout from 'packages/website-ue/src/layouts/BaseLayout.astro';
|
||||
import { Page } from './_index';
|
||||
|
||||
export { getStaticPaths } from '../index.astro';
|
||||
|
||||
const { locale } = Astro.props;
|
||||
|
||||
const gameStrings = await metadata.stringsPartial(locale, [
|
||||
'ProfileAvatarEntity__*',
|
||||
]);
|
||||
---
|
||||
|
||||
<BaseLayout {locale}>
|
||||
<Page client:load />
|
||||
<Page localeData={{ locale, gameStrings }} client:load />
|
||||
</BaseLayout>
|
||||
@@ -1,20 +0,0 @@
|
||||
import { TankCatalogComponent } from '@protos/blitz_static_tank_component';
|
||||
import { BlitzkitAllTanksComponent } from '@protos/blitzkit_static_all_tanks_component';
|
||||
import { SocketCatalogAccessor } from 'packages/core/src';
|
||||
import { remoteCatalog } from 'packages/website-ue/src/core/blitz/remoteCatalog';
|
||||
|
||||
const data = await remoteCatalog
|
||||
.get('BlitzKitAllTanksEntity.blitzkit_all_tanks')
|
||||
.then((components) =>
|
||||
components.get(BlitzkitAllTanksComponent, 'blitzkitAllTanksComponent'),
|
||||
);
|
||||
|
||||
export function Page() {
|
||||
const tankCatalog = new SocketCatalogAccessor(data.tanks);
|
||||
|
||||
const content = tankCatalog
|
||||
.get('TankEntity.A92_M60')
|
||||
.get(TankCatalogComponent, 'tankCatalogComponent');
|
||||
|
||||
return <pre children={JSON.stringify(content, null, 2)} />;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
import { Page } from './_index';
|
||||
|
||||
export { getStaticPaths } from '../index.astro';
|
||||
|
||||
const { locale } = Astro.props;
|
||||
---
|
||||
|
||||
<Page client:load />
|
||||
Reference in new issue
Block a user