Für Test-Kunden: vollständige fr-Locale mit Tonalität für Recovery-Kontext („addiction", „Série", „Période de blocage"). Eigenname „Lyra" und Brand „Rebreak" bleiben unübersetzt. - locales/fr.json: 1:1 key parity zu de.json/en.json (UI-Agent-Output) - lib/i18n.ts: fr in resources + initialLng-Detection (Device-Locale fr → fr) - stores/language.ts: AppLanguage union ergänzt um 'fr', init-Logic + persistence - app/settings.tsx: Sprach-Picker mit dritter Option Français - de.json/en.json: language_fr-Label + language_desc trilingual Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import { create } from 'zustand';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import i18n from '../lib/i18n';
|
|
|
|
export type AppLanguage = 'de' | 'en' | 'fr';
|
|
|
|
const STORAGE_KEY = '@rebreak/language';
|
|
|
|
type LanguageState = {
|
|
language: AppLanguage;
|
|
setLanguage: (lang: AppLanguage) => Promise<void>;
|
|
init: () => Promise<void>;
|
|
};
|
|
|
|
export const useLanguageStore = create<LanguageState>((set) => ({
|
|
language: 'en',
|
|
|
|
init: async () => {
|
|
const stored = await AsyncStorage.getItem(STORAGE_KEY);
|
|
if (stored === 'de' || stored === 'en' || stored === 'fr') {
|
|
await i18n.changeLanguage(stored);
|
|
set({ language: stored });
|
|
} else {
|
|
// Kein expliziter Wert gespeichert — i18n.ts hat bereits via deviceLocale
|
|
// initialisiert (Localization.getLocales()). NICHT auf 'en' overriden.
|
|
const detected =
|
|
i18n.language === 'de' ? 'de' : i18n.language === 'fr' ? 'fr' : 'en';
|
|
set({ language: detected as AppLanguage });
|
|
}
|
|
},
|
|
|
|
setLanguage: async (lang) => {
|
|
await AsyncStorage.setItem(STORAGE_KEY, lang);
|
|
await i18n.changeLanguage(lang);
|
|
set({ language: lang });
|
|
},
|
|
}));
|