]> git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/commitdiff
Show upload progress
authorJohannes Zellner <johannes@cloudron.io>
Thu, 17 May 2018 12:59:45 +0000 (14:59 +0200)
committerJohannes Zellner <johannes@cloudron.io>
Thu, 17 May 2018 12:59:45 +0000 (14:59 +0200)
frontend/css/style.css
frontend/index.html
frontend/js/app.js

index 5c9236b485cd67bfbdcdf7c6d0081d38949f48c6..45fce568245d0737474edbd93da358a872081f00 100644 (file)
@@ -23,7 +23,7 @@ body {
 .el-footer {
     padding: 3px 20px;
     font-size: 14px;
-    text-align: center;
+    height: 38px !important;
 }
 
 a {
index 2e2e5e3e3549cccab39839a4d9ccc73fcd2c25a1..15e5d98a5d7ccc21c4523864ec79922097293f7c 100644 (file)
   </el-header>
   <el-main>
 
-    <!-- <div class="container" v-show="uploadStatus.busy" v-cloak>
-        <div class="row">
-            <div class="col-lg-12">
-                <p>Uploading... ({{ uploadStatus.done }} / {{ uploadStatus.count }}) </p>
-                <center>
-                    <div class="progress">
-                        <div class="progress-bar progress-bar-striped" role="progressbar" v-bind:style="{ width: uploadStatus.percentDone + '%' }">
-                            <span class="sr-only">{{ uploadStatus.percentDone }}% Complete</span>
-                        </div>
-                    </div>
-                </center>
-            </div>
-        </div>
-    </div> -->
-
     <div v-show="busy">
       <center><h1><i class="el-icon-loading"></i></h1></center>
     </div>
 
     <div v-show="!busy && session.valid" v-cloak>
-      <el-table :data="entries" style="width: 100%" height="100%" empty-text="Folder is emtpy" :default-sort="{ prop: 'filePath', order: 'descending' }" @row-click="open">
-        <el-table-column prop="previewUrl" label="Type" width="100px" sortable>
-          <template slot-scope="scope">
-            <img v-bind:src="scope.row.previewUrl" height="48px" width="48px"/>
-          </template>
-        </el-table-column>
-        <el-table-column prop="filePath" label="Name" sortable></el-table-column>
-        <el-table-column prop="size" label="Size" width="150px" sortable :formatter="prettyFileSize"></el-table-column>
-        <el-table-column prop="mtime" label="Modified" width="150px" sortable :formatter="prettyDate"></el-table-column>
-        <el-table-column label="Actions" align="right" width="200px" class-name="list-actions">
-          <template slot-scope="scope">
-            <el-button size="small" icon="el-icon-download" circle v-show="scope.row.isFile" @click.stop="onDownload(scope.row)"></el-button>
-            <el-button size="small" icon="el-icon-edit" circle @click.stop="onRename(scope.row)"></el-button>
-            <el-button size="small" icon="el-icon-delete" circle @click.stop="onDelete(scope.row)"></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
+      <center>
+        <el-table :data="entries" style="max-width: 1280px;width: 100%" height="100%" empty-text="Folder is emtpy" :default-sort="{ prop: 'filePath', order: 'descending' }" @row-click="open">
+          <el-table-column prop="previewUrl" label="Type" width="100px" sortable>
+            <template slot-scope="scope">
+              <img v-bind:src="scope.row.previewUrl" height="48px" width="48px"/>
+            </template>
+          </el-table-column>
+          <el-table-column prop="filePath" label="Name" sortable></el-table-column>
+          <el-table-column prop="size" label="Size" width="150px" sortable :formatter="prettyFileSize"></el-table-column>
+          <el-table-column prop="mtime" label="Modified" width="150px" sortable :formatter="prettyDate"></el-table-column>
+          <el-table-column label="Actions" align="right" width="200px" class-name="list-actions">
+            <template slot-scope="scope">
+              <el-button size="small" icon="el-icon-download" circle v-show="scope.row.isFile" @click.stop="onDownload(scope.row)"></el-button>
+              <el-button size="small" icon="el-icon-edit" circle @click.stop="onRename(scope.row)"></el-button>
+              <el-button size="small" icon="el-icon-delete" circle @click.stop="onDelete(scope.row)"></el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </center>
     </div>
 
   </el-main>
-  <el-footer style="height: 24px">Built by the <a href="https://cloudron.io" target="_blank">Cloudron.io</a> team. <a href="https://git.cloudron.io/cloudron/surfer" target="_blank">Get the code</a></el-footer>
+  <el-footer v-show="uploadStatus.busy">
+    <el-row>
+      <el-col :span="4">
+        Uploading files ({{ uploadStatus.done }} / {{ uploadStatus.count }})
+      </el-col>
+      <el-col :span="20">
+        <el-progress :text-inside="true" :stroke-width="18" :percentage="uploadStatus.percentDone"></el-progress>
+      </el-col>
+    </el-row>
+  </el-footer>
 </el-container>
 
 </div>
index d659b180c86a1c7b3972dc4d31254228af5718b2..1500457e0a3993c402a18860ac47a7ce2d69acbc 100644 (file)
@@ -1,6 +1,23 @@
 (function () {
 'use strict';
 
+// poor man's async
+function asyncForEach(items, handler, callback) {
+    var cur = 0;
+
+    if (items.length === 0) return callback();
+
+    (function iterator() {
+        handler(items[cur], function (error) {
+            if (error) return callback(error);
+            if (cur >= items.length-1) return callback();
+            ++cur;
+
+            iterator();
+        });
+    })();
+}
+
 function getProfile(accessToken, callback) {
     callback = callback || function (error) { if (error) console.error(error); };
 
@@ -114,14 +131,12 @@ function up() {
 function uploadFiles(files) {
     if (!files || !files.length) return;
 
-    app.uploadStatus = {
-        busy: true,
-        count: files.length,
-        done: 0,
-        percentDone: 0
-    };
+    app.uploadStatus.busy = true;
+    app.uploadStatus.count = files.length;
+    app.uploadStatus.done = 0;
+    app.uploadStatus.percentDone = 0;
 
-    function uploadFile(file) {
+    asyncForEach(files, function (file, callback) {
         var path = encode(sanitize(app.path + '/' + file.name));
 
         var formData = new FormData();
@@ -129,28 +144,24 @@ function uploadFiles(files) {
 
         superagent.post('/api/files' + path).query({ access_token: localStorage.accessToken }).send(formData).end(function (error, result) {
             if (result && result.statusCode === 401) return logout();
-            if (result && result.statusCode !== 201) console.error('Error uploading file: ', result.statusCode);
-            if (error) console.error(error);
+            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);
 
-            if (app.uploadStatus.done >= app.uploadStatus.count) {
-                app.uploadStatus = {
-                    busy: false,
-                    count: 0,
-                    done: 0,
-                    percentDone: 100
-                };
-
-                refresh();
-            }
+            callback();
         });
-    }
+    }, function (error) {
+        if (error) console.error(error);
 
-    for(var i = 0; i < app.uploadStatus.count; ++i) {
-        uploadFile(files[i]);
-    }
+        app.uploadStatus.busy = false;
+        app.uploadStatus.count = 0;
+        app.uploadStatus.done = 0;
+        app.uploadStatus.percentDone = 100;
+
+        refresh();
+    });
 }
 
 function dragOver(event) {