From 71743bf292c859dfe9d542486cc54bb72bc62e5b Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 3 Jul 2023 18:47:11 +0200 Subject: [PATCH] #598: initial configuration for a multilingual UI --- l10n/bundle.l10n.de.json | 4 ++++ l10n/bundle.l10n.json | 4 ++++ package-lock.json | 13 ++++++++++++ package.json | 21 ++++++++++++++----- src/dashboardWebView/DashboardCommand.ts | 5 ++++- src/dashboardWebView/DashboardMessage.ts | 1 + .../components/Header/Header.tsx | 3 ++- .../components/Header/Startup.tsx | 3 ++- src/dashboardWebView/hooks/useMessages.tsx | 7 +++++++ src/extension.ts | 12 +++++++++++ src/listeners/dashboard/SettingsListener.ts | 16 +++++++++++++- 11 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 l10n/bundle.l10n.de.json create mode 100644 l10n/bundle.l10n.json diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json new file mode 100644 index 00000000..8a56e539 --- /dev/null +++ b/l10n/bundle.l10n.de.json @@ -0,0 +1,4 @@ +{ + "header.createContent": "Inhalte erstellen", + "header.startup.label": "Beim Start öffnen?" +} \ No newline at end of file diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json new file mode 100644 index 00000000..5075f245 --- /dev/null +++ b/l10n/bundle.l10n.json @@ -0,0 +1,4 @@ +{ + "header.createContent": "Create content", + "header.startup.label": "Open on startup?" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 990e6023..6138cfb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "@typescript-eslint/eslint-plugin": "^5.50.0", "@typescript-eslint/parser": "^5.50.0", "@vscode/codicons": "0.0.20", + "@vscode/l10n": "^0.0.14", "@vscode/webview-ui-toolkit": "^0.9.1", "@webpack-cli/serve": "^1.6.0", "ajv": "^8.12.0", @@ -1517,6 +1518,12 @@ "dev": true, "license": "CC-BY-4.0" }, + "node_modules/@vscode/l10n": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.14.tgz", + "integrity": "sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg==", + "dev": true + }, "node_modules/@vscode/vsce": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.17.0.tgz", @@ -13932,6 +13939,12 @@ "version": "0.0.20", "dev": true }, + "@vscode/l10n": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.14.tgz", + "integrity": "sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg==", + "dev": true + }, "@vscode/vsce": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.17.0.tgz", diff --git a/package.json b/package.json index f8951353..13a20065 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,9 @@ }, "qna": "https://github.com/estruyf/vscode-front-matter/discussions", "engines": { - "vscode": "^1.70.0" + "vscode": "^1.73.0" }, + "l10n": "./l10n", "categories": [ "Other" ], @@ -584,12 +585,18 @@ "markdownDescription": "Specify if you want to show the date on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date)" }, "frontMatter.dashboard.content.card.fields.description": { - "type": ["null", "string"], + "type": [ + "null", + "string" + ], "default": "", "markdownDescription": "Specify the name of the metadata field that will be used to show the description on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description)" }, "frontMatter.dashboard.content.card.fields.title": { - "type": ["null", "string"], + "type": [ + "null", + "string" + ], "default": "", "markdownDescription": "Specify the name of the metadata field that will be used to show the title on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title)" }, @@ -1247,7 +1254,10 @@ }, "contentTypeValue": { "type": "string", - "enum": ["path", "slug"], + "enum": [ + "path", + "slug" + ], "default": "path", "description": "Specify the value to insert for the contentRelationship field" }, @@ -2412,10 +2422,11 @@ "@types/react": "17.0.0", "@types/react-datepicker": "^4.1.7", "@types/react-dom": "17.0.0", - "@types/vscode": "^1.70.0", + "@types/vscode": "^1.73.0", "@typescript-eslint/eslint-plugin": "^5.50.0", "@typescript-eslint/parser": "^5.50.0", "@vscode/codicons": "0.0.20", + "@vscode/l10n": "^0.0.14", "@vscode/webview-ui-toolkit": "^0.9.1", "@webpack-cli/serve": "^1.6.0", "ajv": "^8.12.0", diff --git a/src/dashboardWebView/DashboardCommand.ts b/src/dashboardWebView/DashboardCommand.ts index 465d2ebd..b4d80f93 100644 --- a/src/dashboardWebView/DashboardCommand.ts +++ b/src/dashboardWebView/DashboardCommand.ts @@ -10,5 +10,8 @@ export enum DashboardCommand { searchReady = 'searchReady', // Taxonomy dashboard - setTaxonomyData = 'setTaxonomyData' + setTaxonomyData = 'setTaxonomyData', + + // Localization + setLocalization = 'setLocalization' } diff --git a/src/dashboardWebView/DashboardMessage.ts b/src/dashboardWebView/DashboardMessage.ts index a1427074..2bbba352 100644 --- a/src/dashboardWebView/DashboardMessage.ts +++ b/src/dashboardWebView/DashboardMessage.ts @@ -56,6 +56,7 @@ export enum DashboardMessage { moveTaxonomy = 'moveTaxonomy', // Other + getLocalization = 'getLocalization', getTheme = 'getTheme', updateSetting = 'updateSetting', setState = 'setState', diff --git a/src/dashboardWebView/components/Header/Header.tsx b/src/dashboardWebView/components/Header/Header.tsx index eb9148ea..d97d2c58 100644 --- a/src/dashboardWebView/components/Header/Header.tsx +++ b/src/dashboardWebView/components/Header/Header.tsx @@ -29,6 +29,7 @@ import useThemeColors from '../../hooks/useThemeColors'; import { Startup } from './Startup'; import { Navigation } from './Navigation'; import { ProjectSwitcher } from './ProjectSwitcher'; +import * as l10n from '@vscode/l10n'; export interface IHeaderProps { header?: React.ReactNode; @@ -168,7 +169,7 @@ export const Header: React.FunctionComponent = ({ = ({ ) }`} > - Open on startup? + {l10n.t(`header.startup.label`)} diff --git a/src/dashboardWebView/hooks/useMessages.tsx b/src/dashboardWebView/hooks/useMessages.tsx index d85011bb..f51d754d 100644 --- a/src/dashboardWebView/hooks/useMessages.tsx +++ b/src/dashboardWebView/hooks/useMessages.tsx @@ -15,6 +15,7 @@ import { Messenger } from '@estruyf/vscode/dist/client'; import { EventData } from '@estruyf/vscode/dist/models'; import { NavigationType } from '../models'; import { GeneralCommands } from '../../constants'; +import * as l10n from '@vscode/l10n'; export default function useMessages() { const [loading, setLoading] = useRecoilState(LoadingAtom); @@ -59,6 +60,11 @@ export default function useMessages() { case GeneralCommands.toWebview.setMode: setMode(message.payload); break; + case DashboardCommand.setLocalization: + l10n.config({ + contents: message.payload + }) + break; } }; @@ -70,6 +76,7 @@ export default function useMessages() { Messenger.send(DashboardMessage.getTheme); Messenger.send(DashboardMessage.getData); Messenger.send(DashboardMessage.getMode); + Messenger.send(DashboardMessage.getLocalization); return () => { Messenger.unlisten(messageListener); diff --git a/src/extension.ts b/src/extension.ts index cd1ba360..46f1dd30 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,6 +13,7 @@ import { ModeSwitch } from './services/ModeSwitch'; import { PagesParser } from './services/PagesParser'; import { ContentType, Telemetry, Extension } from './helpers'; import { TaxonomyType, DashboardData } from './models'; +import * as l10n from '@vscode/l10n'; import { Backers, Diagnostics, @@ -41,6 +42,17 @@ export async function activate(context: vscode.ExtensionContext) { const extension = Extension.getInstance(context); Backers.init(context).then(() => {}); + // Make sure the EN language file is loaded + if (!vscode.l10n.uri) { + l10n.config({ + fsPath: vscode.Uri.parse(`${extensionPath}/l10n/bundle.l10n.json`).fsPath + }); + } else { + l10n.config({ + fsPath: vscode.l10n.uri.fsPath + }); + } + if (!extension.checkIfExtensionCanRun()) { return undefined; } diff --git a/src/listeners/dashboard/SettingsListener.ts b/src/listeners/dashboard/SettingsListener.ts index 93d5a9a4..9341ecc2 100644 --- a/src/listeners/dashboard/SettingsListener.ts +++ b/src/listeners/dashboard/SettingsListener.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import { commands, Uri } from 'vscode'; +import { commands, Uri, l10n } from 'vscode'; import { Folders } from '../../commands/Folders'; import { COMMAND_NAME, @@ -21,6 +21,7 @@ import { DataListener } from '../panel'; import { MarkdownFoldingProvider } from '../../providers/MarkdownFoldingProvider'; import { ModeSwitch } from '../../services/ModeSwitch'; import { PagesListener } from './PagesListener'; +import { readFileAsync } from '../../utils'; export class SettingsListener extends BaseListener { /** @@ -34,6 +35,9 @@ export class SettingsListener extends BaseListener { case DashboardMessage.getData: this.getSettings(); break; + case DashboardMessage.getLocalization: + this.getLocalization(); + break; case DashboardMessage.updateSetting: this.update(msg.payload); break; @@ -49,6 +53,16 @@ export class SettingsListener extends BaseListener { } } + public static async getLocalization() { + const localeFilePath = + l10n.uri?.fsPath || + Uri.parse(`${Extension.getInstance().extensionPath}/l10n/bundle.l10n.json`).fsPath; + + const fileContents = await readFileAsync(localeFilePath, 'utf-8'); + + this.sendMsg(DashboardCommand.setLocalization, fileContents); + } + public static async switchProject(project: string) { if (project) { this.sendMsg(DashboardCommand.loading, true);