diff --git a/client/components/cards/attachments.css b/client/components/cards/attachments.css
index 67aeed96f..eeb259175 100644
--- a/client/components/cards/attachments.css
+++ b/client/components/cards/attachments.css
@@ -1,3 +1,7 @@
+.attachment-upload {
+ text-align: center;
+ font-weight: bold;
+}
.attachments-galery {
display: flex;
flex-wrap: wrap;
diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade
index f915e8bb5..426914879 100644
--- a/client/components/cards/attachments.jade
+++ b/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 Ctrl+V {{_ "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)
diff --git a/client/components/cards/attachments.js b/client/components/cards/attachments.js
index ade5833b0..a723baf23 100644
--- a/client/components/cards/attachments.js
+++ b/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();
}
diff --git a/imports/i18n/data/en.i18n.json b/imports/i18n/data/en.i18n.json
index b48ae3dcb..12ee428b8 100644
--- a/imports/i18n/data/en.i18n.json
+++ b/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"
}
diff --git a/package-lock.json b/package-lock.json
index 2729c0c0b..f2dff842a 100644
--- a/package-lock.json
+++ b/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",
diff --git a/package.json b/package.json
index a59e398bf..3280d0ab4 100644
--- a/package.json
+++ b/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",