From 2230741779b71d8c5bbe0f0106b6347734fc7df5 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Tue, 30 Sep 2025 16:11:18 +0800 Subject: [PATCH] fix(i18n): apply system language on app start, closes #2141 (#2144) --- .../src/app/reader/components/settings/LangPanel.tsx | 8 +++----- .../src/app/reader/components/tts/TTSControl.tsx | 5 ++++- apps/readest-app/src/components/Providers.tsx | 7 ++++++- apps/readest-app/src/store/settingsStore.ts | 10 ++++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/apps/readest-app/src/app/reader/components/settings/LangPanel.tsx b/apps/readest-app/src/app/reader/components/settings/LangPanel.tsx index 465cf8c4..648d2555 100644 --- a/apps/readest-app/src/app/reader/components/settings/LangPanel.tsx +++ b/apps/readest-app/src/app/reader/components/settings/LangPanel.tsx @@ -1,23 +1,23 @@ import clsx from 'clsx'; -import i18n from 'i18next'; import React, { useEffect, useState } from 'react'; import { useEnv } from '@/context/EnvContext'; import { useAuth } from '@/context/AuthContext'; import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; +import { useSettingsStore } from '@/store/settingsStore'; import { saveViewSettings } from '../../utils/viewSettingsHelper'; import { getTranslators } from '@/services/translators'; import { TRANSLATED_LANGS, TRANSLATOR_LANGS } from '@/services/constants'; import { SettingsPanelPanelProp } from './SettingsDialog'; import { useResetViewSettings } from '../../hooks/useResetSettings'; import { saveAndReload } from '@/utils/reload'; -import { initDayjs } from '@/utils/time'; import Select from '@/components/Select'; const LangPanel: React.FC = ({ bookKey, onRegisterReset }) => { const _ = useTranslation(); const { token } = useAuth(); const { envConfig } = useEnv(); + const { applyUILanguage } = useSettingsStore(); const { getViewSettings, setViewSettings } = useReaderStore(); const viewSettings = getViewSettings(bookKey)!; @@ -117,9 +117,7 @@ const LangPanel: React.FC = ({ bookKey, onRegisterReset useEffect(() => { if (uiLanguage === viewSettings.uiLanguage) return; saveViewSettings(envConfig, bookKey, 'uiLanguage', uiLanguage, false, false); - const locale = uiLanguage ? uiLanguage : navigator.language; - i18n.changeLanguage(locale); - initDayjs(locale); + applyUILanguage(uiLanguage); // eslint-disable-next-line react-hooks/exhaustive-deps }, [uiLanguage]); diff --git a/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx b/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx index 20100f47..6edf2f1c 100644 --- a/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx +++ b/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx @@ -136,7 +136,10 @@ const TTSControl: React.FC = ({ bookKey, gridInsets }) => { const deinitMediaSession = async () => { if (mediaSessionRef.current && mediaSessionRef.current instanceof TauriMediaSession) { - await mediaSessionRef.current.setActive({ active: false }); + await mediaSessionRef.current.setActive({ + active: false, + keepAppInForeground: settings.alwaysInForeground, + }); } mediaSessionRef.current = null; }; diff --git a/apps/readest-app/src/components/Providers.tsx b/apps/readest-app/src/components/Providers.tsx index 634803f6..1dedfb28 100644 --- a/apps/readest-app/src/components/Providers.tsx +++ b/apps/readest-app/src/components/Providers.tsx @@ -1,5 +1,6 @@ 'use client'; +import i18n from '@/i18n/i18n'; import { useEffect } from 'react'; import { IconContext } from 'react-icons'; import { AuthProvider } from '@/context/AuthContext'; @@ -7,13 +8,14 @@ import { useEnv } from '@/context/EnvContext'; import { CSPostHogProvider } from '@/context/PHContext'; import { SyncProvider } from '@/context/SyncContext'; import { initSystemThemeListener, loadDataTheme } from '@/store/themeStore'; +import { useSettingsStore } from '@/store/settingsStore'; import { useDefaultIconSize } from '@/hooks/useResponsiveSize'; import { useSafeAreaInsets } from '@/hooks/useSafeAreaInsets'; import { getLocale } from '@/utils/misc'; -import i18n from '@/i18n/i18n'; const Providers = ({ children }: { children: React.ReactNode }) => { const { appService } = useEnv(); + const { applyUILanguage } = useSettingsStore(); const iconSize = useDefaultIconSize(); useSafeAreaInsets(); // Initialize safe area insets @@ -34,6 +36,9 @@ const Providers = ({ children }: { children: React.ReactNode }) => { loadDataTheme(); if (appService) { initSystemThemeListener(appService); + appService.loadSettings().then((settings) => { + applyUILanguage(settings.globalViewSettings?.uiLanguage); + }); } }, [appService]); diff --git a/apps/readest-app/src/store/settingsStore.ts b/apps/readest-app/src/store/settingsStore.ts index 7d0868ce..7c1cda28 100644 --- a/apps/readest-app/src/store/settingsStore.ts +++ b/apps/readest-app/src/store/settingsStore.ts @@ -1,6 +1,8 @@ +import i18n from '@/i18n/i18n'; import { create } from 'zustand'; import { SystemSettings } from '@/types/settings'; import { EnvConfigType } from '@/services/environment'; +import { initDayjs } from '@/utils/time'; export type FontPanelView = 'main-fonts' | 'custom-fonts'; @@ -14,6 +16,8 @@ interface SettingsState { setFontLayoutSettingsDialogOpen: (open: boolean) => void; setFontLayoutSettingsGlobal: (global: boolean) => void; setFontPanelView: (view: FontPanelView) => void; + + applyUILanguage: (uiLanguage?: string) => void; } export const useSettingsStore = create((set) => ({ @@ -29,4 +33,10 @@ export const useSettingsStore = create((set) => ({ setFontLayoutSettingsDialogOpen: (open) => set({ isFontLayoutSettingsDialogOpen: open }), setFontLayoutSettingsGlobal: (global) => set({ isFontLayoutSettingsGlobal: global }), setFontPanelView: (view) => set({ fontPanelView: view }), + + applyUILanguage: (uiLanguage?: string) => { + const locale = uiLanguage ? uiLanguage : navigator.language; + i18n.changeLanguage(locale); + initDayjs(locale); + }, }));