{{'CLIENT.HELP_CLIPBOARD' | translate}}
diff --git a/guacamole/src/main/webapp/app/client/directives/guacFileTransfer.js b/guacamole/src/main/webapp/app/client/directives/guacFileTransfer.js new file mode 100644 index 000000000..87b7ae949 --- /dev/null +++ b/guacamole/src/main/webapp/app/client/directives/guacFileTransfer.js @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 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. + */ + +/** + * Directive which displays an active file transfer, providing links for + * downloads, if applicable. + */ +angular.module('client').directive('guacFileTransfer', [function guacFileTransfer() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The file transfer to display. + * + * @type ManagedFileUpload|ManagedFileDownload + */ + transfer : '=' + + }, + + templateUrl: 'app/client/templates/guacFileTransfer.html', + controller: ['$scope', '$injector', function guacFileTransferController($scope, $injector) { + + /* STUB */ + + }] + + }; +}]); diff --git a/guacamole/src/main/webapp/app/client/directives/guacFileTransferManager.js b/guacamole/src/main/webapp/app/client/directives/guacFileTransferManager.js new file mode 100644 index 000000000..d49e94288 --- /dev/null +++ b/guacamole/src/main/webapp/app/client/directives/guacFileTransferManager.js @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2014 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. + */ + +/** + * Directive which displays all active file transfers. + */ +angular.module('client').directive('guacFileTransferManager', [function guacFileTransferManager() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The client whose file transfers should be managed by this + * directive. + * + * @type ManagerClient + */ + client : '=' + + }, + + templateUrl: 'app/client/templates/guacFileTransferManager.html', + controller: ['$scope', '$injector', function guacFileTransferManagerController($scope, $injector) { + + // Required types + var ManagedClient = $injector.get('ManagedClient'); + var ManagedFileTransferState = $injector.get('ManagedFileTransferState'); + + /** + * Determines whether the attached client has associated file + * transfers, regardless of those file transfers' state. + * + * @returns {Boolean} + * true if there are any file transfers associated with the + * attached client, false otherise. + */ + $scope.hasTransfers = function hasTransfers() { + + // There are no file transfers if there is no client + if (!$scope.client) + return false; + + return !!($scope.client.uploads.length || $scope.client.downloads.length); + + }; + + /** + * Determines whether the given file transfer state indicates an + * in-progress transfer. + * + * @param {ManagedFileTransferState} transferState + * The file transfer state to check. + * + * @returns {Boolean} + * true if the given file transfer state indicates an in- + * progress transfer, false otherwise. + */ + var isInProgress = function isInProgress(transferState) { + switch (transferState.streamState) { + + // IDLE or OPEN file transfers are active + case ManagedFileTransferState.StreamState.IDLE: + case ManagedFileTransferState.StreamState.OPEN: + return true; + + // All others are not active + default: + return false; + + } + }; + + /** + * Removes all file transfers which are not currently in-progress. + */ + $scope.clearCompletedTransfers = function clearCompletedTransfers() { + + // Nothing to clear if no client attached + if (!$scope.client) + return; + + // Remove completed uploads + $scope.client.uploads = $scope.client.uploads.filter(function isUploadInProgress(upload) { + return isInProgress(upload.transferState); + }); + + // Remove completed downloads + $scope.client.downloads = $scope.client.downloads.filter(function isDownloadInProgress(download) { + return isInProgress(download.transferState); + }); + + }; + + /** + * Begins a file upload through the attached Guacamole client for + * each file in the given FileList. + * + * @param {FileList} files + * The files to upload. + */ + $scope.uploadFiles = function uploadFiles(files) { + + // Ignore file uploads if no attached client + if (!$scope.client) + return; + + // Upload each file + for (var i = 0; i < files.length; i++) + ManagedClient.uploadFile($scope.client, files[i]); + + }; + + }] + + }; +}]); diff --git a/guacamole/src/main/webapp/app/client/styles/transfer-manager.css b/guacamole/src/main/webapp/app/client/styles/transfer-manager.css new file mode 100644 index 000000000..e2b9c5f0d --- /dev/null +++ b/guacamole/src/main/webapp/app/client/styles/transfer-manager.css @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 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. + */ + +.transfer-manager .action-buttons { + text-align: center; +} + +.transfer-manager .no-transfers { + + color: rgba(255, 255, 255, 0.5); + text-shadow: -1px -1px rgba(0, 0, 0, 0.5); + opacity: 0.5; + + font-size: 2em; + font-weight: bolder; + text-align: center; + +} + +.transfer-manager .transfer { + margin: 1em; +} diff --git a/guacamole/src/main/webapp/app/client/styles/transfer.css b/guacamole/src/main/webapp/app/client/styles/transfer.css new file mode 100644 index 000000000..d69df0d4e --- /dev/null +++ b/guacamole/src/main/webapp/app/client/styles/transfer.css @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2014 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. + */ + +.transfer { + position: relative; + padding: 0.5em; + font-size: 0.75em; +} + +.transfer .filename { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + width: 100%; + margin-bottom: 0.5em; +} + +.transfer .text { + position: relative; + text-align: center; + margin-top: 0.5em; +} + +@keyframes transfer-progress { + from {background-position: 0px 0px;} + to {background-position: 64px 0px;} +} + +@-webkit-keyframes transfer-progress { + from {background-position: 0px 0px;} + to {background-position: 64px 0px;} +} + +.transfer .progress { + + width: 100%; + background: #C2C2C2 url('images/progress.png'); + background-size: 16px 16px; + -moz-background-size: 16px 16px; + -webkit-background-size: 16px 16px; + -khtml-background-size: 16px 16px; + + animation-name: transfer-progress; + animation-duration: 2s; + animation-timing-function: linear; + animation-iteration-count: infinite; + + -webkit-animation-name: transfer-progress; + -webkit-animation-duration: 2s; + -webkit-animation-timing-function: linear; + -webkit-animation-iteration-count: infinite; + + padding: 0.25em; + + border: 1px solid gray; + + position: absolute; + top: 0; + left: 0; + bottom: 0; + opacity: 0.25; + +} + +.transfer .progress .bar { + background: #A3D655; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 0; +} diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 8a071ed53..cabe77362 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -60,13 +60,21 @@ {{'CLIENT.ACTION_DISCONNECT' | translate}}
{{'CLIENT.HELP_CLIPBOARD' | translate}}
{{'CLIENT.HELP_MOUSE_MODE' | translate}}
@@ -115,6 +124,7 @@{{'CLIENT.INFO_NO_FILE_TRANSFERS' | translate}}
+ + +