Vmeda.Online/src/providers/lang.ts

259 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import * as moment from 'moment';
import { Globalization } from '@ionic-native/globalization';
import { Platform } from 'ionic-angular';
import { CoreConfigProvider } from './config';
import { CoreConfigConstants } from '../configconstants';
/*
* Service to handle language features, like changing the current language.
*/
@Injectable()
export class CoreLangProvider {
fallbackLanguage:string = 'en'; // mmCoreConfigConstants.default_lang || 'en',
currentLanguage: string; // Save current language in a variable to speed up the get function.
customStrings = {};
customStringsRaw: string;
constructor(private translate: TranslateService, private configProvider: CoreConfigProvider, platform: Platform,
private globalization: Globalization) {
// Set fallback language and language to use until the app determines the right language to use.
translate.setDefaultLang(this.fallbackLanguage);
translate.use(this.fallbackLanguage);
platform.ready().then(() => {
this.getCurrentLanguage().then((language) => {
translate.use(language);
moment.locale(language);
});
});
this.decorateTranslate();
}
/**
* Change current language.
*
* @param {string} language New language to use.
* @return {Promise<any>} Promise resolved when the change is finished.
*/
changeCurrentLanguage(language: string) : Promise<any> {
let promises = [];
promises.push(this.translate.use(language));
promises.push(this.configProvider.set('current_language', language));
moment.locale(language);
this.currentLanguage = language;
return Promise.all(promises);
};
/**
* Clear current custom strings.
*/
clearCustomStrings() : void {
this.customStrings = {};
this.customStringsRaw = '';
};
/**
* Function to "decorate" the TranslateService.
* Basically, it extends the translate functions to use the custom lang strings.
*/
decorateTranslate() : void {
let originalGet = this.translate.get,
originalInstant = this.translate.instant;
// Redefine translate.get.
this.translate.get = (key: string|string[], interpolateParams?: object) => {
// Always call the original get function to avoid having to create our own Observables.
if (typeof key == 'string') {
let value = this.getCustomString(key);
if (typeof value != 'undefined') {
key = value;
}
} else {
key = this.getCustomStrings(key).translations;
}
return originalGet.apply(this.translate, [key, interpolateParams]);
};
// Redefine translate.instant.
this.translate.instant = (key: string|string[], interpolateParams?: object) => {
if (typeof key == 'string') {
let value = this.getCustomString(key);
if (typeof value != 'undefined') {
return value;
}
return originalInstant.apply(this.translate, [key, interpolateParams]);
} else {
let result = this.getCustomStrings(key);
if (result.allFound) {
return result.translations;
}
return originalInstant.apply(this.translate, [result.translations]);
}
};
}
/**
* Get all current custom strings.
*
* @return {any} Custom strings.
*/
getAllCustomStrings() : any {
return this.customStrings;
};
/**
* Get current language.
*
* @return {Promise<string>} Promise resolved with the current language.
*/
getCurrentLanguage() : Promise<string> {
if (typeof this.currentLanguage != 'undefined') {
return Promise.resolve(this.currentLanguage);
}
// Get current language from config (user might have changed it).
return this.configProvider.get('current_language').then((language) => {
return language;
}).catch(() => {
// User hasn't defined a language. If default language is forced, use it.
if (CoreConfigConstants.forcedefaultlanguage && !CoreConfigConstants.forcedefaultlanguage) {
return CoreConfigConstants.default_lang;
}
try {
// No forced language, try to get current language from cordova globalization.
return this.globalization.getPreferredLanguage().then((result) => {
let language = result.value.toLowerCase();
if (language.indexOf('-') > -1) {
// Language code defined by locale has a dash, like en-US or es-ES. Check if it's supported.
if (CoreConfigConstants.languages && typeof CoreConfigConstants.languages[language] == 'undefined') {
// Code is NOT supported. Fallback to language without dash. E.g. 'en-US' would fallback to 'en'.
language = language.substr(0, language.indexOf('-'));
}
}
return language;
}).catch(() => {
// Error getting locale. Use default language.
return this.fallbackLanguage;
});
} catch(err) {
// Error getting locale. Use default language.
return Promise.resolve(this.fallbackLanguage);
}
}).then((language) => {
this.currentLanguage = language; // Save it for later.
return language;
});
};
/**
* Get a custom string for a certain key.
*
* @param {string} key The key of the translation to get.
* @return {string} Translation, undefined if not found.
*/
getCustomString(key: string) : string {
let customStrings = this.getCustomStringsForLanguage();
if (customStrings && typeof customStrings[key] != 'undefined') {
return customStrings[key];
}
}
/**
* Get custom strings for several keys.
*
* @param {string[]} keys The keys of the translations to get.
* @return {any} Object with translations and a boolean indicating if all translations were found in custom strings.
*/
getCustomStrings(keys: string[]) : any {
let customStrings = this.getCustomStringsForLanguage(),
translations = [],
allFound = true;
keys.forEach((key : string) => {
if (customStrings && typeof customStrings[key] != 'undefined') {
translations.push(customStrings[key]);
} else {
allFound = false;
translations.push(key);
}
});
return {
allFound: allFound,
translations: translations
};
}
/**
* Get custom strings for a certain language.
*
* @param {string} [lang] The language to get. If not defined, return current language.
* @return {any} Custom strings.
*/
getCustomStringsForLanguage(lang?: string) : any {
lang = lang || this.currentLanguage;
return this.customStrings[lang];
};
/**
* Load certain custom strings.
*
* @param {string} strings Custom strings to load (tool_mobile_customlangstrings).
*/
loadCustomStrings(strings: string) : void {
if (strings == this.customStringsRaw) {
// Strings haven't changed, stop.
return;
}
// Reset current values.
this.clearCustomStrings();
if (!strings) {
return;
}
let list: string[] = strings.split(/(?:\r\n|\r|\n)/);
list.forEach((entry: string) => {
let values: string[] = entry.split('|'),
lang: string;
if (values.length < 3) {
// Not enough data, ignore the entry.
return;
}
lang = values[2];
if (!this.customStrings[lang]) {
this.customStrings[lang] = {};
}
this.customStrings[lang][values[0]] = values[1];
});
};
}