diff --git a/packages/core/src/blitz/catalogItemAccessor.ts b/packages/core/src/blitz/catalogItemAccessor.ts index fb782f6d3..256788d1e 100644 --- a/packages/core/src/blitz/catalogItemAccessor.ts +++ b/packages/core/src/blitz/catalogItemAccessor.ts @@ -43,12 +43,16 @@ export class CatalogItemAccessor { return this; } - get(Message: MessageFns, component: string) { + getOptional(Message: MessageFns, component: string) { if (component in this.components) { return Message.decode(this.components[component].value); } + } - throw new Error(`Unknown component: ${component}`); + get(Message: MessageFns, component: string) { + const value = this.getOptional(Message, component); + if (value === undefined) throw new Error(`Unknown component: ${component}`); + return value; } pack() { diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json index 9f70b9b7a..bd124f4a9 100644 --- a/packages/i18n/strings/en.json +++ b/packages/i18n/strings/en.json @@ -1260,7 +1260,7 @@ "seo_description": "All World of Tanks Blitz player profile avatars", "description": "Player profile avatars", - "unnamed_avatar": "Unnamed avatar", + "unnamed_avatars": "Unnamed avatars", "search": { "hint": "Search avatars...", "results": "%s1 avatars" diff --git a/packages/website-ue/src/components/Avatars/Group.tsx b/packages/website-ue/src/components/Avatars/Group.tsx index d5fca2711..4a0779512 100644 --- a/packages/website-ue/src/components/Avatars/Group.tsx +++ b/packages/website-ue/src/components/Avatars/Group.tsx @@ -1,29 +1,48 @@ import type { ProfileAvatarComponent } from '@protos/blitz_static_profile_avatar_component'; import type { SellableComponent } from '@protos/blitz_static_sellable_component'; import type { StuffUIComponent } from '@protos/blitz_static_stuff_ui_component'; -import { Badge, Box, Flex, Text } from '@radix-ui/themes'; +import { + Badge, + Box, + Dialog, + Flex, + Text, + type FlexProps, +} from '@radix-ui/themes'; import { literals } from 'packages/i18n/src'; import { Var } from '../../core/radix/var'; import { useLocale } from '../../hooks/useLocale'; interface AvatarGroupProps { - name: string; + name?: string; avatars: { stuff: StuffUIComponent; avatar: ProfileAvatarComponent; - sellable: SellableComponent; + sellable?: SellableComponent; }[]; } const dx = '4px'; const MAX_AVATARS_PREVIEW = 5; -export function AvatarGroup({ avatars, name }: AvatarGroupProps) { +export function AvatarGroup({ name, avatars }: AvatarGroupProps) { + return ( + + + + + + asd + + ); +} + +function Content({ avatars, name, ...props }: FlexProps & AvatarGroupProps) { const { strings } = useLocale(); const avatarsReduced = [...avatars].reverse().slice(0, MAX_AVATARS_PREVIEW); return ( - + {avatarsReduced.map((avatar, index) => ( - {name} + {name ?? strings.website.tools.avatars.unnamed_avatars} ); diff --git a/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx b/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx index d25cb7214..215850e89 100644 --- a/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx +++ b/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx @@ -41,30 +41,37 @@ function Content() { ProfileAvatarComponent, 'profileAvatarComponent', ); - const sellable = item.get(SellableComponent, 'sellableComponent'); - const name = - gameStrings[stuff.display_name] ?? - strings.website.tools.avatars.unnamed_avatar; // maybe move to dumb component? + const sellable = item.getOptional( + SellableComponent, + 'sellableComponent', + ); + const name = gameStrings[stuff.display_name] as string | undefined; return { avatar, name, stuff, sellable }; }) .sort((a, b) => a.stuff.grade - b.stuff.grade) - .sort((a, b) => a.name.localeCompare(b.name)); - const groups: Record = {}; + .sort((a, b) => + a.name === undefined + ? 1 + : b.name === undefined + ? -1 + : a.name.localeCompare(b.name), + ); + const groups = new Map(); for (const avatar of avatars) { - if (avatar.name in groups) { - groups[avatar.name].push(avatar); + if (groups.has(avatar.name)) { + groups.get(avatar.name)!.push(avatar); } else { - groups[avatar.name] = [avatar]; + groups.set(avatar.name, [avatar]); } } - return Object.entries(groups); + return [...groups]; }, []); return ( - + +