mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-1571: Check available translations rather than hardcoding which use the default.
This commit is contained in:
committed by
Mike Jumper
parent
77bd5e116a
commit
3ed5b62589
@@ -34,16 +34,16 @@ angular.module('client').directive('guacClientNotification', [function guacClien
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The client whose status should be displayed.
|
* The client whose status should be displayed.
|
||||||
*
|
*
|
||||||
* @type ManagedClient
|
* @type ManagedClient
|
||||||
*/
|
*/
|
||||||
client : '='
|
client : '='
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
directive.controller = ['$scope', '$injector', '$element',
|
directive.controller = ['$scope', '$injector', '$element',
|
||||||
function guacClientNotificationController($scope, $injector, $element) {
|
function guacClientNotificationController($scope, $injector, $element) {
|
||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
const ManagedClient = $injector.get('ManagedClient');
|
const ManagedClient = $injector.get('ManagedClient');
|
||||||
const ManagedClientState = $injector.get('ManagedClientState');
|
const ManagedClientState = $injector.get('ManagedClientState');
|
||||||
@@ -53,6 +53,7 @@ angular.module('client').directive('guacClientNotification', [function guacClien
|
|||||||
const $location = $injector.get('$location');
|
const $location = $injector.get('$location');
|
||||||
const authenticationService = $injector.get('authenticationService');
|
const authenticationService = $injector.get('authenticationService');
|
||||||
const guacClientManager = $injector.get('guacClientManager');
|
const guacClientManager = $injector.get('guacClientManager');
|
||||||
|
const guacTranslate = $injector.get('guacTranslate');
|
||||||
const requestService = $injector.get('requestService');
|
const requestService = $injector.get('requestService');
|
||||||
const userPageService = $injector.get('userPageService');
|
const userPageService = $injector.get('userPageService');
|
||||||
|
|
||||||
@@ -65,26 +66,6 @@ angular.module('client').directive('guacClientNotification', [function guacClien
|
|||||||
*/
|
*/
|
||||||
$scope.status = false;
|
$scope.status = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* All client error codes handled and passed off for translation. Any error
|
|
||||||
* code not present in this list will be represented by the "DEFAULT"
|
|
||||||
* translation.
|
|
||||||
*/
|
|
||||||
const CLIENT_ERRORS = {
|
|
||||||
0x0201: true,
|
|
||||||
0x0202: true,
|
|
||||||
0x0203: true,
|
|
||||||
0x0207: true,
|
|
||||||
0x0208: true,
|
|
||||||
0x0209: true,
|
|
||||||
0x020A: true,
|
|
||||||
0x020B: true,
|
|
||||||
0x0301: true,
|
|
||||||
0x0303: true,
|
|
||||||
0x0308: true,
|
|
||||||
0x031D: true
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All error codes for which automatic reconnection is appropriate when a
|
* All error codes for which automatic reconnection is appropriate when a
|
||||||
* client error occurs.
|
* client error occurs.
|
||||||
@@ -98,26 +79,7 @@ angular.module('client').directive('guacClientNotification', [function guacClien
|
|||||||
0x0301: true,
|
0x0301: true,
|
||||||
0x0308: true
|
0x0308: true
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* All tunnel error codes handled and passed off for translation. Any error
|
|
||||||
* code not present in this list will be represented by the "DEFAULT"
|
|
||||||
* translation.
|
|
||||||
*/
|
|
||||||
const TUNNEL_ERRORS = {
|
|
||||||
0x0201: true,
|
|
||||||
0x0202: true,
|
|
||||||
0x0203: true,
|
|
||||||
0x0204: true,
|
|
||||||
0x0205: true,
|
|
||||||
0x0207: true,
|
|
||||||
0x0208: true,
|
|
||||||
0x0301: true,
|
|
||||||
0x0303: true,
|
|
||||||
0x0308: true,
|
|
||||||
0x031D: true
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All error codes for which automatic reconnection is appropriate when a
|
* All error codes for which automatic reconnection is appropriate when a
|
||||||
* tunnel error occurs.
|
* tunnel error occurs.
|
||||||
@@ -239,7 +201,7 @@ angular.module('client').directive('guacClientNotification', [function guacClien
|
|||||||
// Get any associated status code
|
// Get any associated status code
|
||||||
const status = $scope.client.clientState.statusCode;
|
const status = $scope.client.clientState.statusCode;
|
||||||
|
|
||||||
// Connecting
|
// Connecting
|
||||||
if (connectionState === ManagedClientState.ConnectionState.CONNECTING
|
if (connectionState === ManagedClientState.ConnectionState.CONNECTING
|
||||||
|| connectionState === ManagedClientState.ConnectionState.WAITING) {
|
|| connectionState === ManagedClientState.ConnectionState.WAITING) {
|
||||||
$scope.status = {
|
$scope.status = {
|
||||||
@@ -254,44 +216,58 @@ angular.module('client').directive('guacClientNotification', [function guacClien
|
|||||||
// Client error
|
// Client error
|
||||||
else if (connectionState === ManagedClientState.ConnectionState.CLIENT_ERROR) {
|
else if (connectionState === ManagedClientState.ConnectionState.CLIENT_ERROR) {
|
||||||
|
|
||||||
// Determine translation name of error
|
// Translation IDs for this error code
|
||||||
const errorName = (status in CLIENT_ERRORS) ? status.toString(16).toUpperCase() : "DEFAULT";
|
const errorPrefix = "CLIENT.ERROR_CLIENT_";
|
||||||
|
const errorId = errorPrefix + status.toString(16).toUpperCase();
|
||||||
|
const defaultErrorId = errorPrefix + "DEFAULT";
|
||||||
|
|
||||||
// Determine whether the reconnect countdown applies
|
// Determine whether the reconnect countdown applies
|
||||||
const countdown = (status in CLIENT_AUTO_RECONNECT) ? RECONNECT_COUNTDOWN : null;
|
const countdown = (status in CLIENT_AUTO_RECONNECT) ? RECONNECT_COUNTDOWN : null;
|
||||||
|
|
||||||
// Show error status
|
// Use the guacTranslate service to determine if there is a translation for
|
||||||
notifyConnectionClosed({
|
// this error code; if not, use the default
|
||||||
className : "error",
|
guacTranslate(errorId, defaultErrorId).then(
|
||||||
title : "CLIENT.DIALOG_HEADER_CONNECTION_ERROR",
|
|
||||||
text : {
|
// Show error status
|
||||||
key : "CLIENT.ERROR_CLIENT_" + errorName
|
translationResult => notifyConnectionClosed({
|
||||||
},
|
className : "error",
|
||||||
countdown : countdown,
|
title : "CLIENT.DIALOG_HEADER_CONNECTION_ERROR",
|
||||||
actions : actions
|
text : {
|
||||||
});
|
key : translationResult.id
|
||||||
|
},
|
||||||
|
countdown : countdown,
|
||||||
|
actions : actions
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tunnel error
|
// Tunnel error
|
||||||
else if (connectionState === ManagedClientState.ConnectionState.TUNNEL_ERROR) {
|
else if (connectionState === ManagedClientState.ConnectionState.TUNNEL_ERROR) {
|
||||||
|
|
||||||
// Determine translation name of error
|
// Translation IDs for this error code
|
||||||
const errorName = (status in TUNNEL_ERRORS) ? status.toString(16).toUpperCase() : "DEFAULT";
|
const errorPrefix = "CLIENT.ERROR_TUNNEL_";
|
||||||
|
const errorId = errorPrefix + status.toString(16).toUpperCase();
|
||||||
|
const defaultErrorId = errorPrefix + "DEFAULT";
|
||||||
|
|
||||||
// Determine whether the reconnect countdown applies
|
// Determine whether the reconnect countdown applies
|
||||||
const countdown = (status in TUNNEL_AUTO_RECONNECT) ? RECONNECT_COUNTDOWN : null;
|
const countdown = (status in TUNNEL_AUTO_RECONNECT) ? RECONNECT_COUNTDOWN : null;
|
||||||
|
|
||||||
// Show error status
|
// Use the guacTranslate service to determine if there is a translation for
|
||||||
notifyConnectionClosed({
|
// this error code; if not, use the default
|
||||||
className : "error",
|
guacTranslate(errorId, defaultErrorId).then(
|
||||||
title : "CLIENT.DIALOG_HEADER_CONNECTION_ERROR",
|
|
||||||
text : {
|
// Show error status
|
||||||
key : "CLIENT.ERROR_TUNNEL_" + errorName
|
translationResult => notifyConnectionClosed({
|
||||||
},
|
className : "error",
|
||||||
countdown : countdown,
|
title : "CLIENT.DIALOG_HEADER_CONNECTION_ERROR",
|
||||||
actions : actions
|
text : {
|
||||||
});
|
key : translationResult.id
|
||||||
|
},
|
||||||
|
countdown : countdown,
|
||||||
|
actions : actions
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ angular.module('client').directive('guacFileTransfer', [function guacFileTransfe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The file transfer to display.
|
* The file transfer to display.
|
||||||
*
|
*
|
||||||
* @type ManagedFileUpload|ManagedFileDownload
|
* @type ManagedFileUpload|ManagedFileDownload
|
||||||
*/
|
*/
|
||||||
transfer : '='
|
transfer : '='
|
||||||
@@ -40,27 +40,12 @@ angular.module('client').directive('guacFileTransfer', [function guacFileTransfe
|
|||||||
templateUrl: 'app/client/templates/guacFileTransfer.html',
|
templateUrl: 'app/client/templates/guacFileTransfer.html',
|
||||||
controller: ['$scope', '$injector', function guacFileTransferController($scope, $injector) {
|
controller: ['$scope', '$injector', function guacFileTransferController($scope, $injector) {
|
||||||
|
|
||||||
|
// Required services
|
||||||
|
const guacTranslate = $injector.get('guacTranslate');
|
||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
var ManagedFileTransferState = $injector.get('ManagedFileTransferState');
|
var ManagedFileTransferState = $injector.get('ManagedFileTransferState');
|
||||||
|
|
||||||
/**
|
|
||||||
* All upload error codes handled and passed off for translation.
|
|
||||||
* Any error code not present in this list will be represented by
|
|
||||||
* the "DEFAULT" translation.
|
|
||||||
*/
|
|
||||||
var UPLOAD_ERRORS = {
|
|
||||||
0x0100: true,
|
|
||||||
0x0201: true,
|
|
||||||
0x0202: true,
|
|
||||||
0x0203: true,
|
|
||||||
0x0204: true,
|
|
||||||
0x0205: true,
|
|
||||||
0x0301: true,
|
|
||||||
0x0303: true,
|
|
||||||
0x0308: true,
|
|
||||||
0x031D: true
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the unit string that is most appropriate for the
|
* Returns the unit string that is most appropriate for the
|
||||||
* number of bytes transferred thus far - either 'gb', 'mb', 'kb',
|
* number of bytes transferred thus far - either 'gb', 'mb', 'kb',
|
||||||
@@ -193,7 +178,7 @@ angular.module('client').directive('guacFileTransfer', [function guacFileTransfe
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Save file
|
// Save file
|
||||||
saveAs($scope.transfer.blob, $scope.transfer.filename);
|
saveAs($scope.transfer.blob, $scope.transfer.filename);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -210,23 +195,20 @@ angular.module('client').directive('guacFileTransfer', [function guacFileTransfe
|
|||||||
return $scope.transfer.transferState.streamState === ManagedFileTransferState.StreamState.ERROR;
|
return $scope.transfer.transferState.streamState === ManagedFileTransferState.StreamState.ERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The translated error message for the current status code
|
||||||
* Returns the text of the current error as a translation string.
|
$scope.translatedErrorMessage = '';
|
||||||
*
|
|
||||||
* @returns {String}
|
$scope.$watch('transfer.transferState.statusCode', function statusCodeChanged(statusCode) {
|
||||||
* The name of the translation string containing the text
|
|
||||||
* associated with the current error.
|
|
||||||
*/
|
|
||||||
$scope.getErrorText = function getErrorText() {
|
|
||||||
|
|
||||||
// Determine translation name of error
|
// Determine translation name of error
|
||||||
var status = $scope.transfer.transferState.statusCode;
|
const errorName = 'CLIENT.ERROR_UPLOAD_' + statusCode.toString(16).toUpperCase();
|
||||||
var errorName = (status in UPLOAD_ERRORS) ? status.toString(16).toUpperCase() : "DEFAULT";
|
|
||||||
|
|
||||||
// Return translation string
|
// Use translation string, or the default if no translation is found for this error code
|
||||||
return 'CLIENT.ERROR_UPLOAD_' + errorName;
|
guacTranslate(errorName, 'CLIENT.ERROR_UPLOAD_DEFAULT').then(
|
||||||
|
translationResult => $scope.translatedErrorMessage = translationResult.message
|
||||||
|
);
|
||||||
|
|
||||||
};
|
});
|
||||||
|
|
||||||
}] // end file transfer controller
|
}] // end file transfer controller
|
||||||
|
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around the angular-translate $translate service that offers a
|
||||||
|
* convenient way to fall back to a default translation if the requested
|
||||||
|
* translation is not available.
|
||||||
|
*/
|
||||||
|
angular.module('client').factory('guacTranslate', ['$injector', function guacTranslate($injector) {
|
||||||
|
|
||||||
|
// Required services
|
||||||
|
const $q = $injector.get('$q');
|
||||||
|
const $translate = $injector.get('$translate');
|
||||||
|
|
||||||
|
// Required types
|
||||||
|
const TranslationResult = $injector.get('TranslationResult');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a promise that will be resolved with a TranslationResult containg either the
|
||||||
|
* requested ID and message (if translated), or the default ID and message if translated,
|
||||||
|
* or the literal value of `defaultTranslationId` for both the ID and message if neither
|
||||||
|
* is translated.
|
||||||
|
*
|
||||||
|
* @param {String} translationId
|
||||||
|
* The requested translation ID, which may or may not be translated.
|
||||||
|
*
|
||||||
|
* @param {Sting} defaultTranslationId
|
||||||
|
* The translation ID that will be used if no translation is found for `translationId`.
|
||||||
|
*
|
||||||
|
* @returns {Promise.<TranslationResult>}
|
||||||
|
* A promise which resolves with a TranslationResult containing the results from
|
||||||
|
* the translation attempt.
|
||||||
|
*/
|
||||||
|
function translateWithFallback(translationId, defaultTranslationId) {
|
||||||
|
const deferredTranslation = $q.defer();
|
||||||
|
|
||||||
|
// Attempt to translate the requested translation ID
|
||||||
|
$translate(translationId).then(
|
||||||
|
|
||||||
|
// If the requested translation is available, use that
|
||||||
|
translation => deferredTranslation.resolve(new TranslationResult({
|
||||||
|
id: translationId, message: translation
|
||||||
|
})),
|
||||||
|
|
||||||
|
// Otherwise, try the default translation ID
|
||||||
|
() => $translate(defaultTranslationId).then(
|
||||||
|
|
||||||
|
// Default translation worked, so use that
|
||||||
|
defaultTranslation =>
|
||||||
|
deferredTranslation.resolve(new TranslationResult({
|
||||||
|
id: defaultTranslationId, message: defaultTranslation
|
||||||
|
})),
|
||||||
|
|
||||||
|
// Neither translation is available; as a fallback, return default ID for both
|
||||||
|
() => deferredTranslation.resolve(new TranslationResult({
|
||||||
|
id: defaultTranslationId, message: defaultTranslationId
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return deferredTranslation.promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
return translateWithFallback;
|
||||||
|
|
||||||
|
}]);
|
@@ -10,7 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Error text -->
|
<!-- Error text -->
|
||||||
<p class="error-text">{{getErrorText() | translate}}</p>
|
<p class="error-text">{{translatedErrorMessage}}</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the TranslationResult class used by the guacTranslate service. This class contains
|
||||||
|
* both the translated message and the translation ID that generated the message, in the case
|
||||||
|
* where it's unknown whether a translation is defined or not.
|
||||||
|
*/
|
||||||
|
angular.module('client').factory('TranslationResult', [function defineTranslationResult() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object which represents the result of a translation as returned from
|
||||||
|
* the guacTranslate service.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {TranslationResult|Object} [template={}]
|
||||||
|
* The object whose properties should be copied within the new
|
||||||
|
* TranslationResult.
|
||||||
|
*/
|
||||||
|
const TranslationResult = function TranslationResult(template) {
|
||||||
|
|
||||||
|
// Use empty object by default
|
||||||
|
template = template || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The translation ID.
|
||||||
|
*
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
this.id = template.id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The translated message.
|
||||||
|
*
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
this.message = template.message;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return TranslationResult;
|
||||||
|
|
||||||
|
}]);
|
Reference in New Issue
Block a user