diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-03-30 13:34:40 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-05-16 00:54:57 +0200 |
commit | 0f8c96d26a74865a35440338739de037bf984315 (patch) | |
tree | 77767c4107b72ee763115ddb4ecad64d898bdafd /packages | |
parent | feat(main): Add localization support (diff) | |
download | sophie-0f8c96d26a74865a35440338739de037bf984315.tar.gz sophie-0f8c96d26a74865a35440338739de037bf984315.tar.zst sophie-0f8c96d26a74865a35440338739de037bf984315.zip |
feat(main): Translation hot reloading during development
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages')
-rw-r--r-- | packages/main/src/i18n/I18nStore.ts | 16 | ||||
-rw-r--r-- | packages/main/src/stores/MainStore.ts | 7 | ||||
-rw-r--r-- | packages/renderer/src/devTools.ts | 9 | ||||
-rw-r--r-- | packages/renderer/src/index.tsx | 4 | ||||
-rw-r--r-- | packages/shared/src/schemas/Action.ts | 3 |
5 files changed, 33 insertions, 6 deletions
diff --git a/packages/main/src/i18n/I18nStore.ts b/packages/main/src/i18n/I18nStore.ts index d833e8a..c364f0e 100644 --- a/packages/main/src/i18n/I18nStore.ts +++ b/packages/main/src/i18n/I18nStore.ts | |||
@@ -82,7 +82,12 @@ export default class I18nStore { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | const loadAsync = async () => { | 84 | const loadAsync = async () => { |
85 | await this.i18next.loadNamespaces([ns]); | 85 | try { |
86 | await this.i18next.loadNamespaces([ns]); | ||
87 | } catch (error) { | ||
88 | setImmediate(loaded); | ||
89 | throw error; | ||
90 | } | ||
86 | if (this.i18next.isInitialized) { | 91 | if (this.i18next.isInitialized) { |
87 | setImmediate(loaded); | 92 | setImmediate(loaded); |
88 | return; | 93 | return; |
@@ -98,7 +103,14 @@ export default class I18nStore { | |||
98 | 103 | ||
99 | loadAsync().catch((error) => { | 104 | loadAsync().catch((error) => { |
100 | log.error('Failed to load translations for namespace', ns, error); | 105 | log.error('Failed to load translations for namespace', ns, error); |
101 | setImmediate(loaded); | ||
102 | }); | 106 | }); |
103 | } | 107 | } |
108 | |||
109 | async reloadTranslations(): Promise<void> { | ||
110 | await this.i18next.reloadResources(); | ||
111 | setImmediate(() => { | ||
112 | this.languageChangedAtom.reportChanged(); | ||
113 | }); | ||
114 | log.debug('Reloaded translations'); | ||
115 | } | ||
104 | } | 116 | } |
diff --git a/packages/main/src/stores/MainStore.ts b/packages/main/src/stores/MainStore.ts index 873f998..93cabb9 100644 --- a/packages/main/src/stores/MainStore.ts +++ b/packages/main/src/stores/MainStore.ts | |||
@@ -96,6 +96,13 @@ const MainStore = types | |||
96 | case 'reload-all-services': | 96 | case 'reload-all-services': |
97 | self.services.forEach((service) => service.reload()); | 97 | self.services.forEach((service) => service.reload()); |
98 | break; | 98 | break; |
99 | case 'reload-all-translations': | ||
100 | if (self.i18n !== undefined) { | ||
101 | self.i18n.reloadTranslations().catch((error) => { | ||
102 | log.error('Failed to reload translations', error); | ||
103 | }); | ||
104 | } | ||
105 | break; | ||
99 | case 'dispatch-service-action': { | 106 | case 'dispatch-service-action': { |
100 | const { serviceId, serviceAction } = action; | 107 | const { serviceId, serviceAction } = action; |
101 | const service = self.shared.servicesById.get(serviceId); | 108 | const service = self.shared.servicesById.get(serviceId); |
diff --git a/packages/renderer/src/devTools.ts b/packages/renderer/src/devTools.ts index cb695c3..1fe39f7 100644 --- a/packages/renderer/src/devTools.ts +++ b/packages/renderer/src/devTools.ts | |||
@@ -52,13 +52,18 @@ export async function exposeToReduxDevtools( | |||
52 | } | 52 | } |
53 | 53 | ||
54 | /** | 54 | /** |
55 | * Sends a message to the main process to reload all services when | 55 | * Sends a message to the main process to reload all services or translations when |
56 | * `build/watch.js` sends a reload event on bundle write. | 56 | * `build/watch.js` sends a reload event on bundle write. |
57 | */ | 57 | */ |
58 | export function hotReloadServices(): void { | 58 | export function hotReload(): void { |
59 | import.meta.hot?.on('sophie:reload-services', () => { | 59 | import.meta.hot?.on('sophie:reload-services', () => { |
60 | window.sophieRenderer.dispatchAction({ | 60 | window.sophieRenderer.dispatchAction({ |
61 | action: 'reload-all-services', | 61 | action: 'reload-all-services', |
62 | }); | 62 | }); |
63 | }); | 63 | }); |
64 | import.meta.hot?.on('sophie:reload-translations', () => { | ||
65 | window.sophieRenderer.dispatchAction({ | ||
66 | action: 'reload-all-translations', | ||
67 | }); | ||
68 | }); | ||
64 | } | 69 | } |
diff --git a/packages/renderer/src/index.tsx b/packages/renderer/src/index.tsx index e87ab8b..54e157c 100644 --- a/packages/renderer/src/index.tsx +++ b/packages/renderer/src/index.tsx | |||
@@ -30,7 +30,7 @@ import { render } from 'react-dom'; | |||
30 | import App from './components/App'; | 30 | import App from './components/App'; |
31 | import StoreProvider from './components/StoreProvider'; | 31 | import StoreProvider from './components/StoreProvider'; |
32 | import ThemeProvider from './components/ThemeProvider'; | 32 | import ThemeProvider from './components/ThemeProvider'; |
33 | import { exposeToReduxDevtools, hotReloadServices } from './devTools'; | 33 | import { exposeToReduxDevtools, hotReload } from './devTools'; |
34 | import { createAndConnectRendererStore } from './stores/RendererStore'; | 34 | import { createAndConnectRendererStore } from './stores/RendererStore'; |
35 | import { getLogger } from './utils/log'; | 35 | import { getLogger } from './utils/log'; |
36 | 36 | ||
@@ -39,7 +39,7 @@ const isDevelopment = import.meta.env.MODE === 'development'; | |||
39 | const log = getLogger('index'); | 39 | const log = getLogger('index'); |
40 | 40 | ||
41 | if (isDevelopment) { | 41 | if (isDevelopment) { |
42 | hotReloadServices(); | 42 | hotReload(); |
43 | } | 43 | } |
44 | 44 | ||
45 | const store = createAndConnectRendererStore(window.sophieRenderer); | 45 | const store = createAndConnectRendererStore(window.sophieRenderer); |
diff --git a/packages/shared/src/schemas/Action.ts b/packages/shared/src/schemas/Action.ts index d5d0a8d..8d6ca3a 100644 --- a/packages/shared/src/schemas/Action.ts +++ b/packages/shared/src/schemas/Action.ts | |||
@@ -46,6 +46,9 @@ export const Action = /* @__PURE__ */ (() => | |||
46 | action: z.literal('reload-all-services'), | 46 | action: z.literal('reload-all-services'), |
47 | }), | 47 | }), |
48 | z.object({ | 48 | z.object({ |
49 | action: z.literal('reload-all-translations'), | ||
50 | }), | ||
51 | z.object({ | ||
49 | action: z.literal('dispatch-service-action'), | 52 | action: z.literal('dispatch-service-action'), |
50 | serviceId: z.string(), | 53 | serviceId: z.string(), |
51 | serviceAction: ServiceAction, | 54 | serviceAction: ServiceAction, |