feat: string hooks

This commit is contained in:
TrèsAbhi committed 2026-01-13 20:15:55 -06:00
1 parent f5f3f70e35
commit 27abf1b0de
7 files changed
+82 -12

No files matched your search

@@ -20,5 +20,6 @@
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
@@ -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 (
<div className="avatar-card">
@@ -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;
}
}
@@ -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;
}
@@ -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 (
<LocaleContext.Provider value={{ locale: locale ?? locales.default }}>
{children}
</LocaleContext.Provider>
);
}
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;
}
@@ -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 (
<LocaleProvider locale={locale}>
<Content {...props} />
</LocaleProvider>
);
}
interface ContentProps {
skeleton?: boolean;
}
export function Page({ skeleton }: Props) {
function Content({ skeleton }: ContentProps) {
const { avatars } = useAwait(() => api.avatars(), "avatars");
return (
@@ -18,8 +18,8 @@ const { locale } = Astro.props;
<BaseLayout {locale} accent="gold">
<Section>
<Page client:only="react">
<Page skeleton slot="fallback" />
<Page {locale} client:only="react">
<Page {locale} skeleton slot="fallback" />
</Page>
</Section>
</BaseLayout>