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",