mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: string hooks
This commit is contained in:
1 parent
f5f3f70e35
commit
27abf1b0de
7 files changed
+82
-12
No files matched your search
@@ -20,5 +20,6 @@
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { api } from "../../core/api/dynamic";
|
import { useGameStrings } from "../../hooks/useGameStrings";
|
||||||
import { useAwait } from "../../hooks/useAwait";
|
import { useLocale } from "../../hooks/useLocale";
|
||||||
import type { Avatar } from "../../protos/avatar";
|
import type { Avatar } from "../../protos/avatar";
|
||||||
import { Text } from "../Text";
|
import { Text } from "../Text";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
@@ -9,12 +9,8 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function AvatarCard({ avatar }: Props) {
|
export function AvatarCard({ avatar }: Props) {
|
||||||
// const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
const { locale } = { locale: "en" };
|
const profileAvatarEntityStrings = useGameStrings("ProfileAvatarEntity");
|
||||||
const profileAvatarEntityStrings = useAwait(
|
|
||||||
() => api.groupedGameStrings(locale, "ProfileAvatarEntity"),
|
|
||||||
"profile-avatar-entity-strings"
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="avatar-card">
|
<div className="avatar-card">
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { fetchPB } from "@blitzkit/core";
|
import { fetchPB } from "@blitzkit/core";
|
||||||
|
import type { Strings } from "@blitzkit/i18n";
|
||||||
import { Avatars } from "../../protos/avatars";
|
import { Avatars } from "../../protos/avatars";
|
||||||
import { AbstractAPI } from "./abstract";
|
import { AbstractAPI } from "./abstract";
|
||||||
|
|
||||||
@@ -29,4 +30,11 @@ export class ClientAPI extends AbstractAPI {
|
|||||||
|
|
||||||
return strings;
|
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 { AvatarCard } from "../../../components/AvatarCard";
|
||||||
import { api } from "../../../core/api/dynamic";
|
import { api } from "../../../core/api/dynamic";
|
||||||
import { useAwait } from "../../../hooks/useAwait";
|
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;
|
skeleton?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Page({ skeleton }: Props) {
|
function Content({ skeleton }: ContentProps) {
|
||||||
const { avatars } = useAwait(() => api.avatars(), "avatars");
|
const { avatars } = useAwait(() => api.avatars(), "avatars");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ const { locale } = Astro.props;
|
|||||||
|
|
||||||
<BaseLayout {locale} accent="gold">
|
<BaseLayout {locale} accent="gold">
|
||||||
<Section>
|
<Section>
|
||||||
<Page client:only="react">
|
<Page {locale} client:only="react">
|
||||||
<Page skeleton slot="fallback" />
|
<Page {locale} skeleton slot="fallback" />
|
||||||
</Page>
|
</Page>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
Reference in new issue
Block a user