You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.1 KiB
TypeScript

import { createContext, useContext } from 'react';
import { en, type TranslationKey, type Translations } from './en';
import { ru } from './ru';
export type Locale = 'en' | 'ru';
const bundles: Record<Locale, Translations> = { en, ru };
/** Detect locale from Telegram WebApp or browser */
export function detectLocale(): Locale {
// Check localStorage first (user override)
try {
const saved = localStorage.getItem('autohero_locale');
if (saved === 'en' || saved === 'ru') return saved;
} catch { /* ignore */ }
// Telegram Mini App language
try {
const tg = (window as any).Telegram?.WebApp;
const lang: string | undefined =
tg?.initDataUnsafe?.user?.language_code ?? tg?.language_code;
if (lang?.startsWith('ru')) return 'ru';
} catch { /* ignore */ }
// Browser language fallback
const nav = navigator.language ?? (navigator as any).userLanguage ?? '';
if (nav.startsWith('ru')) return 'ru';
return 'en';
}
// ---- Context ----
interface I18nValue {
tr: Translations;
locale: Locale;
setLocale: (l: Locale) => void;
}
export const I18nContext = createContext<I18nValue>({
tr: en,
locale: 'en',
setLocale: () => {},
});
/** Hook: returns the full translation object for the current locale */
export function useT(): Translations {
return useContext(I18nContext).tr;
}
/** Hook: returns locale + setter for the settings UI */
export function useLocale(): { locale: Locale; setLocale: (l: Locale) => void } {
const { locale, setLocale } = useContext(I18nContext);
return { locale, setLocale };
}
/**
* Interpolate {placeholders} in a translation string.
* Usage: t(translations.levelUp, { level: 5 }) => "Level up! Now level 5"
*/
export function t(template: string, vars?: Record<string, string | number>): string {
if (!vars) return template;
return template.replace(/\{(\w+)\}/g, (_, key) =>
vars[key] != null ? String(vars[key]) : `{${key}}`,
);
}
/** Get translations bundle for a locale */
export function getTranslations(locale: Locale): Translations {
return bundles[locale] ?? en;
}
export type { TranslationKey, Translations };