Jelajahi Sumber

Implements language selection (#4969)

Henning Dieterichs 3 minggu lalu
induk
melakukan
a4d7907bd4

+ 18 - 2
website/src/monaco-loader.ts

@@ -19,6 +19,7 @@ export interface IMonacoSetup {
 	loaderConfigPaths: Record<string, string>;
 	codiconUrl: string;
 	monacoTypesUrl: string | undefined;
+	language?: string;
 }
 
 let loading = false;
@@ -57,7 +58,18 @@ async function _loadMonaco(setup: IMonacoSetup): Promise<typeof monaco> {
 
 	/** @type {any} */
 	const req = global.require as any;
-	req.config({ paths: setup.loaderConfigPaths });
+
+	// Configure language if specified
+	const config: any = { paths: setup.loaderConfigPaths };
+	if (setup.language) {
+		config["vs/nls"] = {
+			availableLanguages: {
+				"*": setup.language,
+			},
+		};
+	}
+
+	req.config(config);
 
 	return new Promise((res) => {
 		// First load editor.main. If it inlines the plugins, we don't want to try to load them from the server.
@@ -97,7 +109,10 @@ export const prodMonacoSetup = getMonacoSetup(
 	"node_modules/monaco-editor/min/vs"
 );
 
-export function getMonacoSetup(corePath: string): IMonacoSetup {
+export function getMonacoSetup(
+	corePath: string,
+	language?: string
+): IMonacoSetup {
 	const loaderConfigPaths = {
 		vs: `${corePath}`,
 	};
@@ -107,5 +122,6 @@ export function getMonacoSetup(corePath: string): IMonacoSetup {
 		loaderConfigPaths,
 		codiconUrl: `${corePath}/base/browser/ui/codicons/codicon/codicon.ttf`,
 		monacoTypesUrl: undefined,
+		language,
 	};
 }

+ 1 - 1
website/src/website/pages/playground/Preview.tsx

@@ -1,7 +1,7 @@
 import * as React from "react";
 import { PlaygroundModel } from "./PlaygroundModel";
 import { observer } from "mobx-react";
-import { autorun, observable, reaction } from "mobx";
+import { observable, reaction } from "mobx";
 import {
 	IMessageFromRunner,
 	IMessageToRunner,

+ 66 - 0
website/src/website/pages/playground/SettingsDialog.tsx

@@ -390,6 +390,72 @@ export class SettingsDialog extends React.Component<{
 								</Vertical>
 							</div>
 						</ListGroup.Item>
+
+						<ListGroup.Item>
+							<div className="d-flex gap-2">
+								<label className="d-flex gap-2">
+									<span>
+										Language/Localization
+										<small className="d-block text-muted">
+											Configure the Monaco Editor language
+											for UI elements. Leave unconfigured
+											to use default English.
+										</small>
+									</span>
+								</label>
+								<Select
+									value={ref(
+										modelSettings.settings,
+										"language"
+									)}
+									values={[
+										undefined,
+										"de",
+										"es",
+										"fr",
+										"it",
+										"ja",
+										"ko",
+										"ru",
+										"zh-cn",
+										"zh-tw",
+									]}
+									getLabel={(v) => {
+										switch (v) {
+											case undefined:
+												return "Unconfigured (English)";
+											case "de":
+												return "German (Deutsch)";
+											case "es":
+												return "Spanish (Español)";
+											case "fr":
+												return "French (Français)";
+											case "it":
+												return "Italian (Italiano)";
+											case "ja":
+												return "Japanese (日本語)";
+											case "ko":
+												return "Korean (한국어)";
+											case "ru":
+												return "Russian (Русский)";
+											case "zh-cn":
+												return "Chinese Simplified (简体中文)";
+											case "zh-tw":
+												return "Chinese Traditional (繁體中文)";
+											default:
+												return (
+													v ||
+													"Unconfigured (English)"
+												);
+										}
+									}}
+									style={{
+										width: 250,
+										marginLeft: "auto",
+									}}
+								/>
+							</div>
+						</ListGroup.Item>
 					</ListGroup>
 				</Modal.Body>
 				<Modal.Footer>

+ 10 - 3
website/src/website/pages/playground/SettingsModel.ts

@@ -88,6 +88,8 @@ export interface Settings {
 
 	previewFullScreen: boolean;
 	autoReload: boolean | undefined;
+
+	language?: string;
 }
 
 export type JsonString<T> = string;
@@ -97,14 +99,18 @@ export function toLoaderConfig(settings: Settings): IMonacoSetup {
 		case "latest":
 			return {
 				...getMonacoSetup(
-					`node_modules/monaco-editor/${settings.latestStability}/vs`
+					`node_modules/monaco-editor/${settings.latestStability}/vs`,
+					settings.language
 				),
 				monacoTypesUrl: "node_modules/monaco-editor/monaco.d.ts",
 			};
 		case "npm":
 			const url = `https://cdn.jsdelivr.net/npm/monaco-editor@${settings.npmVersion}`;
 			return {
-				...getMonacoSetup(`${url}/${settings.npmStability}/vs`),
+				...getMonacoSetup(
+					`${url}/${settings.npmStability}/vs`,
+					settings.language
+				),
 				monacoTypesUrl: `${url}/monaco.d.ts`,
 			};
 		case "custom":
@@ -143,7 +149,7 @@ export function toLoaderConfig(settings: Settings): IMonacoSetup {
 					break;
 			}
 
-			const setup = { ...getMonacoSetup(coreUrl) };
+			const setup = { ...getMonacoSetup(coreUrl, settings.language) };
 			if (
 				!setup.monacoTypesUrl &&
 				setup.loaderConfigPaths["vs"] &&
@@ -186,6 +192,7 @@ export function getDefaultSettings(): Settings {
 		}),
 		previewFullScreen: false,
 		autoReload: true,
+		language: undefined,
 	};
 	return defaultSettings;
 }