mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-04 16:06:41 +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;
|
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) => ({
|
export const useLocaleStore = create<LocaleState>((set, get) => ({
|
||||||
locale: detectDeviceLocale(),
|
locale: detectDeviceLocale(),
|
||||||
override: null,
|
override: null,
|
||||||
@@ -62,7 +69,7 @@ export const useLocaleStore = create<LocaleState>((set, get) => ({
|
|||||||
const override = stored && isSupportedLocale(stored) ? stored : null;
|
const override = stored && isSupportedLocale(stored) ? stored : null;
|
||||||
const locale = override ?? detectDeviceLocale();
|
const locale = override ?? detectDeviceLocale();
|
||||||
const directionChangePending = applyLayoutDirection(locale);
|
const directionChangePending = applyLayoutDirection(locale);
|
||||||
set({ override, locale, hydrated: true, directionChangePending });
|
set({ override, locale, hydrated: true, directionChangePending, t: translatorFor(locale) });
|
||||||
} catch {
|
} catch {
|
||||||
set({ hydrated: true });
|
set({ hydrated: true });
|
||||||
}
|
}
|
||||||
@@ -71,11 +78,11 @@ export const useLocaleStore = create<LocaleState>((set, get) => ({
|
|||||||
setOverride: (override) => {
|
setOverride: (override) => {
|
||||||
const locale = override ?? detectDeviceLocale();
|
const locale = override ?? detectDeviceLocale();
|
||||||
const directionChangePending = applyLayoutDirection(locale);
|
const directionChangePending = applyLayoutDirection(locale);
|
||||||
set({ override, locale, directionChangePending });
|
set({ override, locale, directionChangePending, t: translatorFor(locale) });
|
||||||
void AsyncStorage.setItem(STORAGE_KEY, JSON.stringify({ override })).catch(() => {});
|
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).
|
// Non-hook accessor for code outside React (background tasks, stores).
|
||||||
|
|||||||
Reference in New Issue
Block a user