|
|
|
@ -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) { |
|
|
|
|