Browse Source

support drag file to create new task

MaysWind 6 years ago
parent
commit
a237fbee56

+ 17 - 0
app.js

@@ -11,6 +11,7 @@ const cmd = require('./cmd');
 const tray = require('./tray');
 
 const app = electron.app;
+const ipcMain = electron.ipcMain;
 const BrowserWindow = electron.BrowserWindow;
 
 const singletonLock = app.requestSingleInstanceLock();
@@ -160,4 +161,20 @@ app.on('ready', () => {
 
         core.mainWindow = null;
     });
+
+    ipcMain.on('new-drop-file', (event, arg) => {
+        if (!arg) {
+            return;
+        }
+
+        let filePath = arg.filePath;
+        let location = arg.location;
+
+        if (location.indexOf('/new') === 0) {
+            cmd.newTaskFromFile(filePath);
+        } else {
+            cmd.asyncNewTaskFromFile(filePath);
+            cmd.navigateToNewTask();
+        }
+    });
 });

+ 12 - 0
app/index.html

@@ -20,6 +20,7 @@
     <link rel="stylesheet" href="../node_modules/angularjs-dragula/dist/dragula.min.css"/>
     <link rel="stylesheet" href="styles/core/core.css">
     <link rel="stylesheet" href="styles/core/extend.css">
+    <link rel="stylesheet" href="styles/core/native-core.css">
     <link rel="stylesheet" href="styles/core/app-title.css">
     <link rel="stylesheet" href="styles/controls/global-status.css"/>
     <link rel="stylesheet" href="styles/controls/task-table.css"/>
@@ -32,6 +33,17 @@
     <link rel="stylesheet" href="styles/theme/default-app-title.css">
 </head>
 <body class="hold-transition skin-aria-ng sidebar-mini fixed ng-cloak" ng-class="{'custom-app-title': useCustomAppTitle}">
+<div id="dropzone" class="dropzone">
+    <div id="dropzone-filezone" class="dropzone-filezone"></div>
+    <div class="dropzone-tip-container">
+        <div class="dropzone-tip-wrapper">
+            <div class="dropzone-tip">
+                <i class="fa fa-file-o"></i>
+                <h3 translate>Create New Task</h3>
+            </div>
+        </div>
+    </div>
+</div>
 <div class="wrapper" ng-controller="MainController" ng-swipe-left="swipeActions.leftSwipe()" ng-swipe-right="swipeActions.rightSwipe()" ng-swipe-disable-mouse>
     <header class="main-header">
         <div class="logo">

+ 1 - 0
app/langs/zh_Hans.txt

@@ -249,6 +249,7 @@ Maximize=最大化
 Restore Down=向下还原
 Runtime Environment=运行环境
 Reload AriaNg Native=重新加载 AriaNg Native
+Create New Task=创建新任务
 
 [tray]
 ShowAriaNgNative=显示 AriaNg Native (&S)

+ 1 - 0
app/langs/zh_Hant.txt

@@ -249,6 +249,7 @@ Maximize=最大化
 Restore Down=向下還原
 Runtime Environment=運行環境
 Reload AriaNg Native=重新載入 AriaNg Native
+Create New Task=建立新工作
 
 [tray]
 ShowAriaNgNative=顯示 AriaNg Native (&S)

+ 1 - 0
app/scripts/config/defaultLanguage.js

@@ -254,6 +254,7 @@
             'Restore Down': 'Restore Down',
             'Runtime Environment': 'Runtime Environment',
             'Reload AriaNg Native': 'Reload AriaNg Native',
