mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 08:06:36 +00:00
fix: show the app in the chosen language right after a cold start
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
|
||||
vi.mock('react-native', () => ({
|
||||
I18nManager: { isRTL: false, allowRTL: () => {}, forceRTL: () => {} },
|
||||
}));
|
||||
vi.mock('expo-localization', () => ({ getLocales: () => [{ languageTag: 'en-US', languageCode: 'en' }] }));
|
||||
vi.mock('@react-native-async-storage/async-storage', () => ({
|
||||
default: {
|
||||
getItem: vi.fn(async () => JSON.stringify({ override: 'de' })),
|
||||
setItem: vi.fn(async () => undefined),
|
||||
},
|
||||
}));
|
||||
|
||||
import { useLocaleStore } from '../locale-store';
|
||||
|
||||
describe('locale store', () => {
|
||||
it('hands out a new t once the saved language loads, so screens re-render in it', async () => {
|
||||
const before = useLocaleStore.getState().t;
|
||||
expect(before('sidebar.settings', 'Settings')).toBe('Settings');
|
||||
|
||||
await useLocaleStore.getState().hydrate();
|
||||
|
||||
const after = useLocaleStore.getState().t;
|
||||
expect(after).not.toBe(before);
|
||||
expect(after('sidebar.settings', 'Settings')).toBe('Einstellungen');
|
||||
});
|
||||
});
|
||||
@@ -48,6 +48,13 @@ function applyLayoutDirection(locale: LocaleCode): boolean {
|
||||
return manager.isRTL !== rtl;
|
||||
}
|
||||
|
||||
// A new `t` per locale: most components select only `t`, and a function
|
||||
// that never changed identity left them in the device language after the
|
||||
// saved one loaded on a cold start (tab labels, the folder title).
|
||||
function translatorFor(locale: LocaleCode): TranslateFn {
|
||||
return (key, fallback, params) => translate(locale, key, fallback, params);
|
||||
}
|
||||
|
||||
export const useLocaleStore = create<LocaleState>((set, get) => ({
|
||||
locale: detectDeviceLocale(),
|
||||
override: null,
|
||||
@@ -62,7 +69,7 @@ export const useLocaleStore = create<LocaleState>((set, get) => ({
|
||||
const override = stored && isSupportedLocale(stored) ? stored : null;
|
||||
const locale = override ?? detectDeviceLocale();
|
||||
const directionChangePending = applyLayoutDirection(locale);
|
||||
set({ override, locale, hydrated: true, directionChangePending });
|
||||
set({ override, locale, hydrated: true, directionChangePending, t: translatorFor(locale) });
|
||||
} catch {
|
||||
set({ hydrated: true });
|
||||
}
|
||||
@@ -71,11 +78,11 @@ export const useLocaleStore = create<LocaleState>((set, get) => ({
|
||||
setOverride: (override) => {
|
||||
const locale = override ?? detectDeviceLocale();
|
||||
const directionChangePending = applyLayoutDirection(locale);
|
||||
set({ override, locale, directionChangePending });
|
||||
set({ override, locale, directionChangePending, t: translatorFor(locale) });
|
||||
void AsyncStorage.setItem(STORAGE_KEY, JSON.stringify({ override })).catch(() => {});
|
||||
},
|
||||
|
||||
t: (key, fallback, params) => translate(get().locale, key, fallback, params),
|
||||
t: translatorFor(detectDeviceLocale()),
|
||||
}));
|
||||
|
||||
// Non-hook accessor for code outside React (background tasks, stores).
|
||||
|
||||
Reference in New Issue
Block a user