yangdx commited on
Commit
219639b
·
1 Parent(s): 144edae

Resolve the language setting persistence issue

Browse files

- Move i18n initialization to async function
- Sync i18n with settings store language
- Add Root component for i18n loading state
- Convert i18n.js to TypeScript

lightrag_webui/src/components/Root.tsx ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { StrictMode, useEffect, useState } from 'react'
2
+ import { initializeI18n } from '@/i18n'
3
+ import App from '@/App'
4
+
5
+ export const Root = () => {
6
+ const [isI18nInitialized, setIsI18nInitialized] = useState(false)
7
+
8
+ useEffect(() => {
9
+ // Initialize i18n immediately with persisted language
10
+ initializeI18n().then(() => {
11
+ setIsI18nInitialized(true)
12
+ })
13
+ }, [])
14
+
15
+ if (!isI18nInitialized) {
16
+ return null // or a loading spinner
17
+ }
18
+
19
+ return (
20
+ <StrictMode>
21
+ <App />
22
+ </StrictMode>
23
+ )
24
+ }
lightrag_webui/src/i18n.js DELETED
@@ -1,21 +0,0 @@
1
- import i18n from 'i18next';
2
- import { initReactI18next } from 'react-i18next';
3
-
4
- import en from './locales/en.json';
5
- import zh from './locales/zh.json';
6
-
7
- i18n
8
- .use(initReactI18next)
9
- .init({
10
- resources: {
11
- en: { translation: en },
12
- zh: { translation: zh }
13
- },
14
- lng: 'en', // default
15
- fallbackLng: 'en',
16
- interpolation: {
17
- escapeValue: false
18
- }
19
- });
20
-
21
- export default i18n;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lightrag_webui/src/i18n.ts ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import i18n from 'i18next'
2
+ import { initReactI18next } from 'react-i18next'
3
+ import { useSettingsStore } from '@/stores/settings'
4
+
5
+ import en from './locales/en.json'
6
+ import zh from './locales/zh.json'
7
+
8
+ // Function to sync i18n with store state
9
+ export const initializeI18n = async (): Promise<typeof i18n> => {
10
+ // Get initial language from store
11
+ const initialLanguage = useSettingsStore.getState().language
12
+
13
+ // Initialize with store language
14
+ await i18n.use(initReactI18next).init({
15
+ resources: {
16
+ en: { translation: en },
17
+ zh: { translation: zh }
18
+ },
19
+ lng: initialLanguage,
20
+ fallbackLng: 'en',
21
+ interpolation: {
22
+ escapeValue: false
23
+ }
24
+ })
25
+
26
+ // Subscribe to language changes
27
+ useSettingsStore.subscribe((state) => {
28
+ const currentLanguage = state.language
29
+ if (i18n.language !== currentLanguage) {
30
+ i18n.changeLanguage(currentLanguage)
31
+ }
32
+ })
33
+
34
+ return i18n
35
+ }
36
+
37
+ export default i18n
lightrag_webui/src/main.tsx CHANGED
@@ -1,12 +1,5 @@
1
- import { StrictMode } from 'react'
2
  import { createRoot } from 'react-dom/client'
3
  import './index.css'
4
- import App from './App.tsx'
5
- import "./i18n";
6
 
7
-
8
- createRoot(document.getElementById('root')!).render(
9
- <StrictMode>
10
- <App />
11
- </StrictMode>
12
- )
 
 
1
  import { createRoot } from 'react-dom/client'
2
  import './index.css'
3
+ import { Root } from '@/components/Root'
 
4
 
5
+ createRoot(document.getElementById('root')!).render(<Root />)
 
 
 
 
 
lightrag_webui/src/stores/settings.ts CHANGED
@@ -59,11 +59,27 @@ interface SettingsState {
59
  setCurrentTab: (tab: Tab) => void
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  const useSettingsStoreBase = create<SettingsState>()(
63
  persist(
64
  (set) => ({
65
- theme: 'system',
66
- language: 'zh',
67
  refreshLayout: () => {
68
  const graphState = useGraphStore.getState();
69
  const currentGraph = graphState.sigmaGraph;
@@ -116,10 +132,13 @@ const useSettingsStoreBase = create<SettingsState>()(
116
  setTheme: (theme: Theme) => set({ theme }),
117
 
118
  setLanguage: (language: Language) => {
 
 
119
  import('i18next').then(({ default: i18n }) => {
120
- i18n.changeLanguage(language);
121
- });
122
- set({ language });
 
123
  },
124
 
125
  setGraphLayoutMaxIterations: (iterations: number) =>
 
59
  setCurrentTab: (tab: Tab) => void
60
  }
61
 
62
+ // Helper to get initial state from localStorage
63
+ const getInitialState = () => {
64
+ try {
65
+ const stored = localStorage.getItem('settings-storage')
66
+ if (stored) {
67
+ const { state } = JSON.parse(stored)
68
+ return {
69
+ theme: state?.theme || 'system',
70
+ language: state?.language || 'zh'
71
+ }
72
+ }
73
+ } catch (e) {
74
+ console.error('Failed to parse settings from localStorage:', e)
75
+ }
76
+ return { theme: 'system', language: 'zh' }
77
+ }
78
+
79
  const useSettingsStoreBase = create<SettingsState>()(
80
  persist(
81
  (set) => ({
82
+ ...getInitialState(),
 
83
  refreshLayout: () => {
84
  const graphState = useGraphStore.getState();
85
  const currentGraph = graphState.sigmaGraph;
 
132
  setTheme: (theme: Theme) => set({ theme }),
133
 
134
  setLanguage: (language: Language) => {
135
+ set({ language })
136
+ // Update i18n after state is updated
137
  import('i18next').then(({ default: i18n }) => {
138
+ if (i18n.language !== language) {
139
+ i18n.changeLanguage(language)
140
+ }
141
+ })
142
  },
143
 
144
  setGraphLayoutMaxIterations: (iterations: number) =>