Lots of improvements
Some checks failed
CI / Python (lint + test) (push) Failing after 1m39s
CI / Frontend (lint + typecheck) (push) Failing after 1m49s
CI / Rust (lint + test) (push) Failing after 1m50s
Build and publish Docker image / build-and-push (push) Failing after 3m9s

This commit is contained in:
Andras Schmelczer 2026-04-04 10:45:48 +01:00
parent 3853b5dce7
commit b94cf17d75
33 changed files with 2587 additions and 1866 deletions

View file

@ -7,11 +7,11 @@ import hu from './locales/hu';
import zh from './locales/zh';
export const SUPPORTED_LANGUAGES = [
{ code: 'en', label: 'English', flag: '\uD83C\uDDEC\uD83C\uDDE7' },
{ code: 'fr', label: 'Fran\u00E7ais', flag: '\uD83C\uDDEB\uD83C\uDDF7' },
{ code: 'de', label: 'Deutsch', flag: '\uD83C\uDDE9\uD83C\uDDEA' },
{ code: 'hu', label: 'Magyar', flag: '\uD83C\uDDED\uD83C\uDDFA' },
{ code: 'zh', label: '\u4E2D\u6587', flag: '\uD83C\uDDE8\uD83C\uDDF3' },
{ code: 'en', label: 'English', flag: '\uD83C\uDDEC\uD83C\uDDE7' },
{ code: 'fr', label: 'Fran\u00E7ais', flag: '\uD83C\uDDEB\uD83C\uDDF7' },
{ code: 'de', label: 'Deutsch', flag: '\uD83C\uDDE9\uD83C\uDDEA' },
{ code: 'hu', label: 'Magyar', flag: '\uD83C\uDDED\uD83C\uDDFA' },
{ code: 'zh', label: '\u4E2D\u6587', flag: '\uD83C\uDDE8\uD83C\uDDF3' },
] as const;
export type LanguageCode = (typeof SUPPORTED_LANGUAGES)[number]['code'];
@ -19,37 +19,37 @@ export type LanguageCode = (typeof SUPPORTED_LANGUAGES)[number]['code'];
const supportedCodes: Set<string> = new Set(SUPPORTED_LANGUAGES.map((l) => l.code));
function detectLanguage(): string {
// 1. Explicit user choice (persisted from the language dropdown)
const stored = localStorage.getItem('language');
if (stored && supportedCodes.has(stored)) return stored;
// 1. Explicit user choice (persisted from the language dropdown)
const stored = localStorage.getItem('language');
if (stored && supportedCodes.has(stored)) return stored;
// 2. Browser preference (navigator.languages falls back to navigator.language)
for (const tag of navigator.languages ?? [navigator.language]) {
// Match full tag first (e.g. "zh-CN" → "zh"), then just the prefix
const lower = tag.toLowerCase();
if (supportedCodes.has(lower)) return lower;
const prefix = lower.split('-')[0];
if (supportedCodes.has(prefix)) return prefix;
}
// 2. Browser preference (navigator.languages falls back to navigator.language)
for (const tag of navigator.languages ?? [navigator.language]) {
// Match full tag first (e.g. "zh-CN" → "zh"), then just the prefix
const lower = tag.toLowerCase();
if (supportedCodes.has(lower)) return lower;
const prefix = lower.split('-')[0];
if (supportedCodes.has(prefix)) return prefix;
}
return 'en';
return 'en';
}
const initialLang = detectLanguage();
i18n.use(initReactI18next).init({
resources: {
en: { translation: en },
fr: { translation: fr },
de: { translation: de },
hu: { translation: hu },
zh: { translation: zh },
},
lng: initialLang,
fallbackLng: 'en',
interpolation: {
escapeValue: false, // React already escapes
},
resources: {
en: { translation: en },
fr: { translation: fr },
de: { translation: de },
hu: { translation: hu },
zh: { translation: zh },
},
lng: initialLang,
fallbackLng: 'en',
interpolation: {
escapeValue: false, // React already escapes
},
});
/**
@ -57,8 +57,8 @@ i18n.use(initReactI18next).init({
* Bypasses the strict type checking on t() for dynamic key construction.
*/
export function tDynamic(key: string): string {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (i18n.t as any)(key);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (i18n.t as any)(key);
}
export default i18n;