diff --git a/www/js/app.js b/www/js/app.js index bfe47746f3abb2584fa11bb4dee1647311c5a9b1..b6e9fdf0cdd65e81b5be99df51eb26c730cab458 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -407,29 +407,9 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht } }); - var onLanguageChange = function() { - var lang = $translate.use(); - console.debug('[app] Locale ['+lang+']'); - - // config moment lib - try { - moment.locale(lang.substr(0,2)); - } - catch(err) { - moment.locale('en'); - console.warn('[app] Unknown local for moment lib. Using default [en]'); - } - - // config numeral lib - try { - numeral.language(lang.substr(0,2)); - } - catch(err) { - numeral.language('en'); - console.warn('[app] Unknown local for numeral lib. Using default [en]'); - } - - // Set some translation need by filters + // Update some translations, when locale changed + function onLocaleChange() { + console.debug('[app] Loading cached translations for locale [{0}]'.format($translate.use())); $translate(['COMMON.DATE_PATTERN', 'COMMON.DATE_SHORT_PATTERN', 'COMMON.UD']) .then(function(translations) { $rootScope.translations = $rootScope.translations || {}; @@ -446,17 +426,14 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht $rootScope.translations.UD = 'UD'; } }); - - }; - - // Set up moment translation - $rootScope.$on('$translateChangeSuccess', onLanguageChange); + } + csSettings.api.locale.on.changed($rootScope, onLocaleChange, this); // start plugin PluginService.start(); - // set locale to vendor lib - onLanguageChange(); + // Force at least on call + onLocaleChange(); }) ; diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js index e13027a2239b8a21c481ac55ec4ec0a0b2941983..85291c56b98e544b53a82f70da1b735f19f2326f 100644 --- a/www/js/controllers/settings-controllers.js +++ b/www/js/controllers/settings-controllers.js @@ -43,12 +43,14 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt // Fill locales $scope.locales = angular.copy(csSettings.locales); - var locale = _.findWhere($scope.locales, {id: csSettings.defaultSettings.locale.id}); + + // Apply settings angular.merge($scope.formData, csSettings.data); - $scope.formData.locale = locale; - if (csSettings.data.locale && csSettings.data.locale.id) { - $scope.formData.locale = _.findWhere($scope.locales, {id: csSettings.data.locale.id}); - } + + // Make sure to use full locale object (id+name) + $scope.formData.locale = (csSettings.data.locale && csSettings.data.locale.id && _.findWhere($scope.locales, {id: csSettings.data.locale.id})) || + _.findWhere($scope.locales, {id: csSettings.defaultSettings.locale.id}); + $scope.loading = false; $timeout(function() { @@ -63,9 +65,12 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt $scope.actionsPopover.hide(); } $scope.pendingSaving = true; - csSettings.reset(); - angular.merge($scope.formData, csSettings.data); - $scope.pendingSaving = false; + csSettings.reset() + .then(function() { + // reload + $scope.load(); + $scope.pendingSaving = false; + }); }; $scope.changeLanguage = function(langKey) { diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index 53dca121e713343731af846b91ee184f70bc704a..996d1a148ed15584cd883e7038977af8d0591c8a 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -1,7 +1,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.config', 'cesium.device.services']) -.factory('csSettings', function($q, Api, localStorage, $translate, csConfig, Device) { +.factory('csSettings', function($rootScope, $q, Api, localStorage, $translate, csConfig, Device) { 'ngInject'; function Factory() { @@ -30,13 +30,22 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi // If another locale exists with the same root: use it var similarLocale = _.find(locales, function(l) { - return String.prototype.startsWith.call(l, locale); + return String.prototype.startsWith.call(l.id, locale); }); - if (similarLocale) return similarLocale; + if (similarLocale) return similarLocale.id; return fallbackLocale; } + // Convert browser locale to app locale (fix #140) + function fixLocaleWithLog (locale) { + var fixedLocale = fixLocale(locale); + if (locale != fixedLocale) { + console.debug('[settings] Fix locale [{0}] -> [{1}]'.format(locale, fixedLocale)); + } + return fixedLocale; + } + var constants = { STORAGE_KEY: 'CESIUM_SETTINGS' @@ -77,11 +86,11 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi notificationReadTime: 0 }, locale: { - id: fixLocale(csConfig.defaultLanguage || $translate.use()) // use config locale if set, or browser default + id: fixLocaleWithLog(csConfig.defaultLanguage || $translate.use()) // use config locale if set, or browser default } }, csConfig), - data = angular.copy(defaultSettings), + data = {}, previousData, api = new Api(this, "csSettings"), @@ -90,8 +99,10 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi _.keys(data).forEach(function(key){ delete data[key]; }); - angular.merge(data, defaultSettings); - api.data.raisePromise.reset(data) + + applyData(defaultSettings); + + return api.data.raisePromise.reset(data) .then(store); }, @@ -129,7 +140,32 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi .then(emitChangedEvent); }, - restore = function(first) { + applyData = function(newData) { + var localeChanged = false; + if (newData.locale && newData.locale.id) { + // Fix previously stored locale (could use bad format) + newData.locale.id = fixLocale(newData.locale.id); + localeChanged = !data.locale || newData.locale.id !== data.locale.id || newData.locale.id !== $translate.use(); + } + + // Apply stored settings + angular.merge(data, newData); + + // Always force the usage of deffault settings + // This is a workaround for DEV (TODO: implement edition in settings ?) + data.timeWarningExpire = defaultSettings.timeWarningExpire; + data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership; + data.cacheTimeMs = defaultSettings.cacheTimeMs; + data.timeout = defaultSettings.timeout; + + // Apply the new locale (only if need) + if (localeChanged) { + $translate.use(fixLocale(data.locale.id)); // will produce an event cached by onLocaleChange(); + } + + }, + + restore = function() { var now = new Date().getTime(); return $q(function(resolve, reject){ console.debug("[settings] Loading from local storage..."); @@ -142,12 +178,9 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi // No settings stored if (!storedData) { - console.debug("[settings] No settings in local storage"); - if (data.locale.id !== $translate.use()) { - console.debug("[settings] Changing locale to [{0}]...".format(data.locale.id)); - $translate.use(data.locale.id); - finishRestore(); - } + console.debug("[settings] No settings in local storage. Using defaults."); + applyData(defaultSettings); + finishRestore(); return; } @@ -176,37 +209,48 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi delete storedData.DUNITER_NODE_ES; } - var localeChanged = false; - if (storedData.locale && storedData.locale.id) { - // Fix previously stored bad locale - storedData.locale.id = fixLocale(storedData.locale.id); - localeChanged = (storedData.locale.id !== data.locale.id || storedData.locale.id !== $translate.use()); - } - - // Apply stored settings - angular.merge(data, storedData); - - // Always force the usage of deffault settings - // This is a workaround for DEV (TODO: implement edition in settings ?) - data.timeWarningExpire = defaultSettings.timeWarningExpire; - data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership; - data.cacheTimeMs = defaultSettings.cacheTimeMs; - data.timeout = defaultSettings.timeout; - - // Apply the new locale (only if need) - if (localeChanged) { - $translate.use(fixLocale(data.locale.id)); - } + // Apply stored data + applyData(storedData); console.debug('[settings] Loaded from local storage in '+(new Date().getTime()-now)+'ms'); finishRestore(); }); + }, + + // Detect locale sucessuf changes, then apply to vendor libs + onLocaleChange = function() { + var locale = $translate.use(); + console.debug('[settings] Locale ['+locale+']'); + + // config moment lib + try { + moment.locale(locale.substr(0,2)); + } + catch(err) { + moment.locale('en'); + console.warn('[settings] Unknown local for moment lib. Using default [en]'); + } + + // config numeral lib + try { + numeral.language(locale.substr(0,2)); + } + catch(err) { + numeral.language('en'); + console.warn('[settings] Unknown local for numeral lib. Using default [en]'); + } + + // Emit event + api.locale.raise.changed(locale); }; + $rootScope.$on('$translateChangeSuccess', onLocaleChange); + api.registerEvent('data', 'reset'); api.registerEvent('data', 'changed'); api.registerEvent('data', 'store'); api.registerEvent('data', 'ready'); + api.registerEvent('locale', 'changed'); return { data: data,