Browse Source

Attachment, simple upload progress bar

Martin Filser 2 năm trước cách đây
mục cha
commit
ea937810f2

+ 4 - 0
client/components/cards/attachments.css

@@ -1,3 +1,7 @@
+.attachment-upload {
+  text-align: center;
+  font-weight: bold;
+}
 .attachments-galery {
   display: flex;
   flex-wrap: wrap;

+ 20 - 8
client/components/cards/attachments.jade

@@ -1,10 +1,24 @@
 template(name="cardAttachmentsPopup")
-  ul.pop-over-list
-    li
-      input.js-attach-file.hide(type="file" name="file" multiple)
-      a.js-computer-upload {{_ 'computer'}}
-    li
-      a.js-upload-clipboard-image {{_ 'clipboard'}}
+  with currentUpload
+    .attachment-upload {{_ 'uploading'}}
+      table
+        tr
+          th.upload-file-name-descr {{_ 'name'}}
+          th.upload-progress-descr {{_ 'progress'}}
+          th.upload-remaining-descr {{_ 'remaining_time'}}
+          th.upload-speed-descr {{_ 'speed'}}
+        tr
+          td.upload-file-name-value {{file.name}}
+          td.upload-progress-value {{progress.get}}%
+          td.upload-remaining-value {{getEstimateTime}}
+          td.upload-speed-value {{getEstimateSpeed}}
+  else
+    ul.pop-over-list
+      li
+        input.js-attach-file.hide(type="file" name="file" multiple)
+        a.js-computer-upload {{_ 'computer'}}
+      li
+        a.js-upload-clipboard-image {{_ 'clipboard'}}
 
 template(name="previewClipboardImagePopup")
   p <kbd>Ctrl</kbd>+<kbd>V</kbd> {{_ "paste-or-dragdrop"}}
@@ -37,8 +51,6 @@ template(name="attachmentsGalery")
                   source(src="{{link}}" type="video/mp4")
             else
               span.attachment-thumbnail-ext= extension
-          else
-            +spinner
         p.attachment-details
           = name
           span.file-size ({{fileSize size}} KB)

+ 30 - 2
client/components/cards/attachments.js

@@ -1,3 +1,6 @@
+const filesize = require('filesize');
+const prettyMilliseconds = require('pretty-ms');
+
 Template.attachmentsGalery.events({
   'click .js-add-attachment': Popup.open('cardAttachments'),
   // If we let this event bubble, FlowRouter will handle it and empty the page
@@ -17,8 +20,26 @@ Template.attachmentsGalery.helpers({
   },
 });
 
+Template.cardAttachmentsPopup.onCreated(function() {
+  this.currentUpload = new ReactiveVar(false);
+});
+
+Template.cardAttachmentsPopup.helpers({
+  getEstimateTime() {
+    const ret = prettyMilliseconds(Template.instance().currentUpload.get().estimateTime.get());
+    return ret;
+  },
+  getEstimateSpeed() {
+    const ret = filesize(Template.instance().currentUpload.get().estimateSpeed.get(), {round: 0}) + "/s";
+    return ret;
+  },
+  currentUpload() {
+    return Template.instance().currentUpload.get();
+  }
+});
+
 Template.cardAttachmentsPopup.events({
-  'change .js-attach-file'(event) {
+  'change .js-attach-file'(event, templateInstance) {
     const card = this;
     const files = event.currentTarget.files;
     if (files) {
@@ -36,6 +57,9 @@ Template.cardAttachmentsPopup.events({
           config,
           false,
         );
+        uploader.on('start', function() {
+          templateInstance.currentUpload.set(this);
+        });
         uploader.on('uploaded', (error, fileRef) => {
           if (!error) {
             if (fileRef.isImage) {
@@ -44,7 +68,11 @@ Template.cardAttachmentsPopup.events({
           }
         });
         uploader.on('end', (error, fileRef) => {
-          Popup.back();
+          templateInstance.currentUpload.set(false);
+          finished.push(fileRef);
+          if (finished.length == files.length) {
+            Popup.back();
+          }
         });
         uploader.start();
       }

+ 5 - 1
imports/i18n/data/en.i18n.json

@@ -1181,5 +1181,9 @@
   "storage": "Storage",
   "action": "Action",
   "board-title": "Board Title",
-  "attachmentRenamePopup-title": "Rename"
+  "attachmentRenamePopup-title": "Rename",
+  "uploading": "Uploading",
+  "remaining_time": "Remaining time",
+  "speed": "Speed",
+  "progress": "Progress"
 }

+ 18 - 0
package-lock.json

@@ -1791,6 +1791,11 @@
         "token-types": "^4.1.1"
       }
     },
+    "filesize": {
+      "version": "8.0.7",
+      "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz",
+      "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ=="
+    },
     "find-up": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -3624,6 +3629,11 @@
         "parse5": "^7.0.0"
       }
     },
+    "parse-ms": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz",
+      "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA=="
+    },
     "path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -3671,6 +3681,14 @@
       "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
       "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ=="
     },
+    "pretty-ms": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz",
+      "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==",
+      "requires": {
+        "parse-ms": "^2.1.0"
+      }
+    },
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",

+ 2 - 0
package.json

@@ -37,6 +37,7 @@
     "exceljs": "^4.2.1",
     "fibers": "^5.0.0",
     "file-type": "^16.5.4",
+    "filesize": "^8.0.7",
     "i18next": "^21.6.16",
     "i18next-sprintf-postprocessor": "^0.2.2",
     "jquery": "^2.2.4",
@@ -55,6 +56,7 @@
     "os": "^0.1.2",
     "page": "^1.11.6",
     "papaparse": "^5.3.1",
+    "pretty-ms": "^7.0.1",
     "qs": "^6.10.1",
     "simpl-schema": "^1.12.0",
     "source-map-support": "^0.5.20",