|
@@ -54,7 +54,7 @@ Template.previewAttachedImagePopup.events({
|
|
|
Template.cardAttachmentsPopup.events({
|
|
|
'change .js-attach-file'(event) {
|
|
|
const card = this;
|
|
|
- FS.Utility.eachFile(event, f => {
|
|
|
+ const processFile = f => {
|
|
|
const file = new FS.File(f);
|
|
|
if (card.isLinkedCard()) {
|
|
|
file.boardId = Cards.findOne(card.linkedId).boardId;
|
|
@@ -66,7 +66,6 @@ Template.cardAttachmentsPopup.events({
|
|
|
file.cardId = card._id;
|
|
|
}
|
|
|
file.userId = Meteor.userId();
|
|
|
-
|
|
|
const attachment = Attachments.insert(file);
|
|
|
|
|
|
if (attachment && attachment._id && attachment.isImage()) {
|
|
@@ -74,6 +73,42 @@ Template.cardAttachmentsPopup.events({
|
|
|
}
|
|
|
|
|
|
Popup.close();
|
|
|
+ };
|
|
|
+
|
|
|
+ FS.Utility.eachFile(event, f => {
|
|
|
+ if (
|
|
|
+ MAX_IMAGE_PIXEL > 0 &&
|
|
|
+ typeof f.type === 'string' &&
|
|
|
+ f.type.match(/^image/)
|
|
|
+ ) {
|
|
|
+ // is image
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = function(e) {
|
|
|
+ const dataurl = e && e.target && e.target.result;
|
|
|
+ if (dataurl !== undefined) {
|
|
|
+ shrinkImage({
|
|
|
+ dataurl,
|
|
|
+ maxSize: MAX_IMAGE_PIXEL,
|
|
|
+ ratio: COMPRESS_RATIO,
|
|
|
+ toBlob: true,
|
|
|
+ callback(blob) {
|
|
|
+ if (blob === false) {
|
|
|
+ processFile(f);
|
|
|
+ } else {
|
|
|
+ blob.name = f.name;
|
|
|
+ processFile(blob);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // couldn't process it let other function handle it?
|
|
|
+ processFile(f);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ reader.readAsDataURL(f);
|
|
|
+ } else {
|
|
|
+ processFile(f);
|
|
|
+ }
|
|
|
});
|
|
|
},
|
|
|
'click .js-computer-upload'(event, templateInstance) {
|
|
@@ -83,30 +118,96 @@ Template.cardAttachmentsPopup.events({
|
|
|
'click .js-upload-clipboard-image': Popup.open('previewClipboardImage'),
|
|
|
});
|
|
|
|
|
|
+const MAX_IMAGE_PIXEL = Meteor.settings.public.MAX_IMAGE_PIXEL;
|
|
|
+const COMPRESS_RATIO = Meteor.settings.public.IMAGE_COMPRESS_RATIO;
|
|
|
let pastedResults = null;
|
|
|
+const shrinkImage = function(options) {
|
|
|
+ // shrink image to certain size
|
|
|
+ const dataurl = options.dataurl,
|
|
|
+ callback = options.callback,
|
|
|
+ toBlob = options.toBlob;
|
|
|
+ let canvas = document.createElement('canvas'),
|
|
|
+ image = document.createElement('img');
|
|
|
+ const maxSize = options.maxSize || 1024;
|
|
|
+ const ratio = options.ratio || 1.0;
|
|
|
+ const next = function(result) {
|
|
|
+ image = null;
|
|
|
+ canvas = null;
|
|
|
+ if (typeof callback === 'function') {
|
|
|
+ callback(result);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ image.onload = function() {
|
|
|
+ let width = this.width,
|
|
|
+ height = this.height;
|
|
|
+ let changed = false;
|
|
|
+ if (width > height) {
|
|
|
+ if (width > maxSize) {
|
|
|
+ height *= maxSize / width;
|
|
|
+ width = maxSize;
|
|
|
+ changed = true;
|
|
|
+ }
|
|
|
+ } else if (height > maxSize) {
|
|
|
+ width *= maxSize / height;
|
|
|
+ height = maxSize;
|
|
|
+ changed = true;
|
|
|
+ }
|
|
|
+ canvas.width = width;
|
|
|
+ canvas.height = height;
|
|
|
+ canvas.getContext('2d').drawImage(this, 0, 0, width, height);
|
|
|
+ if (changed === true) {
|
|
|
+ const type = 'image/jpeg';
|
|
|
+ if (toBlob) {
|
|
|
+ canvas.toBlob(next, type, ratio);
|
|
|
+ } else {
|
|
|
+ next(canvas.toDataURL(type, ratio));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ next(changed);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ image.onerror = function() {
|
|
|
+ next(false);
|
|
|
+ };
|
|
|
+ image.src = dataurl;
|
|
|
+};
|
|
|
|
|
|
Template.previewClipboardImagePopup.onRendered(() => {
|
|
|
// we can paste image from clipboard
|
|
|
- $(document.body).pasteImageReader(results => {
|
|
|
+ const handle = results => {
|
|
|
if (results.dataURL.startsWith('data:image/')) {
|
|
|
- $('img.preview-clipboard-image').attr('src', results.dataURL);
|
|
|
- pastedResults = results;
|
|
|
+ const direct = results => {
|
|
|
+ $('img.preview-clipboard-image').attr('src', results.dataURL);
|
|
|
+ pastedResults = results;
|
|
|
+ };
|
|
|
+ if (MAX_IMAGE_PIXEL) {
|
|
|
+ // if has size limitation on image we shrink it before uploading
|
|
|
+ shrinkImage({
|
|
|
+ dataurl: results.dataURL,
|
|
|
+ maxSize: MAX_IMAGE_PIXEL,
|
|
|
+ ratio: COMPRESS_RATIO,
|
|
|
+ callback(changed) {
|
|
|
+ if (changed !== false && !!changed) {
|
|
|
+ results.dataURL = changed;
|
|
|
+ }
|
|
|
+ direct(results);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
+ };
|
|
|
+
|
|
|
+ $(document.body).pasteImageReader(handle);
|
|
|
|
|
|
// we can also drag & drop image file to it
|
|
|
- $(document.body).dropImageReader(results => {
|
|
|
- if (results.dataURL.startsWith('data:image/')) {
|
|
|
- $('img.preview-clipboard-image').attr('src', results.dataURL);
|
|
|
- pastedResults = results;
|
|
|
- }
|
|
|
- });
|
|
|
+ $(document.body).dropImageReader(handle);
|
|
|
});
|
|
|
|
|
|
Template.previewClipboardImagePopup.events({
|
|
|
'click .js-upload-pasted-image'() {
|
|
|
const results = pastedResults;
|
|
|
if (results && results.file) {
|
|
|
+ window.oPasted = pastedResults;
|
|
|
const card = this;
|
|
|
const file = new FS.File(results.file);
|
|
|
if (!results.name) {
|