import { registerLocaleData } from '@angular/common'; import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { CultureInfo } from '../../model/culture-info'; import { LoggingService } from '../logging/logging-service'; import { TypeUtils } from '../utilities/type-utils.service'; const availableCultures: CultureInfo[] = require('../../../../assets/localization/available-cultures.json'); @Injectable() export class CultureService { private cultureValues = new Map(); // cultures by name private cultureChangeSubject = new Subject(); private currentCulture: CultureInfo; constructor( private typeUtils: TypeUtils, private logger: LoggingService ) { if (availableCultures) { this.cultureValues = new Map(); availableCultures.forEach(culture => { this.cultureValues.set(culture.name, culture); }); } } getCultureValues(): CultureInfo[] { const values: CultureInfo[] = []; this.cultureValues.forEach((value) => values.push(value)); return values; } getCultureValue(culture: string): CultureInfo | undefined { return this.cultureValues.get(culture); } cultureSelected(culture: string | CultureInfo) { let newCultureName: string; if (this.typeUtils.isString(culture)) { if (this.currentCulture && this.currentCulture.name === culture) { return; } newCultureName = culture; } else { if (this.currentCulture && this.currentCulture.name === culture.name) { return; } newCultureName = culture.name; } const newCulture = this.cultureValues.get(newCultureName); if (!newCulture) { console.error(`unsupported culture given: ${newCultureName}`); //TODO: throw error? return; } this.currentCulture = newCulture; this.cultureChangeSubject.next(newCulture); // 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 = newCulture.name; 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.name.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); } }); } }); } getCultureChangeObservable(): Observable { return this.cultureChangeSubject.asObservable(); } getCurrentCulture(): CultureInfo { return this.currentCulture || this.cultureValues.get('en-US'); //TODO: fix this } }