diff --git a/src/components/filetree.html b/src/components/filetree.html index 5550464c1..321fc1bd0 100644 --- a/src/components/filetree.html +++ b/src/components/filetree.html @@ -214,7 +214,7 @@ {{ 'filemanager.list.empty' | tr }} - + @@ -222,7 +222,7 @@ {{ entry.uid | prettyOwner }} {{ entry.size | prettyByteSize }} {{ entry.mtime | prettyDate }} - + diff --git a/src/components/filetree.js b/src/components/filetree.js index fa553fbd7..44c393456 100644 --- a/src/components/filetree.js +++ b/src/components/filetree.js @@ -6,7 +6,8 @@ angular.module('Application').component('filetree', { bindings: { backendId: '<', - backendType: '<' + backendType: '<', + view: '<' }, templateUrl: 'components/filetree.html?<%= revision %>', controller: [ '$scope', '$translate', '$timeout', 'Client', FileTreeController ] @@ -15,6 +16,7 @@ angular.module('Application').component('filetree', { function FileTreeController($scope, $translate, $timeout, Client) { $scope.backendId = this.backendId; $scope.backendType = this.backendType; + $scope.view = this.view; $scope.busy = true; $scope.client = Client; @@ -26,7 +28,6 @@ function FileTreeController($scope, $translate, $timeout, Client) { $scope.clipboard = []; // holds cut or copied entries $scope.clipboardCut = false; // if action is cut or copy $scope.dropToBody = false; - $scope.view = 'fileTree'; $scope.applicationLink = ''; $scope.owners = [ @@ -968,4 +969,19 @@ function FileTreeController($scope, $translate, $timeout, Client) { } openPath('.'); + + // handle save shortcuts + window.addEventListener('keydown', function (event) { + if ($scope.$parent.activeView !== $scope.view || $scope.$parent.viewerOpen) return; + + if (event.key === 'ArrowDown') { + $scope.$apply(selectNext); + } else if (event.key === 'ArrowUp') { + $scope.$apply(selectPrev); + } else if (event.key === 'Enter') { + $scope.$apply(openSelected); + } else if (event.key === 'Backspace') { + if ($scope.view === 'fileTree') $scope.goDirectoryUp(); + } + }); } diff --git a/src/filemanager.html b/src/filemanager.html index 8aecd3ab1..fb2f29200 100644 --- a/src/filemanager.html +++ b/src/filemanager.html @@ -144,20 +144,20 @@
  • {{ volume.name }}
  • - +
    - - - - + + + +
    - -
    - + + +
    diff --git a/src/js/filemanager.js b/src/js/filemanager.js index e7acb9057..3be90e081 100644 --- a/src/js/filemanager.js +++ b/src/js/filemanager.js @@ -74,22 +74,35 @@ function isModalVisible() { return !!document.getElementsByClassName('modal in').length; } +var VIEW = { + LEFT: 'left', + RIGHT: 'right' +}; + app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Client', function ($scope, $translate, $timeout, Client) { var search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.split('='); }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {}); + $scope.VIEW = VIEW; + $scope.initialized = false; $scope.status = null; $scope.client = Client; $scope.title = ''; - $scope.id = search.id; - $scope.type = search.type; - - // move to this instead of above $scope.backendId = search.id; $scope.backendType = search.type; - $scope.volumes = []; $scope.splitView = false; + $scope.activeView = VIEW.LEFT; + $scope.viewerOpen = false; + + $scope.toggleSplitView = function () { + $scope.splitView = !$scope.splitView; + if (!$scope.splitView) $scope.activeView = VIEW.LEFT; + }; + + $scope.setActiveView = function (view) { + $scope.activeView = view; + }; // for monaco editor var LANGUAGES = []; @@ -124,13 +137,13 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl // clear model if any if ($scope.textEditor.editor && $scope.textEditor.editor.getModel()) $scope.textEditor.editor.setModel(null); - $scope.view = 'textEditor'; + $scope.viewerOpen = true; // document.getElementById('textEditorModal').style['display'] = 'flex'; var filePath = sanitize($scope.textEditor.cwd + '/' + entry.fileName); var language = getLanguage(entry.fileName); - Client.filesGet($scope.id, $scope.type, filePath, 'data', function (error, result) { + Client.filesGet($scope.backendId, $scope.backendType, filePath, 'data', function (error, result) { if (error) return Client.error(error); if (!$scope.textEditor.editor) { @@ -156,7 +169,7 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl var filePath = sanitize($scope.textEditor.cwd + '/' + $scope.textEditor.entry.fileName); var file = new File([newContent], 'file'); - Client.filesUpload($scope.id, $scope.type, filePath, file, true, function () {}, function (error) { + Client.filesUpload($scope.backendId, $scope.backendType, filePath, file, true, function () {}, function (error) { if (error) return Client.error(error); // update size immediately for the list view to avoid reloading the whole list @@ -172,11 +185,13 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl close: function () { $scope.textEditor.visible = false; + $scope.viewerOpen = false; $('#textEditorCloseModal').modal('hide'); }, onClose: function () { $scope.textEditor.visible = false; + $scope.viewerOpen = false; $('#textEditorCloseModal').modal('hide'); }, @@ -236,11 +251,11 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl if (error) return Client.initError(error, init); var getter; - if ($scope.type === 'app') { - getter = Client.getApp.bind(Client, $scope.id); - } else if ($scope.type === 'volume') { - getter = Client.getVolume.bind(Client, $scope.id); - } else if ($scope.type === 'mail') { + if ($scope.backendType === 'app') { + getter = Client.getApp.bind(Client, $scope.backendId); + } else if ($scope.backendType === 'volume') { + getter = Client.getVolume.bind(Client, $scope.backendId); + } else if ($scope.backendType === 'mail') { getter = function (next) { next(null, null); }; } @@ -251,9 +266,9 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl } // fine to do async - if ($scope.type === 'app') fetchVolumesInfo(result.mounts || []); + if ($scope.backendType === 'app') fetchVolumesInfo(result.mounts || []); - switch ($scope.type) { + switch ($scope.backendType) { case 'app': $scope.title = result.label || result.fqdn; $scope.rootDirLabel = '/app/data/'; @@ -286,15 +301,7 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl // handle save shortcuts window.addEventListener('keydown', function (event) { - if (event.key === 'ArrowDown') { - $scope.$apply(selectNext); - } else if (event.key === 'ArrowUp') { - $scope.$apply(selectPrev); - // } else if (event.key === 'Enter') { - // $scope.$apply(openSelected); - // } else if (event.key === 'Backspace') { - // if ($scope.view === 'fileTree') $scope.goDirectoryUp(); - } else if((navigator.platform.match('Mac') ? event.metaKey : event.ctrlKey) && event.key === 's') { + if((navigator.platform.match('Mac') ? event.metaKey : event.ctrlKey) && event.key === 's') { if ($scope.view !== 'textEditor') return; event.preventDefault(); diff --git a/src/theme.scss b/src/theme.scss index f17cd2111..7d87cb384 100644 --- a/src/theme.scss +++ b/src/theme.scss @@ -1837,17 +1837,21 @@ tag-input { .file-trees { display: flex; - } - - .spacer { - width: 2px; - background-color: #d3d3d3; - margin: 0 10px; + overflow: hidden; } filetree { - // flex-basis: 50%; width: 100%; + + &.two-pane { + width: 50%; + + &:first-of-type { + margin-right: 5px; + padding-right: 5px; + border-right: 1px solid #d3d3d3; + } + } } .toolbar { @@ -1918,12 +1922,13 @@ tag-input { .table td { vertical-align: middle; + padding: 0; } } .file-list-header { th { - padding: 2px 8px; + padding: 0; } } @@ -1932,11 +1937,13 @@ tag-input { } .context-menu-action { - display: none; + display: inline-block; + visibility: hidden; } tr:hover .context-menu-action { - display: inline-block; + // display: inline-block; + visibility: visible; } tr.entry-selected .context-menu-action {