diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js index e13a4cdf5..692051bc1 100644 --- a/guacamole/src/main/webapp/app/client/controllers/clientController.js +++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js @@ -586,6 +586,16 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams return !!$scope.filesystemMenuContents && $scope.menu.shown; }; + // Automatically refresh display when filesystem menu is shown + $scope.$watch('isFilesystemMenuShown()', function refreshFilesystem() { + + // Refresh filesystem, if defined + var filesystem = $scope.filesystemMenuContents; + if (filesystem) + ManagedFilesystem.refresh(filesystem, filesystem.currentDirectory); + + }); + /** * Returns the full path to the given file as an ordered array of parent * directories. diff --git a/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js b/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js index d612dfdfc..dca073a66 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js +++ b/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js @@ -142,22 +142,48 @@ angular.module('client').directive('guacFileBrowser', [function guacFileBrowser( // Create from internal template var element = angular.element($interpolate(fileTemplate)(file)); + // Double-clicking on unknown file types will do nothing + var fileAction = function doNothing() {}; + // Change current directory when directories are clicked if ($scope.isDirectory(file)) { element.addClass('directory'); - element.on('click', function changeDirectory() { + fileAction = function changeDirectory() { $scope.changeDirectory(file); - }); + }; } // Initiate downloads when normal files are clicked else if ($scope.isNormalFile(file)) { element.addClass('normal-file'); - element.on('click', function downloadFile() { + fileAction = function downloadFile() { $scope.downloadFile(file); - }); + }; } + // Mark file as focused upon click + element.on('click', function handleFileClick() { + + // Fire file-specific action if already focused + if (element.hasClass('focused')) { + fileAction(); + element.removeClass('focused'); + } + + // Otherwise mark as focused + else { + element.parent().children().removeClass('focused'); + element.addClass('focused'); + } + + }); + + // Prevent text selection during navigation + element.on('selectstart', function avoidSelect(e) { + e.preventDefault(); + e.stopPropagation(); + }); + return element; }; @@ -222,6 +248,11 @@ angular.module('client').directive('guacFileBrowser', [function guacFileBrowser( }); // end retrieve file template + // Refresh file browser when any upload completes + $scope.$on('guacUploadComplete', function uploadComplete(event, filename) { + ManagedFilesystem.refresh($scope.filesystem, $scope.filesystem.currentDirectory); + }); + }] }; diff --git a/guacamole/src/main/webapp/app/client/styles/file-browser.css b/guacamole/src/main/webapp/app/client/styles/file-browser.css index 73fce34ad..602f4069c 100644 --- a/guacamole/src/main/webapp/app/client/styles/file-browser.css +++ b/guacamole/src/main/webapp/app/client/styles/file-browser.css @@ -29,6 +29,12 @@ .file-browser .list-item .caption { white-space: nowrap; + border: 1px solid transparent; +} + +.file-browser .list-item.focused .caption { + border: 1px dotted rgba(0, 0, 0, 0.5); + background: rgba(204, 221, 170, 0.5); } /* Directory / file icons */ diff --git a/guacamole/src/main/webapp/app/client/styles/file-transfer-dialog.css b/guacamole/src/main/webapp/app/client/styles/file-transfer-dialog.css index 52c00d65c..5f7d594fa 100644 --- a/guacamole/src/main/webapp/app/client/styles/file-transfer-dialog.css +++ b/guacamole/src/main/webapp/app/client/styles/file-transfer-dialog.css @@ -25,6 +25,7 @@ position: absolute; right: 0; bottom: 0; + z-index: 20; font-size: 0.8em; padding: 0.5em; @@ -35,6 +36,6 @@ } #file-transfer-dialog .transfer-manager { - border: 1px solid rgba(0, 0, 0, 0.125); - box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.125); + border: 1px solid rgba(0, 0, 0, 0.5); + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25); } diff --git a/guacamole/src/main/webapp/app/client/templates/guacFileBrowser.html b/guacamole/src/main/webapp/app/client/templates/guacFileBrowser.html index 196a18dcd..2fd57c70d 100644 --- a/guacamole/src/main/webapp/app/client/templates/guacFileBrowser.html +++ b/guacamole/src/main/webapp/app/client/templates/guacFileBrowser.html @@ -21,13 +21,6 @@ THE SOFTWARE. --> - - -
diff --git a/guacamole/src/main/webapp/app/client/types/ManagedFileDownload.js b/guacamole/src/main/webapp/app/client/types/ManagedFileDownload.js index f6c8ffb77..9c9c39f9d 100644 --- a/guacamole/src/main/webapp/app/client/types/ManagedFileDownload.js +++ b/guacamole/src/main/webapp/app/client/types/ManagedFileDownload.js @@ -138,6 +138,9 @@ angular.module('client').factory('ManagedFileDownload', ['$rootScope', '$injecto ManagedFileTransferState.setStreamState(managedFileDownload.transferState, ManagedFileTransferState.StreamState.CLOSED); + // Notify of upload completion + $rootScope.$broadcast('guacDownloadComplete', filename); + }); }; diff --git a/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js b/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js index 6cd51bba9..15839a7a5 100644 --- a/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js +++ b/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js @@ -211,6 +211,9 @@ angular.module('client').factory('ManagedFileUpload', ['$rootScope', '$injector' ManagedFileTransferState.setStreamState(managedFileUpload.transferState, ManagedFileTransferState.StreamState.CLOSED); + // Notify of upload completion + $rootScope.$broadcast('guacUploadComplete', file.name); + } // Otherwise, update progress