]> 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 9d7bacaa1cd4887420714d558972aea1aa7ba420..c1a63a9df6398760e3b1799569bcc033d54cbceb 100644 (file)
@@ -132,26 +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;
 
-    asyncForEach(files, function (file, callback) {
-        // do not handle directories (file.type is empty in such a case)
-        if (file.type === '') return callback();
+    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.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) {
@@ -159,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;
 
@@ -175,7 +186,51 @@ function dragOver(event) {
 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({
@@ -187,7 +242,8 @@ var app = new Vue({
             busy: false,
             count: 0,
             done: 0,
-            percentDone: 50
+            percentDone: 50,
+            uploadListCount: 0
         },
         path: '/',
         pathParts: [],