1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 16:23:44 +00:00

[PM-6511] New i18n for angular (#8122)

* Use state provider to store preferred language

* migrate preferred language

* Use new i18n provider to get LOCAL_ID

* Fix preloaded english i18n

This is a mock service that forces english translations, it doesn't need the i18n interface that allows changing of locales.

* PR improvements

* Fixup merge
This commit is contained in:
Matt Gibson
2024-03-11 12:59:19 -05:00
committed by GitHub
parent c10a59b019
commit f4150ffda6
25 changed files with 278 additions and 106 deletions

View File

@@ -29,6 +29,7 @@ import { MigrationBuilderService } from "@bitwarden/common/platform/services/mig
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
/* eslint-disable import/no-restricted-paths -- Implementation for memory storage */
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
import { GlobalStateProvider } from "@bitwarden/common/platform/state";
import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service";
/* eslint-enable import/no-restricted-paths -- Implementation for memory storage */
@@ -74,7 +75,7 @@ import { WebPlatformUtilsService } from "./web-platform-utils.service";
{
provide: I18nServiceAbstraction,
useClass: I18nService,
deps: [SYSTEM_LANGUAGE, LOCALES_DIRECTORY],
deps: [SYSTEM_LANGUAGE, LOCALES_DIRECTORY, GlobalStateProvider],
},
{ provide: AbstractStorageService, useClass: HtmlStorageService },
{

View File

@@ -1,20 +1,30 @@
import { I18nService as BaseI18nService } from "@bitwarden/common/platform/services/i18n.service";
import { GlobalStateProvider } from "@bitwarden/common/platform/state";
import { SupportedTranslationLocales } from "../../translation-constants";
export class I18nService extends BaseI18nService {
constructor(systemLanguage: string, localesDirectory: string) {
super(systemLanguage || "en-US", localesDirectory, async (formattedLocale: string) => {
const filePath =
this.localesDirectory +
"/" +
formattedLocale +
"/messages.json?cache=" +
process.env.CACHE_TAG;
const localesResult = await fetch(filePath);
const locales = await localesResult.json();
return locales;
});
constructor(
systemLanguage: string,
localesDirectory: string,
globalStateProvider: GlobalStateProvider,
) {
super(
systemLanguage || "en-US",
localesDirectory,
async (formattedLocale: string) => {
const filePath =
this.localesDirectory +
"/" +
formattedLocale +
"/messages.json?cache=" +
process.env.CACHE_TAG;
const localesResult = await fetch(filePath);
const locales = await localesResult.json();
return locales;
},
globalStateProvider,
);
this.supportedTranslationLocales = SupportedTranslationLocales;
}

View File

@@ -50,8 +50,7 @@ export class InitService {
setTimeout(() => this.notificationsService.init(), 3000);
await this.vaultTimeoutService.init(true);
const locale = await this.stateService.getLocale();
await (this.i18nService as I18nService).init(locale);
await (this.i18nService as I18nService).init();
(this.eventUploadService as EventUploadService).init(true);
this.twoFactorService.init();
const htmlEl = this.win.document.documentElement;

View File

@@ -1,16 +1,23 @@
import { APP_INITIALIZER, NgModule } from "@angular/core";
import { Observable, of } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { I18nService as BaseI18nService } from "@bitwarden/common/platform/services/i18n.service";
import { TranslationService } from "@bitwarden/common/platform/services/translation.service";
import eng from "../../../locales/en/messages.json";
class PreloadedEnglishI18nService extends BaseI18nService {
class PreloadedEnglishI18nService extends TranslationService implements I18nService {
translationLocale = "en";
locale$: Observable<string> = of("en");
constructor() {
super("en", "", () => {
return Promise.resolve(eng);
});
}
setLocale(): Promise<void> {
throw new Error("Method not implemented.");
}
}
function i18nInitializer(i18nService: I18nService): () => Promise<void> {

View File

@@ -142,7 +142,7 @@ export class PreferencesComponent implements OnInit {
),
enableFavicons: !(await this.settingsService.getDisableFavicon()),
theme: await this.stateService.getTheme(),
locale: (await this.stateService.getLocale()) ?? null,
locale: (await firstValueFrom(this.i18nService.locale$)) ?? null,
};
this.startingLocale = initialFormValues.locale;
this.startingTheme = initialFormValues.theme;
@@ -169,7 +169,7 @@ export class PreferencesComponent implements OnInit {
await this.themingService.updateConfiguredTheme(values.theme);
this.startingTheme = values.theme;
}
await this.stateService.setLocale(values.locale);
await this.i18nService.setLocale(values.locale);
if (values.locale !== this.startingLocale) {
window.location.reload();
} else {