diff --git a/localization/tiddlywikiLanguages.json b/localization/tiddlywikiLanguages.json new file mode 100644 index 00000000..5c5ba6aa --- /dev/null +++ b/localization/tiddlywikiLanguages.json @@ -0,0 +1,7 @@ +{ + "en": "$:/languages/en-GB", + "fr": "$:/languages/fr-FR", + "ja": "$:/languages/ja-JP", + "ru": "$:/languages/ru-RU", + "zh_CN": "$:/languages/zh-Hans" +} diff --git a/src/constants/channels.ts b/src/constants/channels.ts index 6620d0c9..6cd6dc06 100644 --- a/src/constants/channels.ts +++ b/src/constants/channels.ts @@ -51,6 +51,8 @@ export enum WikiChannel { openTiddler = 'wiki-open-tiddler', printTiddler = 'print-tiddler', sendActionMessage = 'wiki-send-action-message', + setTiddlerText = 'wiki-set-tiddler-text', + setTiddlerTextDone = 'wiki-set-tiddler-text-done', /** show message inside tiddlywiki to show git sync progress */ syncProgress = 'wiki-sync-progress', } diff --git a/src/preload/wikiOperation.ts b/src/preload/wikiOperation.ts index 3a9f13ce..496bded2 100644 --- a/src/preload/wikiOperation.ts +++ b/src/preload/wikiOperation.ts @@ -25,6 +25,13 @@ ipcRenderer.on(WikiChannel.getTiddlerText, async (event, title: string) => { `) as Promise); await ipcRenderer.invoke(WikiChannel.getTiddlerTextDone, tiddlerText); }); +// set tiddler text +ipcRenderer.on(WikiChannel.setTiddlerText, async (event, title: string, value: string) => { + const tiddlerText: string = await (webFrame.executeJavaScript(` + $tw.wiki.setText('${title}', 'text', undefined, \`${value}\`); + `) as Promise); + await ipcRenderer.invoke(WikiChannel.setTiddlerTextDone, tiddlerText); +}); // add snackbar to notify user ipcRenderer.on(WikiChannel.syncProgress, async (event, message: string) => { await webFrame.executeJavaScript(` diff --git a/src/services/libs/i18n/buildLanguageMenu.ts b/src/services/libs/i18n/buildLanguageMenu.ts index 137e95d5..a20956d6 100644 --- a/src/services/libs/i18n/buildLanguageMenu.ts +++ b/src/services/libs/i18n/buildLanguageMenu.ts @@ -5,13 +5,18 @@ import type { IWindowService } from '@services/windows/interface'; import serviceIdentifier from '@services/serviceIdentifier'; import { container } from '@services/container'; import { LOCALIZATION_FOLDER } from '@/constants/paths'; -import { I18NChannels } from '@/constants/channels'; +import { I18NChannels, WikiChannel } from '@/constants/channels'; import type { IPreferenceService } from '@services/preferences/interface'; import type { IViewService } from '@services/view/interface'; import type { IMenuService, DeferredMenuItemConstructorOptions } from '@services/menu/interface'; +import { ipcMain } from 'electron'; const supportedLanguagesMap = JSON.parse(fs.readFileSync(path.join(LOCALIZATION_FOLDER, 'supportedLanguages.json'), 'utf-8')) as Record; +const tiddlywikiLanguagesMap = JSON.parse(fs.readFileSync(path.join(LOCALIZATION_FOLDER, 'tiddlywikiLanguages.json'), 'utf-8')) as Record< + string, + string | undefined +>; const supportedLanguagesKNames = Object.keys(supportedLanguagesMap); @@ -29,15 +34,47 @@ export function buildLanguageMenu(): void { label: supportedLanguagesMap[language], click: async () => { const i18n = (await import('./')).default; + const { logger } = await import('../log'); await Promise.all([preferenceService.set('language', language), i18n.changeLanguage(language)]); viewService.forEachView((view) => { view.webContents.send(I18NChannels.changeLanguageRequest, { lng: language, }); }); + // change tiddlygit language await windowService.sendToAllWindows(I18NChannels.changeLanguageRequest, { lng: language, }); + // change tiddlywiki language + await new Promise((resolve, reject) => { + let inProgressCounter = 0; + // we don't wait more than 10s + const twLanguageUpdateTimeout = 10_000; + const tiddlywikiLanguageName = tiddlywikiLanguagesMap[language]; + if (tiddlywikiLanguageName !== undefined) { + viewService.forEachView((view) => { + inProgressCounter += 1; + ipcMain.once(WikiChannel.setTiddlerTextDone, () => { + inProgressCounter -= 1; + if (inProgressCounter === 0) { + resolve(); + } + }); + view.webContents.send(WikiChannel.setTiddlerText, '$:/language', tiddlywikiLanguageName); + }); + setTimeout(() => { + logger.error( + `When click language menu "${language}", language "${tiddlywikiLanguageName}" is too slow to update, inProgressCounter is ${inProgressCounter} after ${twLanguageUpdateTimeout}ms.`, + ); + }, twLanguageUpdateTimeout); + } else { + logger.error(`When click language menu "${language}", there is no corresponding tiddlywiki language registered`, { + supportedLanguagesMap, + tiddlywikiLanguagesMap, + }); + resolve(); + } + }); await menuService.buildMenu(); }, });