import { Injectable } from '@angular/core'; import { Platform, Events } from '@ionic/angular'; import { Globalization } from '@ionic-native/globalization/ngx'; import { Translation } from './Translation'; import { HttpClient } from '@angular/common/http'; import { NativeStorage } from '@ionic-native/native-storage/ngx'; @Injectable({ providedIn: 'root' }) export class TranslatorService { public static LNG_KEY = 'current-language'; public static EN = 'en'; public static EN_US = 'en-us'; public static AR = 'ar'; public static CURRENT_LANGUAGE = TranslatorService.EN; public static CHANGE_EVENT = 'language-changed-event'; private static translations: any; constructor( private platform: Platform, private glob: Globalization, private httpClient: HttpClient, private nativeStorage: NativeStorage, private events: Events ) { } public static getCurrentLanguageCode(): number { switch (TranslatorService.CURRENT_LANGUAGE) { case TranslatorService.EN: return 2; case TranslatorService.AR: return 1; default: return 2; } } public static getCurrentDirection(): string { return TranslatorService.getCurrentLanguageName() === TranslatorService.AR ? 'rtl' : 'ltr'; } public async getCurrentSystemLanguageName() { const lng = await this.glob.getPreferredLanguage(); if (lng && lng.value) { return lng.value.toLowerCase(); } else { return TranslatorService.EN_US; } } public static getCurrentLanguageName(): string { return TranslatorService.CURRENT_LANGUAGE; } private isLoaded(): boolean { return TranslatorService.translations != null; } /* load system translation files */ private loadTranslationAssetNative(onSuccess: any) { this.httpClient.get('assets/localization/i18n.json').subscribe(data => { TranslatorService.translations = data; if (data) { if (!this.isSystemLanguageSupported()) { this.setCurrentLanguageToDefault(); } if (onSuccess) { onSuccess(); } } }); } private isSystemLanguageSupported(): boolean { for (const lng of TranslatorService.translations.SUPPORTED_LANGUAGES) { if (TranslatorService.CURRENT_LANGUAGE === lng) { return true; } } return false; } /* get current system prefered language */ public loadResourcesNative(onSuccess: any) { this.platform.ready().then(() => { this.glob.getPreferredLanguage().then(res => { const lang = res.value.split('-')[0]; TranslatorService.CURRENT_LANGUAGE = lang; this.loadTranslationAssetNative(onSuccess); }).catch(err => { this.setCurrentLanguageToDefault(); this.loadTranslationAssetNative(onSuccess); }); }); } private loadTranslationAsset(onSuccess: any) { this.httpClient.get('assets/localization/i18n.json').subscribe(data => { TranslatorService.translations = data; if (data) { if (onSuccess) { onSuccess(); } } }); } public loadResources(onSuccess: any) { this.platform.ready().then(() => { this.nativeStorage.getItem(TranslatorService.LNG_KEY).then((previousLanguage: string) => { TranslatorService.CURRENT_LANGUAGE = previousLanguage; this.loadTranslationAsset(onSuccess); }, () => { this.setCurrentLanguageToDefault(); this.loadTranslationAsset(onSuccess); }); }); } /* translate key depend on current prefered language */ public translate(trans: Translation): string { if (this.isLoaded()) { const page = TranslatorService.translations[trans.page]; if (page) { const word = page[trans.key]; if (word) { return word[TranslatorService.CURRENT_LANGUAGE]; } } } return ''; } private isValidTranslation(trans: Translation): boolean { if (trans != null) { return trans.isValid(); } return false; } /* shortcut for translate */ public tr(trans: Translation): string { return this.translate(trans); } /* translate with page and key */ public trPK(page: string, key: string): string { return this.translate(new Translation(page, key)); } public trInline(pageKey: string): string { if (pageKey) { const parts = pageKey.split(','); if (parts.length === 2) { return this.trPK(parts[0].trim(), parts[1].trim()); } } else { return ''; } } private setCurrentLanguageToDefault() { TranslatorService.CURRENT_LANGUAGE = TranslatorService.EN; } public setCurrentLanguage(language: string) { TranslatorService.CURRENT_LANGUAGE = language; this.events.publish(TranslatorService.CHANGE_EVENT); this.nativeStorage.setItem(TranslatorService.LNG_KEY, language).then(() => { }, () => { }); } public switchLanguage() { this.nativeStorage.getItem(TranslatorService.LNG_KEY).then((previousLanguage: string) => { this.setCurrentLanguage(this.getNextLanguage(previousLanguage)); }, () => { this.setCurrentLanguage(this.getNextLanguage(TranslatorService.CURRENT_LANGUAGE)); }); } private getNextLanguage(currentLanguage: string) { return (currentLanguage === TranslatorService.EN) ? TranslatorService.AR : TranslatorService.EN; } }