diff --git a/demo_app/CHANGELOG.MD b/demo_app/CHANGELOG.MD index f107bca..b710b92 100644 --- a/demo_app/CHANGELOG.MD +++ b/demo_app/CHANGELOG.MD @@ -1,5 +1,20 @@ # MaidSafe Demo App Change Log +##[0.5.1] +- Close application on authorisation failure + +##[0.5.0] +- New UI workflow integration + - Separation of website and network data management +- Ability to cancel uploads +- Show file count status while uploading folders +- Open the download folder instead of opening the downloaded file +- Initial root folder creation failure recovery +- Show initial authorisation stages on loading +- Ability to remap service home directory +- Option to delete a service +- various bug fixes and UX updates + ##[0.4.0] - File size limit increased to 50 MB - Compatibility with safe launcher v0.6.0 diff --git a/demo_app/app/images/add.svg b/demo_app/app/images/add.svg old mode 100644 new mode 100755 index 27c985f..f2e5090 --- a/demo_app/app/images/add.svg +++ b/demo_app/app/images/add.svg @@ -1,9 +1,15 @@ - - - - - - + + + + + + + + + + + diff --git a/demo_app/app/images/copy.svg b/demo_app/app/images/copy.svg new file mode 100755 index 0000000..bc3dd82 --- /dev/null +++ b/demo_app/app/images/copy.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/demo_app/app/images/cut.svg b/demo_app/app/images/cut.svg new file mode 100755 index 0000000..b45534f --- /dev/null +++ b/demo_app/app/images/cut.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + diff --git a/demo_app/app/images/delete.svg b/demo_app/app/images/delete.svg old mode 100644 new mode 100755 index d12d47d..5e9a314 --- a/demo_app/app/images/delete.svg +++ b/demo_app/app/images/delete.svg @@ -1,15 +1,16 @@ - - - - - - - - - - - - + + + + + + + + + + + diff --git a/demo_app/app/images/paste.svg b/demo_app/app/images/paste.svg new file mode 100755 index 0000000..b2e86bd --- /dev/null +++ b/demo_app/app/images/paste.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/demo_app/app/images/rename.svg b/demo_app/app/images/rename.svg index 8562dbd..1491b94 100644 --- a/demo_app/app/images/rename.svg +++ b/demo_app/app/images/rename.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - - + + + + + + + + + + diff --git a/demo_app/app/images/tick_white.svg b/demo_app/app/images/tick_white.svg new file mode 100644 index 0000000..e41d39d --- /dev/null +++ b/demo_app/app/images/tick_white.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo_app/app/package.json b/demo_app/app/package.json index 9710c80..bea0083 100644 --- a/demo_app/app/package.json +++ b/demo_app/app/package.json @@ -1,9 +1,9 @@ { "name": "maidsafe-demo-app", - "productName": "MaidSafe Demo App", + "productName": "Launcher Demo App", "identifier": "com.maidsafe.demo_app", "description": "MaidSafe Demo Application", - "version": "0.4.0", + "version": "0.5.1", "author": "MaidSafe", "copyright": "", "main": "background.js", diff --git a/demo_app/app/scripts/constants.js b/demo_app/app/scripts/constants.js index 4563d2e..4c58161 100644 --- a/demo_app/app/scripts/constants.js +++ b/demo_app/app/scripts/constants.js @@ -12,3 +12,10 @@ window.maidsafeDemo.constant('MESSAGES', { 'CREATE_PUBLIC_ID': 'Creating Public ID', 'PREPARING_TEMPLATE': 'Preparing Template' }); + +window.maidsafeDemo.constant('CONSTANT', { + ROOT_PATH: { + APP: 'app', + DRIVE: 'drive' + } +}); diff --git a/demo_app/app/scripts/controllers/authorise_controller.js b/demo_app/app/scripts/controllers/authorise_controller.js index d90edc0..6e231ab 100644 --- a/demo_app/app/scripts/controllers/authorise_controller.js +++ b/demo_app/app/scripts/controllers/authorise_controller.js @@ -98,6 +98,10 @@ window.maidsafeDemo.controller('AuthoriseCtrl', [ '$scope', '$rootScope', '$stat var authoriseCb = function(err, res) { if (err) { console.error(err); + $rootScope.$loader.hide(); + $rootScope.prompt.show('Authorisation failed', 'Failed to authorise with launcher.', function() { + window.uiUtils.closeApp(); + }); return; } $scope.authorisationTasks.currentState = $scope.authorisationTasks.state.INITIALISING; diff --git a/demo_app/app/scripts/directives/explorer.js b/demo_app/app/scripts/directives/explorer.js index 4d5b003..a0454ba 100644 --- a/demo_app/app/scripts/directives/explorer.js +++ b/demo_app/app/scripts/directives/explorer.js @@ -27,25 +27,123 @@ window.maidsafeDemo.directive('explorer', [ '$rootScope', '$state', '$timeout', to you, it is therefore well suited for data which you wish to remain confidential.' }, ]; - + var MANIPULATE_ACTION = { + MOVE: 'move', + COPY: 'copy' + }; $scope.currentDirectory = '/' + ($scope.startingPath ? ($scope.startingPath + '/') : ''); $scope.mime = require('mime'); $scope.selectedPath = null; $scope.dir = null; $scope.isFileSelected = null; $scope.listSelected = false; + $scope.selectedEle = null; + $scope.currentManipulateAction = null; + $scope.currentManipulatePath = null; + $scope.currentManipulateSelectedIsFile = null; + + var selection = function(target, name, isFile) { + var reset = function() { + $('.ms-list-2-i').removeClass('active'); + if (target.className.split(' ').indexOf('edit') === -1) { + resetRename(); + } + }; + reset(); + var ele = angular.element(target); + $scope.selectedEle = ele; + $scope.listSelected = true; + ele.addClass('active'); + $scope.isFileSelected = isFile; + $scope.selectedPath = name; + $scope.$applyAsync(); + if (isFile || !$scope.onDirectorySelected) { + return; + } + $scope.onDirectorySelected({ + name: $scope.currentDirectory + $scope.selectedPath + '/' + }); + }; + + var resetRename = function() { + var listItems = $('.ms-list-2-i'); + var renameField = $('.ms-list-2-i .rename input[name=rename]'); + renameField.val(function() { + return this.dataset['originalVal']; + }); + listItems.removeClass('edit cut'); + }; + + var resetPaste = function() { + $scope.currentManipulateAction = null; + $scope.currentManipulatePath = null; + $scope.currentManipulateSelectedIsFile = null; + }; + + var resetSelection = function() { + $scope.listSelected = false; + }; + + var showContextMenu = function(e) { + var contextMenu = $('#ContextMenu'); + var listItems = $('.ms-list-2-i'); + var list = $('.ms-list-2'); + var targetList = null; + resetSelection(); + if ($(e.target).is(listItems)) { + targetList = e.target; + } + if ($(e.target.parentElement).is(listItems)) { + targetList = e.target.parentElement; + } + if ($(e.target).is(list)) { + targetList = e.target; + } + if (!targetList) { + return; + } + var targetName = targetList.dataset['name']; + var targetIsFile = targetList.dataset['isFile'] ? JSON.parse(targetList.dataset['isFile']) : false; + if (targetName) { + selection(targetList, targetName, targetIsFile); + } + var posX = e.clientX; + var posY = e.clientY; + contextMenu.show(); + contextMenu.css('top', posY); + contextMenu.css('left', posX); + $scope.$applyAsync(); + }; + + var hideContextMenu = function() { + var contextMenu = $('#ContextMenu'); + if ($scope.selectedEle) { + $scope.selectedEle.removeClass('active'); + } + contextMenu.hide(); + contextMenu.css('top', 0); + contextMenu.css('left', 0); + }; var releaseSelection = function() { $(document).on('mouseup', function(e) { var listItems = $('.ms-list-2-i'); var explorer = $('.ms-explr'); - if (!listItems.is(e.target) && (listItems.has(e.target).length === 0) && (explorer.has(e.target).length !== 0)) { + var contextMenu = $('#ContextMenu'); + + // show context menu + if(e.button === 2) { + return showContextMenu(e); + } + hideContextMenu(); + if (!listItems.is(e.target) && (listItems.has(e.target).length === 0) && (explorer.has(e.target).length !== 0) && (contextMenu.has(e.target).length === 0)) { if ($scope.listSelected) { $scope.onDirectorySelected({ name: null }); - $scope.listSelected = false; + resetSelection(); } + resetRename(); listItems.removeClass('active'); } var dropdown = $('.ms-dropdown .ms-dropdown-b'); @@ -189,14 +287,28 @@ window.maidsafeDemo.directive('explorer', [ '$rootScope', '$state', '$timeout', }); }; - $scope.rename = function(newName) { + $scope.renameTarget = function(e) { + var renameEle = e.currentTarget.previousElementSibling; + if (renameEle.nodeName !== 'INPUT') { + return; + } + var newName = renameEle.value; + if (!newName) { + return; + } var callback = function(err) { + $rootScope.$loader.hide(); if (err) { - alert('Rename failed'); + $rootScope.prompt.show('MaidSafe Demo', 'Rename failed', function() {}, + { + title: 'Reason', + ctx: err + }); } getDirectory(); }; - var oldPath = $scope.currentDirectory + $scope.selected; + var oldPath = $scope.currentDirectory + '/' + $scope.selectedPath; + $rootScope.$loader.show(); if ($scope.isFileSelected) { safeApi.renameFile(oldPath, false, newName, callback); } else { @@ -204,7 +316,10 @@ window.maidsafeDemo.directive('explorer', [ '$rootScope', '$state', '$timeout', } }; - $scope.download = function(fileName, size) { + $scope.download = function(e, fileName, size) { + if ($(e.target).is($('.ms-list-2-i .rename input[name=rename]'))) { + return; + } $scope.listSelected = false; $scope.isFileSelected = true; $scope.selectedPath = fileName; @@ -235,7 +350,8 @@ window.maidsafeDemo.directive('explorer', [ '$rootScope', '$state', '$timeout', downloader.download(); }; - $scope.delete = function() { + $scope.deleteAction = function() { + resetPaste(); var path = $scope.currentDirectory + '/' + $scope.selectedPath; $rootScope.$loader.show(); var onDelete = function(err) { @@ -256,32 +372,92 @@ window.maidsafeDemo.directive('explorer', [ '$rootScope', '$state', '$timeout', } }; - $scope.openDirectory = function(directoryName) { - if ($scope.listMode) { + $scope.openDirectory = function(e, directoryName) { + if ($scope.listMode || ($(e.target).is($('.ms-list-2-i .rename input[name=rename]')))) { return; } $scope.listSelected = false; $scope.selectedPath = directoryName; - $scope.currentDirectory += ($scope.selectedPath + '/'); + var selectedDir = $scope.currentDirectory + $scope.selectedPath; + if (($scope.currentManipulatePath === selectedDir) && $scope.currentManipulateAction === MANIPULATE_ACTION.MOVE) { + resetPaste(); + return; + } + $scope.currentDirectory = selectedDir + '/'; + $scope.selectedPath = ''; getDirectory(); }; $scope.select = function($event, name, isFile) { + selection($event.currentTarget, name, isFile); + }; + + $scope.showRenameField = function() { + $scope.selectedEle.addClass('active edit'); + $scope.selectedEle.children('.rename').find('input').select(); + }; + + $scope.cutAction = function() { + $scope.currentManipulateAction = MANIPULATE_ACTION.MOVE; + $scope.currentManipulatePath = $scope.currentDirectory + $scope.selectedPath; + $scope.currentManipulateSelectedIsFile = $scope.isFileSelected; + if ($scope.selectedEle) { + $scope.selectedEle.addClass('cut'); + } + }; + + $scope.copyAction = function() { + $scope.currentManipulateAction = MANIPULATE_ACTION.COPY; + $scope.currentManipulatePath = $scope.currentDirectory + $scope.selectedPath; + $scope.currentManipulateSelectedIsFile = $scope.isFileSelected; + }; + + $scope.pasteAction = function() { var reset = function() { - $('.ms-list-2-i').removeClass('active'); + $scope.currentManipulatePath = null; + $scope.currentManipulateAction = null; }; - reset(); - var ele = angular.element($event.currentTarget); - $scope.listSelected = true; - ele.addClass('active'); - $scope.isFileSelected = isFile; - $scope.selectedPath = name; - if (isFile || !$scope.onDirectorySelected) { - return; + + var moveCallback = function(err, res) { + $rootScope.$loader.hide(); + if (err) { + console.error(err) + $rootScope.prompt.show('MaidSafe Demo', 'Move failed', function() {}, { + title: 'Reason', + ctx: err.data.description + }); + } + reset(); + getDirectory(); + }; + + var copyCallback = function(err, res) { + $rootScope.$loader.hide(); + if (err) { + console.error(err) + $rootScope.prompt.show('MaidSafe Demo', 'Copy failed', function() {}, { + title: 'Reason', + ctx: err.data.description + }); + } + reset(); + getDirectory(); + }; + $rootScope.$loader.show(); + var selectedPath = $scope.selectedPath ? ($scope.currentDirectory + $scope.selectedPath + '/') : $scope.currentDirectory; + if ($scope.currentManipulateSelectedIsFile) { + if ($scope.currentManipulateAction === MANIPULATE_ACTION.MOVE) { + safeApi.moveFile($scope.currentManipulatePath, false, selectedPath, false, moveCallback); + } else { + safeApi.copyFile($scope.currentManipulatePath, false, selectedPath, false, moveCallback); + } + } else { + if ($scope.currentManipulateAction === MANIPULATE_ACTION.MOVE) { + safeApi.moveDirectory($scope.currentManipulatePath, false, selectedPath, false, copyCallback); + } else { + safeApi.copyDirectory($scope.currentManipulatePath, false, selectedPath, false, copyCallback); + } } - $scope.onDirectorySelected({ - name: $scope.currentDirectory + $scope.selectedPath + '/' - }); }; $scope.back = function() { diff --git a/demo_app/app/scripts/factories/dns_factory.js b/demo_app/app/scripts/factories/dns_factory.js index 1159546..a1b84d0 100644 --- a/demo_app/app/scripts/factories/dns_factory.js +++ b/demo_app/app/scripts/factories/dns_factory.js @@ -1,10 +1,9 @@ /** * DNS factory */ -window.maidsafeDemo.factory('dnsFactory', [ function(Shared) { +window.maidsafeDemo.factory('dnsFactory', [ 'CONSTANT', function(CONSTANT) { 'use strict'; var self = this; - self.createPublicId = function(longName, callback) { var payload = { url: this.SERVER + 'dns/' + longName, @@ -42,6 +41,7 @@ window.maidsafeDemo.factory('dnsFactory', [ function(Shared) { // add service self.addService = function(longName, serviceName, isPathShared, serviceHomeDirPath, callback) { + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; var payload = { url: this.SERVER + 'dns', method: 'PUT', @@ -51,8 +51,8 @@ window.maidsafeDemo.factory('dnsFactory', [ function(Shared) { data: { longName: longName, serviceName: serviceName, - isPathShared: isPathShared, - serviceHomeDirPath: serviceHomeDirPath + serviceHomeDirPath: serviceHomeDirPath, + rootPath: rootPath } }; (new this.Request(payload, callback)).send(); diff --git a/demo_app/app/scripts/factories/nfs_factory.js b/demo_app/app/scripts/factories/nfs_factory.js index f856e0f..08fef85 100644 --- a/demo_app/app/scripts/factories/nfs_factory.js +++ b/demo_app/app/scripts/factories/nfs_factory.js @@ -1,20 +1,16 @@ /** * Nfs factory */ -window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { +window.maidsafeDemo.factory('nfsFactory', [ 'CONSTANT', function(CONSTANT) { 'use strict'; var self = this; var mime = require('mime'); - var ROOT_PATH = { - APP: 'app', - DRIVE: 'drive' - }; var fs = require('fs'); var request = require('request'); // create new directory self.createDir = function(dirPath, isPrivate, userMetadata, isPathShared, callback) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + var rootPath = isPathShared ? CONSTANT.CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; dirPath = dirPath[0] === '/' ? dirPath.slice(1) : dirPath; var payload = { url: this.SERVER + 'nfs/directory/' + rootPath + '/' + dirPath, @@ -32,7 +28,7 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { // get specific directory self.getDir = function(callback, dirPath, isPathShared) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; var URL = this.SERVER + 'nfs/directory/' + rootPath + '/' + dirPath; var payload = { url: URL, @@ -45,7 +41,7 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { }; self.deleteDirectory = function(dirPath, isPathShared, callback) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; var url = this.SERVER + 'nfs/directory/' + rootPath + '/' + dirPath; var payload = { url: url, @@ -58,7 +54,7 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { }; self.deleteFile = function(filePath, isPathShared, callback) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; var payload = { url: this.SERVER + 'nfs/file/' + rootPath + '/' + filePath, method: 'DELETE', @@ -70,7 +66,7 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { }; self.createFile = function(filePath, metadata, isPathShared, localPath, callback) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; var url = this.SERVER + 'nfs/file/' + rootPath + '/' + filePath; var factor = 0; @@ -103,13 +99,13 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { callback({data: errMsg}); }); fileStream.pipe(writeStream); - return writeStream; + return writeStream; }; // self.modifyFileContent = function(filePath, isPathShared, localPath, offset, callback) { // offset = offset || 0; // var self = this; - // var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + // var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; // var url = this.SERVER + 'nfs/file/' + rootPath + '/' + filePath; // // TODO this factor usage is just a patch - must use a better implementation for progress bar handling // var factor = 0; @@ -136,7 +132,7 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { // }; self.getFile = function(filePath, isPathShared, downloadPath, callback) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; var url = this.SERVER + 'nfs/file/' + rootPath + '/' + filePath; var headers = { auth: { @@ -155,28 +151,66 @@ window.maidsafeDemo.factory('nfsFactory', [ function(Shared) { .pipe(fs.createWriteStream(downloadPath)); }; - var rename = function(path, isPathShared, newName, isFile, callback) { - var rootPath = isPathShared ? ROOT_PATH.DRIVE : ROOT_PATH.APP; - var url = this.SERVER + (isFile ? 'nfs/file/metadata/' : 'nfs/directory/') + rootPath + '/' + path; + self.rename = function(self, path, isPathShared, newName, isFile, callback) { + var rootPath = isPathShared ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; + var url = self.SERVER + (isFile ? 'nfs/file/metadata/' : 'nfs/directory/') + rootPath + '/' + path; var payload = { url: url, method: 'PUT', headers: { - authorization: 'Bearer ' + this.getAuthToken() + authorization: 'Bearer ' + self.getAuthToken() }, data: { name: newName } }; - (new this.Request(payload, callback)).send(); + (new self.Request(payload, callback)).send(); }; self.renameDirectory = function(dirPath, isPathShared, newName, callback) { - rename(dirPath, isPathShared, newName, false, callback); + self.rename(this, dirPath, isPathShared, newName, false, callback); }; self.renameFile = function(oldPath, isPathShared, newPath, callback) { - rename(dirPath, isPathShared, newName, true, callback); + self.rename(this, oldPath, isPathShared, newPath, true, callback); + }; + + self.moveOrCopy = function(self, srcPath, srcRootPath, destPath, destRootPath, isFile, toMove, callback) { + srcRootPath = srcRootPath ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; + destRootPath = destRootPath ? CONSTANT.ROOT_PATH.DRIVE : CONSTANT.ROOT_PATH.APP; + var url = self.SERVER + (isFile ? 'nfs/movefile/' : 'nfs/movedir/'); + var payload = { + url: url, + method: 'POST', + headers: { + authorization: 'Bearer ' + self.getAuthToken() + }, + data: { + srcPath: srcPath, + destPath: destPath, + srcRootPath: srcRootPath, + destRootPath: destRootPath, + action: (toMove ? 'MOVE' : 'COPY') + } + }; + (new self.Request(payload, callback)).send(); + }; + + self.moveDirectory = function(srcPath, srcRootPath, destPath, destRootPath, callback) { + self.moveOrCopy(this, srcPath, srcRootPath, destPath, destRootPath, false, true, callback); + }; + + self.moveFile = function(srcPath, srcRootPath, destPath, destRootPath, callback) { + self.moveOrCopy(this, srcPath, srcRootPath, destPath, destRootPath, true, true, callback); }; + + self.copyDirectory = function(srcPath, srcRootPath, destPath, destRootPath, callback) { + self.moveOrCopy(this, srcPath, srcRootPath, destPath, destRootPath, false, false, callback); + }; + + self.copyFile = function(srcPath, srcRootPath, destPath, destRootPath, callback) { + self.moveOrCopy(this, srcPath, srcRootPath, destPath, destRootPath, true, false, callback); + }; + return self; } ]); diff --git a/demo_app/app/stylesheets/buttons.less b/demo_app/app/stylesheets/buttons.less index e14e82d..8fed011 100644 --- a/demo_app/app/stylesheets/buttons.less +++ b/demo_app/app/stylesheets/buttons.less @@ -58,21 +58,45 @@ .ms-rename-btn { background-image: url('../images/rename.svg'); - background-size: 42px; + background-size: 18px; background-position: center; background-repeat: no-repeat; } .ms-add-btn { background-image: url('../images/add.svg'); - background-size: 42px; + background-size: 18px; background-position: center; background-repeat: no-repeat; } .ms-delete-btn { background-image: url('../images/delete.svg'); - background-size: 42px; + background-size: 18px; + background-position: center; + background-repeat: no-repeat; +} +.ms-paste-btn { + background-image: url('../images/paste.svg'); + background-size: 18px; + background-position: center; + background-repeat: no-repeat; +} +.ms-cut-btn { + background-image: url('../images/cut.svg'); + background-size: 18px; + background-position: center; + background-repeat: no-repeat; +} +.ms-copy-btn { + background-image: url('../images/copy.svg'); + background-size: 18px; + background-position: center; + background-repeat: no-repeat; +} +.ms-tick-btn { + background-image: url('../images/tick_white.svg'); + background-size: 14px; background-position: center; background-repeat: no-repeat; } diff --git a/demo_app/app/stylesheets/components.less b/demo_app/app/stylesheets/components.less index 9d9cabb..3b8b96a 100644 --- a/demo_app/app/stylesheets/components.less +++ b/demo_app/app/stylesheets/components.less @@ -184,6 +184,9 @@ li { padding: 8px 16px; cursor: pointer; + &:hover { + background-color: @gray-450; + } } } } diff --git a/demo_app/app/stylesheets/explorer.less b/demo_app/app/stylesheets/explorer.less index e5d36d9..173c48b 100644 --- a/demo_app/app/stylesheets/explorer.less +++ b/demo_app/app/stylesheets/explorer.less @@ -4,22 +4,41 @@ padding-top: 20px; .ms-explr-h { display: flex; - background-color: @blue-200; - padding: 3px 0; + background-color: @exp-light; .ms-explr-h-lt, .ms-explr-h-rt { display: inline-block; float: left; - button { + .dark { + display: inline-block; + float: right; + background-color: @exp-dark; + } + .ms-btn { width: 40px; - height: 30px; + height: 36px; float: left; background-color: transparent; color: white; padding: 0 8px; display: inline-block; + &:hover { + opacity: 0.3; + } + &:active { + background-color: @exp-light-active; + } + &.dark { + &:active { + background-color: @exp-dark-active; + } + } &:disabled { - opacity: 0.5; + opacity: 0.2; cursor: not-allowed; + background-color: @exp-light !important; + &.dark { + background-color: @exp-dark !important; + } } } } @@ -27,6 +46,7 @@ flex: 1; display: inline-block; float: left; + padding: 3px 0; input { width: 100%; height: 30px; @@ -43,7 +63,40 @@ height: 250px; overflow: auto; background-color: white; - box-shadow: 0 0 1px @gray-500; + box-shadow: 0 0 1px @gray-500; + position: relative; + } + .context-menu { + width: 120px; + display: none; + position: fixed; + top: 0; + left: 0; + background-color: #FFFFFF; + border-radius: 3px; + border: 1px solid #EEE; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); + ul { + padding: 0; + margin: 0; + list-style-type: none; + li { + button { + width: 100%; + text-align: left; + padding: 8px 16px; + background-color: transparent; + border: 0; + margin: 0; + outline: 0; + font-size: inherit; + cursor: pointer; + } + &:hover { + background-color: @gray-450; + } + } + } } } @@ -60,6 +113,7 @@ padding: 24px; display: flex; position: relative; + border: 0; &:before { content: ''; width: 94%; diff --git a/demo_app/app/stylesheets/list.less b/demo_app/app/stylesheets/list.less index 8b6a2d4..feb2f2e 100644 --- a/demo_app/app/stylesheets/list.less +++ b/demo_app/app/stylesheets/list.less @@ -125,12 +125,15 @@ } } .ms-list-2-i { + border-width: 2px; + border-color: transparent; + border-style: solid; cursor: pointer; - &.active { - background-color: @blue-100; - } &:hover { - background-color: @blue-100; + background-color: @exp-hover; + } + &.active { + background-color: @exp-highlight; } > .ms-list-2-i-ctx { display: inline-block; @@ -143,12 +146,48 @@ overflow: hidden; text-overflow: ellipsis; } + &.edit { + > .name { + display: none; + } + > .rename { + display: block; + } + } + &.cut { + border-style: dashed; + border-color: @exp-light; + } > .icn { width: 5%; } > .name { width: 40%; } + > .rename { + width: 40%; + position: relative; + display: none; + input { + width: 100%; + padding: 0 30px 0 8px; + font-size: 16px; + line-height: 29px; + border: 0; + outline: 0; + } + button { + position: absolute; + width: 30px; + height: 29px; + top: 3px; + right: 8px; + border: 0; + background-color: @blue-300; + color: #FFF; + outline: 0; + } + } > .date { width: 15%; } diff --git a/demo_app/app/stylesheets/variables.less b/demo_app/app/stylesheets/variables.less index 8ad1334..485275c 100644 --- a/demo_app/app/stylesheets/variables.less +++ b/demo_app/app/stylesheets/variables.less @@ -4,6 +4,7 @@ @gray-200: #f7f7f7; @gray-300: #eeeeee; @gray-400: #ececec; +@gray-450: #ebebeb; @gray-500: #a6a6a6; @gray-600: #b2b2b2; @gray-700: #858585; @@ -22,3 +23,13 @@ @btn-default: #D7D3DD; @btn-hover: #78A1BF; @btn-active: #3D6280; + +// explorer +@exp-dark: #606C77; +@exp-dark-hover: #6C7785; +@exp-dark-active: #57606B; +@exp-light: #788694; +@exp-light-hover: #8595A3; +@exp-light-active: #6E7B87; +@exp-hover: #EBEFF5; +@exp-highlight: #CAD5E0; diff --git a/demo_app/app/views/explorer.html b/demo_app/app/views/explorer.html index 7c90303..35fbcb5 100644 --- a/demo_app/app/views/explorer.html +++ b/demo_app/app/views/explorer.html @@ -9,7 +9,7 @@
-
- - +
+ + + + +
+ ng-click="select($event, dir.name, false);openDirectory($event, dir.name)">
@@ -49,19 +58,24 @@

{{ dir.displayName }}

Size
Date
-
+
 
{{ dir.name }}
+
+ + +
 
 
{{ dir.createdOn | date : 'dd-MM-yy HH:mm' }}
-
+
 
-
{{ file.name }}
- +
{{ file.name }}
+
+ + +
{{ mime.lookup(file.name) }}
{{ bytesToSize(file.size) }}
{{ file.createdOn | date : 'dd-MM-yy HH:mm' }}
@@ -71,5 +85,14 @@

{{ dir.displayName }}

-->
+
+
    +
  • +
  • +
  • +
  • +
  • +
+