Path: blob/main/src/vs/workbench/services/localization/browser/localeService.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { localize } from '../../../../nls.js';6import { Language, LANGUAGE_DEFAULT } from '../../../../base/common/platform.js';7import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';8import { ILanguagePackItem } from '../../../../platform/languagePacks/common/languagePacks.js';9import { IActiveLanguagePackService, ILocaleService } from '../common/locale.js';10import { IHostService } from '../../host/browser/host.js';11import { IProductService } from '../../../../platform/product/common/productService.js';12import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';13import { CancellationToken } from '../../../../base/common/cancellation.js';14import { IExtensionGalleryService } from '../../../../platform/extensionManagement/common/extensionManagement.js';15import { ILogService } from '../../../../platform/log/common/log.js';1617const localeStorage = new class LocaleStorage {1819private static readonly LOCAL_STORAGE_LOCALE_KEY = 'vscode.nls.locale';20private static readonly LOCAL_STORAGE_EXTENSION_ID_KEY = 'vscode.nls.languagePackExtensionId';2122setLocale(locale: string): void {23localStorage.setItem(LocaleStorage.LOCAL_STORAGE_LOCALE_KEY, locale);24this.doSetLocaleToCookie(locale);25}2627private doSetLocaleToCookie(locale: string): void {28document.cookie = `${LocaleStorage.LOCAL_STORAGE_LOCALE_KEY}=${locale};path=/;max-age=3153600000`;29}3031clearLocale(): void {32localStorage.removeItem(LocaleStorage.LOCAL_STORAGE_LOCALE_KEY);33this.doClearLocaleToCookie();34}3536private doClearLocaleToCookie(): void {37document.cookie = `${LocaleStorage.LOCAL_STORAGE_LOCALE_KEY}=;path=/;max-age=0`;38}3940setExtensionId(extensionId: string): void {41localStorage.setItem(LocaleStorage.LOCAL_STORAGE_EXTENSION_ID_KEY, extensionId);42}4344getExtensionId(): string | null {45return localStorage.getItem(LocaleStorage.LOCAL_STORAGE_EXTENSION_ID_KEY);46}4748clearExtensionId(): void {49localStorage.removeItem(LocaleStorage.LOCAL_STORAGE_EXTENSION_ID_KEY);50}51};5253export class WebLocaleService implements ILocaleService {5455declare readonly _serviceBrand: undefined;5657constructor(58@IDialogService private readonly dialogService: IDialogService,59@IHostService private readonly hostService: IHostService,60@IProductService private readonly productService: IProductService61) { }6263async setLocale(languagePackItem: ILanguagePackItem, _skipDialog = false): Promise<void> {64const locale = languagePackItem.id;65if (locale === Language.value() || (!locale && Language.value() === navigator.language.toLowerCase())) {66return;67}68if (locale) {69localeStorage.setLocale(locale);70if (languagePackItem.extensionId) {71localeStorage.setExtensionId(languagePackItem.extensionId);72}73} else {74localeStorage.clearLocale();75localeStorage.clearExtensionId();76}7778const restartDialog = await this.dialogService.confirm({79type: 'info',80message: localize('relaunchDisplayLanguageMessage', "To change the display language, {0} needs to reload", this.productService.nameLong),81detail: localize('relaunchDisplayLanguageDetail', "Press the reload button to refresh the page and set the display language to {0}.", languagePackItem.label),82primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"),83});8485if (restartDialog.confirmed) {86this.hostService.restart();87}88}8990async clearLocalePreference(): Promise<void> {91localeStorage.clearLocale();92localeStorage.clearExtensionId();9394if (Language.value() === navigator.language.toLowerCase()) {95return;96}9798const restartDialog = await this.dialogService.confirm({99type: 'info',100message: localize('clearDisplayLanguageMessage', "To change the display language, {0} needs to reload", this.productService.nameLong),101detail: localize('clearDisplayLanguageDetail', "Press the reload button to refresh the page and use your browser's language."),102primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"),103});104105if (restartDialog.confirmed) {106this.hostService.restart();107}108}109}110111class WebActiveLanguagePackService implements IActiveLanguagePackService {112_serviceBrand: undefined;113114constructor(115@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,116@ILogService private readonly logService: ILogService117) { }118119async getExtensionIdProvidingCurrentLocale(): Promise<string | undefined> {120const language = Language.value();121if (language === LANGUAGE_DEFAULT) {122return undefined;123}124const extensionId = localeStorage.getExtensionId();125if (extensionId) {126return extensionId;127}128129if (!this.galleryService.isEnabled()) {130return undefined;131}132133try {134const tagResult = await this.galleryService.query({ text: `tag:lp-${language}` }, CancellationToken.None);135136// Only install extensions that are published by Microsoft and start with vscode-language-pack for extra certainty137const extensionToInstall = tagResult.firstPage.find(e => e.publisher === 'MS-CEINTL' && e.name.startsWith('vscode-language-pack'));138if (extensionToInstall) {139localeStorage.setExtensionId(extensionToInstall.identifier.id);140return extensionToInstall.identifier.id;141}142143// TODO: If a non-Microsoft language pack is installed, we should prompt the user asking if they want to install that.144// Since no such language packs exist yet, we can wait until that happens to implement this.145} catch (e) {146// Best effort147this.logService.error(e);148}149150return undefined;151}152}153154registerSingleton(ILocaleService, WebLocaleService, InstantiationType.Delayed);155registerSingleton(IActiveLanguagePackService, WebActiveLanguagePackService, InstantiationType.Delayed);156157158