mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-29 14:37:44 +02:00
Publish stable GHCR self-host images, switch self-host deploys to official image pulls with a source-build fallback, and move self-host signup / Google OAuth config onto runtime /api/config.
58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useContext, useState, useCallback, useMemo } from "react";
|
|
import { useConfigStore } from "@multica/core/config";
|
|
import { createEnDict } from "./en";
|
|
import { createZhDict } from "./zh";
|
|
import type { LandingDict, Locale } from "./types";
|
|
|
|
const dictionaryFactories: Record<Locale, (allowSignup: boolean) => LandingDict> = {
|
|
en: createEnDict,
|
|
zh: createZhDict,
|
|
};
|
|
|
|
const COOKIE_NAME = "multica-locale";
|
|
const COOKIE_MAX_AGE = 60 * 60 * 24 * 365; // 1 year
|
|
|
|
type LocaleContextValue = {
|
|
locale: Locale;
|
|
t: LandingDict;
|
|
setLocale: (locale: Locale) => void;
|
|
};
|
|
|
|
const LocaleContext = createContext<LocaleContextValue | null>(null);
|
|
|
|
export function LocaleProvider({
|
|
children,
|
|
initialLocale = "en",
|
|
}: {
|
|
children: React.ReactNode;
|
|
initialLocale?: Locale;
|
|
}) {
|
|
const [locale, setLocaleState] = useState<Locale>(initialLocale);
|
|
const allowSignup = useConfigStore((state) => state.allowSignup);
|
|
const t = useMemo(
|
|
() => dictionaryFactories[locale](allowSignup),
|
|
[allowSignup, locale],
|
|
);
|
|
|
|
const setLocale = useCallback((l: Locale) => {
|
|
setLocaleState(l);
|
|
document.cookie = `${COOKIE_NAME}=${l}; path=/; max-age=${COOKIE_MAX_AGE}; SameSite=Lax`;
|
|
}, []);
|
|
|
|
return (
|
|
<LocaleContext.Provider
|
|
value={{ locale, t, setLocale }}
|
|
>
|
|
{children}
|
|
</LocaleContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useLocale() {
|
|
const ctx = useContext(LocaleContext);
|
|
if (!ctx) throw new Error("useLocale must be used within LocaleProvider");
|
|
return ctx;
|
|
}
|