From 27abf1b0deb051268fec3aeddac0e1b39df1a0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 13 Jan 2026 20:15:55 -0600 Subject: [PATCH] feat: string hooks --- .../src/components/AvatarCard/index.css | 1 + .../src/components/AvatarCard/index.tsx | 12 ++---- packages/website-ue/src/core/api/client.ts | 8 ++++ .../website-ue/src/hooks/useGameStrings.ts | 13 +++++++ packages/website-ue/src/hooks/useLocale.tsx | 39 +++++++++++++++++++ .../src/pages/[...locale]/avatars/_index.tsx | 17 +++++++- .../src/pages/[...locale]/avatars/index.astro | 4 +- 7 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 packages/website-ue/src/hooks/useGameStrings.ts create mode 100644 packages/website-ue/src/hooks/useLocale.tsx diff --git a/packages/website-ue/src/components/AvatarCard/index.css b/packages/website-ue/src/components/AvatarCard/index.css index e67b7aed0..6d7715603 100644 --- a/packages/website-ue/src/components/AvatarCard/index.css +++ b/packages/website-ue/src/components/AvatarCard/index.css @@ -20,5 +20,6 @@ max-width: 100%; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } } diff --git a/packages/website-ue/src/components/AvatarCard/index.tsx b/packages/website-ue/src/components/AvatarCard/index.tsx index 316848e87..4ddb4b6b3 100644 --- a/packages/website-ue/src/components/AvatarCard/index.tsx +++ b/packages/website-ue/src/components/AvatarCard/index.tsx @@ -1,5 +1,5 @@ -import { api } from "../../core/api/dynamic"; -import { useAwait } from "../../hooks/useAwait"; +import { useGameStrings } from "../../hooks/useGameStrings"; +import { useLocale } from "../../hooks/useLocale"; import type { Avatar } from "../../protos/avatar"; import { Text } from "../Text"; import "./index.css"; @@ -9,12 +9,8 @@ interface Props { } export function AvatarCard({ avatar }: Props) { - // const { locale } = useLocale(); - const { locale } = { locale: "en" }; - const profileAvatarEntityStrings = useAwait( - () => api.groupedGameStrings(locale, "ProfileAvatarEntity"), - "profile-avatar-entity-strings" - ); + const { locale } = useLocale(); + const profileAvatarEntityStrings = useGameStrings("ProfileAvatarEntity"); return (
diff --git a/packages/website-ue/src/core/api/client.ts b/packages/website-ue/src/core/api/client.ts index fb8ec176f..d1ff4077c 100644 --- a/packages/website-ue/src/core/api/client.ts +++ b/packages/website-ue/src/core/api/client.ts @@ -1,4 +1,5 @@ import { fetchPB } from "@blitzkit/core"; +import type { Strings } from "@blitzkit/i18n"; import { Avatars } from "../../protos/avatars"; import { AbstractAPI } from "./abstract"; @@ -29,4 +30,11 @@ export class ClientAPI extends AbstractAPI { return strings; } + + protected async _strings(locale: string) { + const response = await fetch(`/api/strings/${locale}.json`); + const json = (await response.json()) as Strings; + + return json; + } } diff --git a/packages/website-ue/src/hooks/useGameStrings.ts b/packages/website-ue/src/hooks/useGameStrings.ts new file mode 100644 index 000000000..998c2c597 --- /dev/null +++ b/packages/website-ue/src/hooks/useGameStrings.ts @@ -0,0 +1,13 @@ +import { api } from "../core/api/dynamic"; +import { useAwait } from "./useAwait"; +import { useLocale } from "./useLocale"; + +export function useGameStrings(group: string) { + const { locale } = useLocale(); + const strings = useAwait( + () => api.groupedGameStrings(locale, group), + `game-strings-${locale}-${group}` + ); + + return strings; +} diff --git a/packages/website-ue/src/hooks/useLocale.tsx b/packages/website-ue/src/hooks/useLocale.tsx new file mode 100644 index 000000000..2bf4020e5 --- /dev/null +++ b/packages/website-ue/src/hooks/useLocale.tsx @@ -0,0 +1,39 @@ +import locales from "@blitzkit/i18n/locales.json"; +import { createContext, useContext, type ReactNode } from "react"; +import { api } from "../core/api/dynamic"; +import { useAwait } from "./useAwait"; + +const LocaleContext = createContext<{ + locale: string; +} | null>(null); + +interface LocaleProviderProps extends LocaleAcceptorProps { + children: ReactNode; +} + +export function LocaleProvider({ locale, children }: LocaleProviderProps) { + return ( + + {children} + + ); +} + +export function useLocale() { + const context = useContext(LocaleContext); + + if (!context) { + throw new Error("useLocale must be used within a LocaleProvider"); + } + + const strings = useAwait( + () => api.strings(context.locale), + `strings-${context.locale}` + ); + + return { locale: context.locale, strings }; +} + +export interface LocaleAcceptorProps { + locale: string | undefined; +} diff --git a/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx b/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx index d8e0f0b2b..a7a30da17 100644 --- a/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx +++ b/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx @@ -1,12 +1,25 @@ import { AvatarCard } from "../../../components/AvatarCard"; import { api } from "../../../core/api/dynamic"; import { useAwait } from "../../../hooks/useAwait"; +import { LocaleProvider } from "../../../hooks/useLocale"; -interface Props { +interface PageProps extends ContentProps { + locale: string; +} + +export function Page({ locale, ...props }: PageProps) { + return ( + + + + ); +} + +interface ContentProps { skeleton?: boolean; } -export function Page({ skeleton }: Props) { +function Content({ skeleton }: ContentProps) { const { avatars } = useAwait(() => api.avatars(), "avatars"); return ( diff --git a/packages/website-ue/src/pages/[...locale]/avatars/index.astro b/packages/website-ue/src/pages/[...locale]/avatars/index.astro index fff0ba90f..d8b13960f 100644 --- a/packages/website-ue/src/pages/[...locale]/avatars/index.astro +++ b/packages/website-ue/src/pages/[...locale]/avatars/index.astro @@ -18,8 +18,8 @@ const { locale } = Astro.props;
- - + +