import { registerLocaleData } from '@angular/common'; import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { LoggingService } from '../logging/logging-service'; import { TypeUtils } from '../utilities/type-utils.service'; import { LanguageInfo } from '@app/core/model/language-info'; const availableLanguageInfos: LanguageInfo[] = require('../../../../assets/localization/languages.json'); @Injectable() export class LanguageInfoService { private languageInfoValues = new Map(); // cultures by name private languageInfoeChangeSubject = new Subject(); private currentLanguageInfo: LanguageInfo; constructor( private typeUtils: TypeUtils, private logger: LoggingService ) { if (availableLanguageInfos) { this.languageInfoValues = new Map(); availableLanguageInfos.forEach(languageInfo => { this.languageInfoValues.set(languageInfo.code, languageInfo); }); } } getLanguageInfoValues(): LanguageInfo[] { const values: LanguageInfo[] = []; this.languageInfoValues.forEach((value) => values.push(value)); return values; } getLanguageInfoValue(languageInfo: string): LanguageInfo | undefined { return this.languageInfoValues.get(languageInfo); } languageInfoSelected(languageInfo: string | LanguageInfo) { let newLanguageInfoName: string; if (this.typeUtils.isString(languageInfo)) { if (this.currentLanguageInfo && this.currentLanguageInfo.code === languageInfo) { return; } newLanguageInfoName = languageInfo; } else { if (this.currentLanguageInfo && this.currentLanguageInfo.code === languageInfo.code) { return; } newLanguageInfoName = languageInfo.code; } const newLanguageInfo = this.languageInfoValues.get(newLanguageInfoName); if (!newLanguageInfo) { console.error(`unsupported language given: ${newLanguageInfoName}`); //TODO: throw error? return; } this.currentLanguageInfo = newLanguageInfo; this.languageInfoeChangeSubject.next(newLanguageInfo); // Set angular locale based on user selection. // This is a very hacky way to map cultures with angular cultures, since there is no mapping. We first try to // use the culture with the specialization (ex en-US), and if not exists we import the base culture (first part). let locale = newLanguageInfo.code; import(`@angular/common/locales/${locale}.js`).catch(reason => { this.logger.error('Could not load locale: ' + locale); }).then(selectedLocale => { if (selectedLocale) { registerLocaleData(selectedLocale.default); } else { // locale = newCulture.code.split('-')[0]; import(`@angular/common/locales/${locale}.js`).catch(reason => { this.logger.error('Could not load locale: ' + locale); }).then(selectedDefaultLocale => { if (selectedDefaultLocale !== undefined) { registerLocaleData(selectedDefaultLocale.default); } }); } }); } getLanguageInfoChangeObservable(): Observable { return this.languageInfoeChangeSubject.asObservable(); } getCurrentLanguageInfo(): LanguageInfo { return this.currentLanguageInfo; } }