feat: translate gallery

This commit is contained in:
tresabhi committed 2025-01-07 13:00:43 -06:00
1 parent 9de41529d1
commit 6b2dda0f9d
8 files changed
+52 -38

No files matched your search

+6 -1
View File
@@ -778,7 +778,12 @@
"name": "Gallery",
"button": "Browse all",
"description": "Blitz player avatars",
"seo_description": "All World of Tanks Blitz player avatars"
"seo_description": "All World of Tanks Blitz player avatars",
"last_updated": "Last updated on %s1",
"search": {
"hint": "Search avatars...",
"results": "%s1 avatars"
}
},
"session": {
"name": "Session",
@@ -2,6 +2,7 @@ import { Flex, Text } from '@radix-ui/themes';
import fuzzysort from 'fuzzysort';
import { times } from 'lodash-es';
import { useMemo, useState } from 'react';
import { literals } from '../../core/i18n/literals';
import { useLocale } from '../../hooks/useLocale';
import { GalleryEphemeral } from '../../stores/galleryEphemeral';
import { GalleryCard } from './Card';
@@ -21,7 +22,7 @@ const PREVIEW_COUNT = 28;
export function GalleryList({ avatars }: GalleryListProps) {
const search = GalleryEphemeral.use((state) => state.search);
const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED);
const { locale } = useLocale();
const { locale, strings } = useLocale();
const filtered = useMemo(() => {
setLoadedCards(DEFAULT_LOADED);
@@ -37,7 +38,9 @@ export function GalleryList({ avatars }: GalleryListProps) {
return (
<>
<Text align="center" color="gray">
{filtered.length.toLocaleString(locale)} avatars
{literals(strings.website.tools.gallery.search.results, [
filtered.length.toLocaleString(locale),
])}
</Text>
<Flex wrap="wrap" gap="4" justify="center">
@@ -1,15 +1,17 @@
import { MagnifyingGlassIcon } from '@radix-ui/react-icons';
import { TextField } from '@radix-ui/themes';
import { useRef } from 'react';
import { useLocale } from '../../hooks/useLocale';
import { GalleryEphemeral } from '../../stores/galleryEphemeral';
export function GallerySearch() {
const input = useRef<HTMLInputElement>(null);
const mutateGalleryEphemeral = GalleryEphemeral.useMutation();
const { strings } = useLocale();
return (
<TextField.Root
placeholder="Search avatars..."
placeholder={strings.website.tools.gallery.search.hint}
ref={input}
onChange={(event) => {
mutateGalleryEphemeral((draft) => {
@@ -1,6 +1,10 @@
import { assertSecret, type BlitzGlossary } from '@blitzkit/core';
export async function fetchGlossary() {
const response = await fetch(assertSecret(import.meta.env.WOTB_GLOSSARY));
export async function fetchGlossary(locale: string) {
const response = await fetch(
`${assertSecret(
import.meta.env.WOTB_GLOSSARY_DOMAIN,
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`,
);
return (await response.json()) as BlitzGlossary;
}
@@ -3,14 +3,32 @@ import { Callout, Flex } from '@radix-ui/themes';
import { GalleryList, type Avatar } from '../../../../components/Gallery/List';
import { GallerySearch } from '../../../../components/Gallery/Search';
import { PageWrapper } from '../../../../components/PageWrapper';
import { literals } from '../../../../core/i18n/literals';
import {
LocaleProvider,
useLocale,
type LocaleAcceptorProps,
} from '../../../../hooks/useLocale';
import { GalleryEphemeral } from '../../../../stores/galleryEphemeral';
interface PageProps {
interface ContentProps {
avatars: Avatar[];
lastUpdated: string;
}
export function Page({ avatars, lastUpdated }: PageProps) {
type PageProps = ContentProps & LocaleAcceptorProps;
export function Page({ locale, ...props }: PageProps) {
return (
<LocaleProvider locale={locale}>
<Content {...props} />
</LocaleProvider>
);
}
function Content({ avatars, lastUpdated }: ContentProps) {
const { strings } = useLocale();
return (
<PageWrapper maxWidth="80rem" color="gold">
<Flex justify="center">
@@ -18,7 +36,11 @@ export function Page({ avatars, lastUpdated }: PageProps) {
<Callout.Icon>
<CalendarIcon />
</Callout.Icon>
<Callout.Text>Last updated on {lastUpdated}</Callout.Text>
<Callout.Text>
{literals(strings.website.tools.gallery.last_updated, [
lastUpdated,
])}
</Callout.Text>
</Callout.Root>
</Flex>
@@ -7,7 +7,8 @@ import { Page } from './_index';
export { getStaticPaths } from '../../index.astro';
const glossary = await fetchGlossary();
const { locale } = Astro.params;
const glossary = await fetchGlossary(locale);
const avatars = Object.entries(glossary)
.filter(
([key, value]) =>
@@ -20,9 +21,9 @@ const avatars = Object.entries(glossary)
({ id: key.replace('avatar_', ''), name: value.title }) satisfies Avatar,
)
.sort((a, b) => a.name.localeCompare(b.name));
const lastUpdated = new Date().toLocaleDateString();
const lastUpdated = new Date().toLocaleDateString(locale);
---
<ToolLayout tool={galleryTool}>
<Page {avatars} {lastUpdated} client:load />
<Page {locale} {avatars} {lastUpdated} client:load />
</ToolLayout>
@@ -1,8 +1,9 @@
import { DEFAULT_LOCALE } from '@blitzkit/core';
import type { APIRoute, GetStaticPaths } from 'astro';
import { fetchGlossary } from '../../../core/blitz/fetchGlossary';
export const getStaticPaths = (async () => {
const glossary = await fetchGlossary();
const glossary = await fetchGlossary(DEFAULT_LOCALE);
const avatarKeys = Object.keys(glossary)
.filter((key) => key.startsWith('avatar_'))
.map((key) => key.replace('avatar_', ''));
@@ -10,7 +11,7 @@ export const getStaticPaths = (async () => {
return avatarKeys.map((avatar) => ({ params: { avatar } }));
}) satisfies GetStaticPaths;
const glossary = await fetchGlossary();
const glossary = await fetchGlossary(DEFAULT_LOCALE);
export const GET: APIRoute<{}, { avatar: string }> = async ({ params }) => {
const image =