diff --git a/_package.json b/_package.json index 03b0424f9..de8f5957c 100644 --- a/_package.json +++ b/_package.json @@ -54,7 +54,6 @@ "crc": "^4.3.2", "dotenv": "^16.4.5", "lz4js": "^0.2.0", - "ts-proto": "^2.2.2", "yaml": "^2.5.0", "ts-deepmerge": "^7.0.2", "@types/decompress": "^4.2.7", @@ -69,34 +68,25 @@ "progress": "^2.0.3", "puppeteer": "^23.10.4", "@astrojs/check": "^0.9.4", - "@astrojs/sitemap": "^3.2.1", "@playform/compress": "^0.1.9", "@playform/inline": "^0.1.2", "@types/js-cookie": "^3.0.6", - "@types/three": "^0.160.0", "astro-compressor": "^1.0.0", - "@astrojs/partytown": "^2.1.4", "@fontsource/inter": "^5.2.5", "@nanostores/persistent": "^0.10.2", "@nanostores/react": "^0.7.3", "@nivo/bar": "^0.87.0", "@nivo/line": "^0.88.0", - "@react-three/drei": "^9.115.0", - "@react-three/fiber": "^8.17.10", "compare-versions": "^6.1.1", "echarts": "^5.5.1", - "immer": "^10.1.1", "js-cookie": "^3.0.5", "markdown-to-jsx": "^7.5.0", "nanostores": "^0.11.3", "react-device-detect": "^2.2.3", "react-promise-suspense": "^0.3.4", - "three": "^0.169.0", "urlon": "^3.1.0", - "zustand": "^4.5.5", "@types/bun": "latest", "@types/node": "^22.14.1", - "prettier": "^3.5.3", "prisma": "^6.6.0", "typescript": "^5.8.3", "googleapis": "^144.0.0", diff --git a/bun.lockb b/bun.lockb index 80bdc4b51..88ec7b0d0 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 8e3bb4dc3..edc98de5a 100644 --- a/package.json +++ b/package.json @@ -39,5 +39,8 @@ "build:ids": "cd packages/scripts && bun build:ids", "prunestrings": "cd packages/scripts && bun prunestrings" }, - "license": "MIT" + "license": "MIT", + "dependencies": { + "prettier": "^3.5.3" + } } diff --git a/packages/core/package.json b/packages/core/package.json index fa0c8aa5b..f39be73b5 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -2,5 +2,8 @@ "name": "@blitzkit/core", "private": true, "type": "module", - "main": "src/index.ts" + "main": "src/index.ts", + "dependencies": { + "ts-proto": "^2.2.2" + } } diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json index caa25ce0f..3cc2d7809 100644 --- a/packages/i18n/strings/en.json +++ b/packages/i18n/strings/en.json @@ -1254,6 +1254,7 @@ }, "gallery": { "name": "Gallery", + "unnamed_avatar": "Unnamed avatar", "button": "Browse all", "description": "Blitz player avatars", "seo_description": "All World of Tanks Blitz player avatars", diff --git a/packages/website-ue/astro.config.mjs b/packages/website-ue/astro.config.mjs index 4e39c0f77..75acc1237 100644 --- a/packages/website-ue/astro.config.mjs +++ b/packages/website-ue/astro.config.mjs @@ -3,7 +3,6 @@ import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; -// https://astro.build/config export default defineConfig({ integrations: [react()], devToolbar: { enabled: false }, diff --git a/packages/website-ue/package.json b/packages/website-ue/package.json index cf10d08e9..34316915e 100644 --- a/packages/website-ue/package.json +++ b/packages/website-ue/package.json @@ -8,22 +8,30 @@ "astro": "astro" }, "dependencies": { + "@astrojs/partytown": "^2.1.4", "@astrojs/react": "^4.3.0", + "@astrojs/sitemap": "^3.2.1", "@astrolib/seo": "^1.0.0-beta.8", "@blitzkit/closed": "workspace:*", "@blitzkit/core": "workspace:*", "@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", + "@react-three/drei": "^9.115.0", + "@react-three/fiber": "^8.17.10", "@types/js-yaml": "^4.0.9", "@types/lodash-es": "^4.17.12", "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", + "@types/three": "^0.160.0", "astro": "^5.8.0", + "immer": "^10.1.1", "js-yaml": "^4.1.0", "lodash-es": "^4.17.21", "minimatch": "^10.0.1", "react": "^19.1.0", - "react-dom": "^19.1.0" + "react-dom": "^19.1.0", + "three": "^0.169.0", + "zustand": "^4.5.5" } } diff --git a/packages/website-ue/src/pages/[...locale]/gallery/_index.tsx b/packages/website-ue/src/pages/[...locale]/gallery/_index.tsx index 38c6301a0..e14927f57 100644 --- a/packages/website-ue/src/pages/[...locale]/gallery/_index.tsx +++ b/packages/website-ue/src/pages/[...locale]/gallery/_index.tsx @@ -1,11 +1,17 @@ import { ProfileAvatarComponent } from '@protos/blitz_static_profile_avatar_component'; import { StuffUIComponent } from '@protos/blitz_static_stuff_ui_component'; import { BlitzkitAllAvatarsComponent } from '@protos/blitzkit_static_all_avatars_component'; -import { Flex, Text } from '@radix-ui/themes'; +import { Badge, Box, Flex, Grid, Text } from '@radix-ui/themes'; import { CatalogItemAccessor } from 'packages/core/src/blitz/catalogItemAccessor'; +import { PageWrapper } from 'packages/website-ue/src/components/PageWrapper'; 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'; +import { + LocaleProvider, + useLocale, + type LocaleAcceptorProps, +} from 'packages/website-ue/src/hooks/useLocale'; +import { useMemo } from 'react'; const allAvatars = await metadata .get('BlitzkitAllAvatarsEntity.blitzkit_all_avatars') @@ -17,40 +23,107 @@ const allAvatars = await metadata export function Page({ localeData }: LocaleAcceptorProps) { return ( - - {allAvatars.map((avatar) => { - const item = new CatalogItemAccessor(avatar); + + + + ); +} +const dx = '4px'; +const MAX_AVATARS_PREVIEW = 5; + +function Content() { + const { gameStrings, strings } = useLocale(); + const groups = useMemo(() => { + const avatars = allAvatars + .map((avatar) => { + const item = new CatalogItemAccessor(avatar); const stuffComponent = item.get(StuffUIComponent, 'UIComponent'); const avatarComponent = item.get( ProfileAvatarComponent, 'profileAvatarComponent', ); + const name = + gameStrings[stuffComponent.display_name] ?? + strings.website.tools.gallery.unnamed_avatar; - return ( - - apple sauce - {stuffComponent.display_name} - - ); - })} - + return { avatar, name, stuffComponent, avatarComponent }; + }) + .sort((a, b) => a.stuffComponent.grade - b.stuffComponent.grade) + .sort((a, b) => a.name.localeCompare(b.name)); + const groups: Record = {}; + + for (const avatar of avatars) { + if (avatar.name in groups) { + groups[avatar.name].push(avatar); + } else { + groups[avatar.name] = [avatar]; + } + } + + return Object.entries(groups); + }, []); + + return ( + + + {groups.map(([name, avatars]) => { + const avatarsReduced = [...avatars] + .reverse() + .slice(0, MAX_AVATARS_PREVIEW); + + return ( + + + {avatarsReduced.map((avatar, index) => ( + + ))} + + {avatars.length > 1 && ( + + + x{avatars.length} + + + )} + + + {name} + + ); + })} + + ); }