mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-30 00:23:21 +00:00 
			
		
		
		
	Merge pull request #160 from glyptodon/fix-language-defaults
GUAC-1053: Fix language defaults
This commit is contained in:
		| @@ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * Copyright (C) 2014 Glyptodon LLC |  * Copyright (C) 2015 Glyptodon LLC | ||||||
|  * |  * | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  * of this software and associated documentation files (the "Software"), to deal |  * of this software and associated documentation files (the "Software"), to deal | ||||||
| @@ -23,18 +23,25 @@ | |||||||
| /** | /** | ||||||
|  * The configuration block for setting up everything having to do with i18n. |  * The configuration block for setting up everything having to do with i18n. | ||||||
|  */ |  */ | ||||||
| angular.module('index').config(['$translateProvider', function($translateProvider) { | angular.module('index').config(['$injector', function($injector) { | ||||||
|  |  | ||||||
|     // Use US English by default |     // Required providers | ||||||
|     $translateProvider.preferredLanguage('en_US'); |     var $translateProvider        = $injector.get('$translateProvider'); | ||||||
|  |     var preferenceServiceProvider = $injector.get('preferenceServiceProvider'); | ||||||
|  |  | ||||||
|     // Load translations from static JSON files |     // Fallback to US English | ||||||
|     $translateProvider.useStaticFilesLoader({ |     var fallbackLanguages = ['en_US']; | ||||||
|         prefix: 'translations/', |  | ||||||
|         suffix: '.json' |     // Prefer chosen language, use fallback languages if necessary | ||||||
|  |     $translateProvider.fallbackLanguage(fallbackLanguages); | ||||||
|  |     $translateProvider.preferredLanguage(preferenceServiceProvider.preferences.language); | ||||||
|  |  | ||||||
|  |     // Load translations via translationLoader service | ||||||
|  |     $translateProvider.useLoader('translationLoader', { | ||||||
|  |         fallbackLanguages : fallbackLanguages | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     // Provide pluralization, etc. via messageformat.js |     // Provide pluralization, etc. via messageformat.js | ||||||
|     $translateProvider.useMessageFormatInterpolation(); |     $translateProvider.useMessageFormatInterpolation(); | ||||||
|  |  | ||||||
| }]); | }]); | ||||||
|   | |||||||
| @@ -0,0 +1,114 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (C) 2015 Glyptodon LLC | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in | ||||||
|  |  * all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  * THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Service for loading translation definition files, conforming to the | ||||||
|  |  * angular-translate documentation for custom translation loaders: | ||||||
|  |  *  | ||||||
|  |  * https://github.com/angular-translate/angular-translate/wiki/Asynchronous-loading#using-custom-loader-service | ||||||
|  |  */ | ||||||
|  | angular.module('locale').factory('translationLoader', ['$injector', function translationLoader($injector) { | ||||||
|  |  | ||||||
|  |     // Required services | ||||||
|  |     var $http        = $injector.get('$http'); | ||||||
|  |     var $q           = $injector.get('$q'); | ||||||
|  |     var cacheService = $injector.get('cacheService'); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Satisfies a translation request for the given key by searching for the | ||||||
|  |      * translation files for each key in the given array, in order. The request | ||||||
|  |      * fails only if none of the files can be found. | ||||||
|  |      * | ||||||
|  |      * @param {Deferred} deferred | ||||||
|  |      *     The Deferred object to resolve or reject depending on whether at | ||||||
|  |      *     least one translation file can be successfully loaded. | ||||||
|  |      * | ||||||
|  |      * @param {String} requestedKey | ||||||
|  |      *     The originally-requested language key. | ||||||
|  |      * | ||||||
|  |      * @param {String[]} remainingKeys | ||||||
|  |      *     The keys of the languages to attempt to load, in order, where the | ||||||
|  |      *     first key in this array is the language to try within this function | ||||||
|  |      *     call. The first key in the array is not necessarily the originally- | ||||||
|  |      *     requested language key. | ||||||
|  |      */ | ||||||
|  |     var satisfyTranslation = function satisfyTranslation(deferred, requestedKey, remainingKeys) { | ||||||
|  |  | ||||||
|  |         // Get current language key | ||||||
|  |         var currentKey = remainingKeys.shift(); | ||||||
|  |  | ||||||
|  |         // If no languages to try, just fail | ||||||
|  |         if (!currentKey) { | ||||||
|  |             deferred.reject(requestedKey); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Attempt to retrieve language | ||||||
|  |         $http({ | ||||||
|  |             cache   : cacheService.languages, | ||||||
|  |             method  : 'GET', | ||||||
|  |             url     : 'translations/' + encodeURIComponent(currentKey) + '.json' | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // Resolve promise if translation retrieved successfully | ||||||
|  |         .success(function translationFileRetrieved(translation) { | ||||||
|  |             deferred.resolve(translation); | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // Retry with remaining languages if translation file could not be retrieved | ||||||
|  |         .error(function translationFileUnretrievable() { | ||||||
|  |             satisfyTranslation(deferred, requestedKey, remainingKeys); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Custom loader function for angular-translate which loads the desired | ||||||
|  |      * language file dynamically via HTTP. If the language file cannot be | ||||||
|  |      * found, the fallback language is used instead. | ||||||
|  |      * | ||||||
|  |      * @param {Object} options | ||||||
|  |      *     Arbitrary options, containing at least a "key" property which | ||||||
|  |      *     contains the requested language key. | ||||||
|  |      * | ||||||
|  |      * @returns {Promise.<Object>} | ||||||
|  |      *     A promise which resolves to the requested translation string object. | ||||||
|  |      */ | ||||||
|  |     return function loadTranslationFile(options) { | ||||||
|  |  | ||||||
|  |         var translation = $q.defer(); | ||||||
|  |  | ||||||
|  |         // Get requested language from options | ||||||
|  |         var requestedKey = options.key; | ||||||
|  |  | ||||||
|  |         // Append fallback languages to requested language | ||||||
|  |         var keys = [requestedKey].concat(options.fallbackLanguages); | ||||||
|  |  | ||||||
|  |         // Satisfy the translation request | ||||||
|  |         satisfyTranslation(translation, requestedKey, keys); | ||||||
|  |  | ||||||
|  |         // Return promise which is resolved only after the translation file is loaded | ||||||
|  |         return translation.promise; | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  | }]); | ||||||
| @@ -24,17 +24,20 @@ | |||||||
|  * A service for setting and retrieving browser-local preferences. Preferences |  * A service for setting and retrieving browser-local preferences. Preferences | ||||||
|  * may be any JSON-serializable type. |  * may be any JSON-serializable type. | ||||||
|  */ |  */ | ||||||
| angular.module('settings').factory('preferenceService', ['$injector', | angular.module('settings').provider('preferenceService', function preferenceServiceProvider() { | ||||||
|         function preferenceService($injector) { |  | ||||||
|  |  | ||||||
|     // Required services |     /** | ||||||
|     var $rootScope = $injector.get('$rootScope'); |      * Reference to the provider itself. | ||||||
|     var $translate = $injector.get('$translate'); |      * | ||||||
|     var $window    = $injector.get('$window'); |      * @type preferenceServiceProvider | ||||||
|  |      */ | ||||||
|  |     var provider = this; | ||||||
|  |  | ||||||
|     var service = {}; |     /** | ||||||
|  |      * The storage key of Guacamole preferences within local storage. | ||||||
|     // The parameter name for getting the history from local storage |      * | ||||||
|  |      * @type String | ||||||
|  |      */ | ||||||
|     var GUAC_PREFERENCES_STORAGE_KEY = "GUAC_PREFERENCES"; |     var GUAC_PREFERENCES_STORAGE_KEY = "GUAC_PREFERENCES"; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -42,7 +45,7 @@ angular.module('settings').factory('preferenceService', ['$injector', | |||||||
|      * |      * | ||||||
|      * @type Object.<String, String> |      * @type Object.<String, String> | ||||||
|      */ |      */ | ||||||
|     service.inputMethods = { |     var inputMethods = { | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * No input method is used. Keyboard events are generated from a |          * No input method is used. Keyboard events are generated from a | ||||||
| @@ -74,13 +77,31 @@ angular.module('settings').factory('preferenceService', ['$injector', | |||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the key of the language currently in use within the browser. | ||||||
|  |      * This is not necessarily the user's desired language, but is rather the | ||||||
|  |      * language user by the browser's interface. | ||||||
|  |      * | ||||||
|  |      * @returns {String} | ||||||
|  |      *     The key of the language currently in use within the browser. | ||||||
|  |      */ | ||||||
|  |     var getDefaultLanguageKey = function getDefaultLanguageKey() { | ||||||
|  |  | ||||||
|  |         // Pull browser language, falling back to US English | ||||||
|  |         var language = navigator.language || navigator.browserLanguage || 'en_US'; | ||||||
|  |  | ||||||
|  |         // Convert to format used internally | ||||||
|  |         return language.replace(/-/g, '_'); | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * All currently-set preferences, as name/value pairs. Each property name |      * All currently-set preferences, as name/value pairs. Each property name | ||||||
|      * corresponds to the name of a preference. |      * corresponds to the name of a preference. | ||||||
|      * |      * | ||||||
|      * @type Object.<String, Object> |      * @type Object.<String, Object> | ||||||
|      */ |      */ | ||||||
|     service.preferences = { |     this.preferences = { | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * Whether translation of touch to mouse events should emulate an |          * Whether translation of touch to mouse events should emulate an | ||||||
| @@ -96,28 +117,14 @@ angular.module('settings').factory('preferenceService', ['$injector', | |||||||
|          * |          * | ||||||
|          * @type String |          * @type String | ||||||
|          */ |          */ | ||||||
|         inputMethod : service.inputMethods.NONE, |         inputMethod : inputMethods.NONE, | ||||||
|          |          | ||||||
|         /** |         /** | ||||||
|          * The selected language. |          * The key of the desired display language. | ||||||
|          *  |          *  | ||||||
|          * @type String |          * @type String | ||||||
|          */ |          */ | ||||||
|         language : $translate.use() |         language : getDefaultLanguageKey() | ||||||
|  |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Persists the current values of all preferences, if possible. |  | ||||||
|      */ |  | ||||||
|     service.save = function save() { |  | ||||||
|  |  | ||||||
|         // Save updated preferences, ignore inability to use localStorage |  | ||||||
|         try { |  | ||||||
|             if (localStorage) |  | ||||||
|                 localStorage.setItem(GUAC_PREFERENCES_STORAGE_KEY, JSON.stringify(service.preferences)); |  | ||||||
|         } |  | ||||||
|         catch (ignore) {} |  | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -127,25 +134,65 @@ angular.module('settings').factory('preferenceService', ['$injector', | |||||||
|         if (localStorage) { |         if (localStorage) { | ||||||
|             var preferencesJSON = localStorage.getItem(GUAC_PREFERENCES_STORAGE_KEY); |             var preferencesJSON = localStorage.getItem(GUAC_PREFERENCES_STORAGE_KEY); | ||||||
|             if (preferencesJSON) |             if (preferencesJSON) | ||||||
|                 angular.extend(service.preferences, JSON.parse(preferencesJSON)); |                 angular.extend(provider.preferences, JSON.parse(preferencesJSON)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     } |     } | ||||||
|     catch (ignore) {} |     catch (ignore) {} | ||||||
|  |  | ||||||
|     // Persist settings when window is unloaded |     // Factory method required by provider | ||||||
|     $window.addEventListener('unload', service.save); |     this.$get = ['$injector', function preferenceServiceFactory($injector) { | ||||||
|  |  | ||||||
|     // Persist settings upon navigation  |         // Required services | ||||||
|     $rootScope.$on('$routeChangeSuccess', function handleNavigate() { |         var $rootScope = $injector.get('$rootScope'); | ||||||
|         service.save(); |         var $window    = $injector.get('$window'); | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     // Persist settings upon logout |         var service = {}; | ||||||
|     $rootScope.$on('guacLogout', function handleLogout() { |  | ||||||
|         service.save(); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     return service; |         /** | ||||||
|  |          * All valid input method type names. | ||||||
|  |          * | ||||||
|  |          * @type Object.<String, String> | ||||||
|  |          */ | ||||||
|  |         service.inputMethods = inputMethods; | ||||||
|  |  | ||||||
| }]); |         /** | ||||||
|  |          * All currently-set preferences, as name/value pairs. Each property name | ||||||
|  |          * corresponds to the name of a preference. | ||||||
|  |          * | ||||||
|  |          * @type Object.<String, Object> | ||||||
|  |          */ | ||||||
|  |         service.preferences = provider.preferences; | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Persists the current values of all preferences, if possible. | ||||||
|  |          */ | ||||||
|  |         service.save = function save() { | ||||||
|  |  | ||||||
|  |             // Save updated preferences, ignore inability to use localStorage | ||||||
|  |             try { | ||||||
|  |                 if (localStorage) | ||||||
|  |                     localStorage.setItem(GUAC_PREFERENCES_STORAGE_KEY, JSON.stringify(service.preferences)); | ||||||
|  |             } | ||||||
|  |             catch (ignore) {} | ||||||
|  |  | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         // Persist settings when window is unloaded | ||||||
|  |         $window.addEventListener('unload', service.save); | ||||||
|  |  | ||||||
|  |         // Persist settings upon navigation  | ||||||
|  |         $rootScope.$on('$routeChangeSuccess', function handleNavigate() { | ||||||
|  |             service.save(); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         // Persist settings upon logout | ||||||
|  |         $rootScope.$on('guacLogout', function handleLogout() { | ||||||
|  |             service.save(); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         return service; | ||||||
|  |  | ||||||
|  |     }]; | ||||||
|  |  | ||||||
|  | }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user