+            'Create New Task': 'Create New Task',
             'tray': {
                 'ShowAriaNgNative': '&Show AriaNg Native',
                 'Exit': 'E&xit',

+ 21 - 16
app/scripts/controllers/new.js

@@ -57,23 +57,28 @@
         };
 
         var openFileViaElectron = function (event, result) {
-            if (result && !result.exception) {
-                $scope.context.uploadFile = result;
-                $scope.context.taskType = result.type;
-                $scope.changeTab('options');
-            } else if (result && result.exception) {
-                ariaNgLogService.error('[NewTaskController] get file via electron error', result.exception);
-
-                if (result.exception.code === 'ENOENT') {
-                    ariaNgLocalizationService.showError('native.error.file-not-found', null, {
-                        textParams: {
-                            filepath: result.exception.path
-                        }
-                    });
-                } else {
-                    ariaNgLocalizationService.showError(result.exception.code);
+            $scope.$apply(function () {
+                if (result && !result.exception) {
+                    $scope.context.uploadFile = result;
+                    $scope.context.taskType = result.type;
+
+                    if (!result.async) {
+                        $rootScope.loadPromise = $timeout(function () {}, 200);
+                    }
+                } else if (result && result.exception) {
+                    ariaNgLogService.error('[NewTaskController] get file via electron error', result.exception);
+
+                    if (result.exception.code === 'ENOENT') {
+                        ariaNgLocalizationService.showError('native.error.file-not-found', null, {
+                            textParams: {
+                                filepath: result.exception.path
+                            }
+                        });
+                    } else {
+                        ariaNgLocalizationService.showError(result.exception.code);
+                    }
                 }
-            }
+            });
         };
 
         $scope.context = {

+ 46 - 1
app/scripts/core/root.js

@@ -1,7 +1,7 @@
 (function () {
     'use strict';
 
-    angular.module('ariaNg').run(['$rootScope', '$location', '$document', 'ariaNgCommonService', 'ariaNgLocalizationService', 'ariaNgLogService', 'ariaNgSettingService', 'aria2TaskService', 'ariaNgNativeElectronService', function ($rootScope, $location, $document, ariaNgCommonService, ariaNgLocalizationService, ariaNgLogService, ariaNgSettingService, aria2TaskService, ariaNgNativeElectronService) {
+    angular.module('ariaNg').run(['$rootScope', '$location', '$window', '$document', 'ariaNgCommonService', 'ariaNgLocalizationService', 'ariaNgLogService', 'ariaNgSettingService', 'aria2TaskService', 'ariaNgNativeElectronService', function ($rootScope, $location, $window, $document, ariaNgCommonService, ariaNgLocalizationService, ariaNgLogService, ariaNgSettingService, aria2TaskService, ariaNgNativeElectronService) {
         var isUrlMatchUrl2 = function (url, url2) {
             if (url === url2) {
                 return true;
@@ -93,6 +93,46 @@
             $('.content-body').css('height', windowHeight - neg);
         };
 
+        var initFileDragSupport = function () {
+            var getDropFile = function (e) {
+                if (!e || !e.dataTransfer) {
+                    return null;
+                }
+
+                if (e.dataTransfer.items && e.dataTransfer.items[0] && e.dataTransfer.items[0].kind === 'file') {
+                    return e.dataTransfer.items[0].getAsFile();
+                } else if (e.dataTransfer.files && e.dataTransfer.files[0]) {
+                    return  e.dataTransfer.files[0];
+                } else {
+                    return null;
+                }
+            };
+
+            var dropzone = angular.element('#dropzone');
+            var dropzoneFileZone = angular.element('#dropzone-filezone');
+
+            angular.element($window).on('dragenter', function (e) {
+                dropzone.show();
+                e.preventDefault();
+            });
+
+            dropzoneFileZone.on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
+                e.preventDefault();
+                e.stopPropagation();
+            }).on('dragleave dragend drop', function() {
+                dropzone.hide();
+            }).on('drop', function(e) {
+                var file = getDropFile(e.originalEvent);
+
+                if (file) {
+                    ariaNgNativeElectronService.sendMessageToMainProcess('new-drop-file', {
+                        filePath: file.path,
+                        location: $location.url()
+                    });
+                }
+            });
+        };
+
         var showSidebar = function () {
             angular.element('body').removeClass('sidebar-collapse').addClass('sidebar-open');
         };
@@ -219,6 +259,10 @@
             $location.path(routeUrl);
         });
 
+        ariaNgNativeElectronService.onMainProcessMessage('show-error', function (event, message) {
+            ariaNgLocalizationService.showError(message);
+        });
+
         ariaNgSettingService.setDebugMode(ariaNgNativeElectronService.isDevMode());
 
         ariaNgSettingService.onFirstAccess(function () {
@@ -296,5 +340,6 @@
         initCheck();
         initNavbar();
         initContentWrapper();
+        initFileDragSupport();
     }]);
 }());

+ 46 - 0
app/styles/core/native-core.css

@@ -0,0 +1,46 @@
+.dropzone {
+    background: rgba(255, 255, 255, 0.85);
+    display: none;
+    position: fixed;
+    width: 100%;
+    height: 100%;
+    left: 0;
+    top: 0;
+    box-sizing: border-box;
+    z-index: 10000;
+}
+
+.dropzone .dropzone-filezone {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    z-index: 10009;
+}
+
+.dropzone .dropzone-tip-container {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    padding: 12px;
+}
+
+.dropzone .dropzone-tip-container .dropzone-tip-wrapper {
+    width: 100%;
+    height: 100%;
+    border: 6px dashed #ccc;
+    border-radius: 8px;
+}
+
+.dropzone .dropzone-tip-container .dropzone-tip-wrapper .dropzone-tip {
+    display: inline-block;
+    position: absolute;
+    padding-right: 18px;
+    width: 100%;
+    top: 50%;
+    transform: translateY(-50%);
+    text-align: center;
+}
+
+.dropzone .dropzone-tip-container .dropzone-tip-wrapper .dropzone-tip i.fa {
+    font-size: 96px;
+}

+ 32 - 20
cmd.js

@@ -65,35 +65,45 @@ let cmd = (function () {
         navigateTo('/new');
     };
 
-    let asyncNewTaskFromFile = function (filePath) {
-        if (!filePath) {
-            return;
-        }
+    let showErrorMessage = function (message) {
+        core.mainWindow.webContents.send('show-error', message);
+    };
 
+    let newTaskFromFile = function (filePath, async) {
         let fileExtension = path.extname(filePath);
 
         if (!supportedFileExtensions[fileExtension]) {
+            cmd.showErrorMessage('The selected file type is invalid!');
             return;
         }
 
-        ipcMain.once('view-content-loaded', (event, arg) => {
-            let result = null;
-
-            try {
-                let fileContent = fs.readFileSync(filePath);
-
-                result = {
-                    type: supportedFileExtensions[fileExtension],
-                    fileName: path.basename(filePath),
-                    base64Content: Buffer.from(fileContent).toString('base64')
-                };
-            } catch (e) {
-                result = {
-                    exception: e
-                }
+        let result = null;
+
+        try {
+            let fileContent = fs.readFileSync(filePath);
+
+            result = {
+                type: supportedFileExtensions[fileExtension],
+                fileName: path.basename(filePath),
+                base64Content: Buffer.from(fileContent).toString('base64'),
+                async: !!async
+            };
+        } catch (e) {
+            result = {
+                exception: e
             }
+        }
 
-            event.sender.send('new-task-from-file', result)
+        core.mainWindow.webContents.send('new-task-from-file', result)
+    };
+
+    let asyncNewTaskFromFile = function (filePath) {
+        if (!filePath) {
+            return;
+        }
+
+        ipcMain.once('view-content-loaded', (event, arg) => {
+            newTaskFromFile(filePath, true);
         });
     };
 
@@ -104,6 +114,8 @@ let cmd = (function () {
         loadNewTaskUrl: loadNewTaskUrl,
         navigateTo: navigateTo,
         navigateToNewTask: navigateToNewTask,
+        showErrorMessage: showErrorMessage,
+        newTaskFromFile: newTaskFromFile,
         asyncNewTaskFromFile: asyncNewTaskFromFile
     }
 })();