]> git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/blobdiff - frontend/js/app.js
Superagent is a bit bogus
[perso/Immae/Projets/Nodejs/Surfer.git] / frontend / js / app.js
index 92dc1defd6b804183a2140583fe6a0ac77140e0c..c1a63a9df6398760e3b1799569bcc033d54cbceb 100644 (file)
@@ -132,23 +132,36 @@ function uploadFiles(files) {
 
     app.uploadStatus.busy = true;
     app.uploadStatus.count = files.length;
+    app.uploadStatus.size = 0;
     app.uploadStatus.done = 0;
     app.uploadStatus.percentDone = 0;
 
+    for (var i = 0; i < files.length; ++i) {
+        app.uploadStatus.size += files[i].size;
+    }
+
     asyncForEach(files, function (file, callback) {
-        var path = encode(sanitize(app.path + '/' + file.name));
+        var path = encode(sanitize(app.path + '/' + (file.webkitRelativePath || file.name)));
 
         var formData = new FormData();
         formData.append('file', file);
 
-        superagent.post('/api/files' + path).query({ access_token: localStorage.accessToken }).send(formData).end(function (error, result) {
+        var finishedUploadSize = app.uploadStatus.done;
+
+        superagent.post('/api/files' + path)
+          .query({ access_token: localStorage.accessToken })
+          .send(formData)
+          .on('progress', function (event) {
+            // only handle upload events
+            if (!(event.target instanceof XMLHttpRequestUpload)) return;
+
+            app.uploadStatus.done = finishedUploadSize + event.loaded;
+            app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.size * 100);
+        }).end(function (error, result) {
             if (result && result.statusCode === 401) return logout();
             if (result && result.statusCode !== 201) return callback('Error uploading file: ', result.statusCode);
             if (error) return callback(error);
 
-            app.uploadStatus.done += 1;
-            app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.count * 100);
-
             callback();
         });
     }, function (error) {
@@ -156,6 +169,7 @@ function uploadFiles(files) {
 
         app.uploadStatus.busy = false;
         app.uploadStatus.count = 0;
+        app.uploadStatus.size = 0;
         app.uploadStatus.done = 0;
         app.uploadStatus.percentDone = 100;
 
@@ -164,12 +178,59 @@ function uploadFiles(files) {
 }
 
 function dragOver(event) {
+    event.stopPropagation();
     event.preventDefault();
+    event.dataTransfer.dropEffect = 'copy';
 }
 
 function drop(event) {
+    event.stopPropagation();
     event.preventDefault();
-    uploadFiles(event.dataTransfer.files || []);
+
+    if (!event.dataTransfer.items[0]) return;
+
+    // figure if a folder was dropped on a modern browser, in this case the first would have to be a directory
+    var folderItem;
+    try {
+        folderItem = event.dataTransfer.items[0].webkitGetAsEntry();
+        if (folderItem.isFile) return uploadFiles(event.dataTransfer.files);
+    } catch (e) {
+        return uploadFiles(event.dataTransfer.files);
+    }
+
+    // if we got here we have a folder drop and a modern browser
+    // now traverse the folder tree and create a file list
+    app.uploadStatus.busy = true;
+    app.uploadStatus.uploadListCount = 0;
+
+    var fileList = [];
+    function traverseFileTree(item, path, callback) {
+        if (item.isFile) {
+            // Get file
+            item.file(function (file) {
+                fileList.push(file);
+                ++app.uploadStatus.uploadListCount;
+                callback();
+            });
+        } else if (item.isDirectory) {
+            // Get folder contents
+            var dirReader = item.createReader();
+            dirReader.readEntries(function (entries) {
+                asyncForEach(entries, function (entry, callback) {
+                    traverseFileTree(entry, path + item.name + '/', callback);
+                }, callback);
+            });
+        }
+    }
+
+    traverseFileTree(folderItem, '', function (error) {
+        app.uploadStatus.busy = false;
+        app.uploadStatus.uploadListCount = 0;
+
+        if (error) return console.error(error);
+
+        uploadFiles(fileList);
+    });
 }
 
 var app = new Vue({
@@ -181,7 +242,8 @@ var app = new Vue({
             busy: false,
             count: 0,
             done: 0,
-            percentDone: 50
+            percentDone: 50,
+            uploadListCount: 0
         },
         path: '/',
         pathParts: [],
@@ -250,10 +312,8 @@ var app = new Vue({
             var that = this;
 
             $(this.$refs.upload).on('change', function () {
-
                 // detach event handler
                 $(that.$refs.upload).off('change');
-
                 uploadFiles(that.$refs.upload.files || []);
             });
 
@@ -261,6 +321,19 @@ var app = new Vue({
             this.$refs.upload.value = '';
             this.$refs.upload.click();
         },
+        onUploadFolder: function () {
+            var that = this;
+
+            $(this.$refs.uploadFolder).on('change', function () {
+                // detach event handler
+                $(that.$refs.uploadFolder).off('change');
+                uploadFiles(that.$refs.uploadFolder.files || []);
+            });
+
+            // reset the form first to make the change handler retrigger even on the same file selected
+            this.$refs.uploadFolder.value = '';
+            this.$refs.uploadFolder.click();
+        },
         onDelete: function (entry) {
             var that = this;
 
@@ -275,9 +348,7 @@ var app = new Vue({
 
                     refresh();
                 });
-            }).catch(function () {
-                console.log('delete error:', arguments);
-            });
+            }).catch(function () {});
         },
         onRename: function (entry) {
             var that = this;
@@ -294,9 +365,7 @@ var app = new Vue({
 
                     refresh();
                 });
-            }).catch(function (error) {
-                that.$message.error(error.message);
-            });
+            }).catch(function () {});
         },
         onNewFolder: function () {
             var that = this;
@@ -314,9 +383,7 @@ var app = new Vue({
 
                     refresh();
                 });
-            }).catch(function (error) {
-                that.$message.error(error.message);
-            });
+            }).catch(function () {});
         },
         prettyDate: function (row, column, cellValue, index) {
             var date = new Date(cellValue),