diff --git a/conversation.html b/conversation.html index f3e80b8a..390e9747 100644 --- a/conversation.html +++ b/conversation.html @@ -35,7 +35,7 @@
- +
diff --git a/js/views/file_input_view.js b/js/views/file_input_view.js index 95468a2f..0431c6c7 100644 --- a/js/views/file_input_view.js +++ b/js/views/file_input_view.js @@ -46,37 +46,75 @@ var Whisper = Whisper || {}; this.$el.find('.paperclip').append(this.thumb.render().el); }, + autoScale: function(file) { + if (file.type.split('/')[0] !== 'image' || file.size/1024 < 420) { + // nothing to do + return Promise.resolve(file); + } + + return new Promise(function(resolve, reject) { + // components/blueimp-load-image + window.loadImage(file, resolve, { + maxWidth: 1920, + maxHeight: 1920, + canvas: true, + contain: true + }); + }).then(this.autoCompress.bind(this)); + }, + + autoCompress: function(canvas, numRetries, quality) { + if (numRetries === undefined) { numRetries = 3; } + if (quality === undefined) { quality = 0.95; } + + var autoCompress = this.autoCompress.bind(this); + + return new Promise(function(resolve, reject) { + canvas.toBlob(function(blob) { + var kb = blob.size/1024; + if (kb < 420 || numRetries === 0) { + resolve(blob); + } else { + quality = quality * 420 / kb; + if (quality < 50) { + quality = 50; + numRetries = 1; + } + resolve(autoCompress(canvas, numRetries - 1, quality)); + } + }, 'image/jpeg', quality); + }); + }, + previewImages: function() { this.clearForm(); - var files = this.$input.prop('files'); - for (var i = 0; i < files.length; i++) { - var type = files[i].type.split('/')[0]; + var file = this.$input.prop('files')[0]; + if (!file) { return; } + + var type = file.type.split('/')[0]; + switch (type) { + case 'audio': this.addThumb('/images/audio.png'); break; + case 'video': this.addThumb('/images/video.png'); break; + case 'image': + this.oUrl = URL.createObjectURL(file); + this.addThumb(this.oUrl); + break; + } + + this.autoScale(file).then(function(blob) { var limitKb = 1000000; switch (type) { case 'image': limitKb = 420; break; case 'audio': limitKb = 32000; break; case 'video': limitKb = 8000; break; } - if ((files[i].size/1024).toFixed(4) >= limitKb) { + if ((blob.size/1024).toFixed(4) >= limitKb) { new Whisper.FileSizeToast({ model: {limit: limitKb} }).render(); this.deleteFiles(); } - else { - switch (type) { - case 'audio': this.addThumb('/images/audio.png'); break; - case 'video': this.addThumb('/images/video.png'); break; - case 'image': - var FR = new FileReader(); - FR.onload = function(e) { - this.addThumb(e.target.result); - }.bind(this); - FR.readAsDataURL(files[i]); - break; - } - } - } + }.bind(this)); }, hasFiles: function() { @@ -88,12 +126,18 @@ var Whisper = Whisper || {}; var promises = []; var files = this.$input.prop('files'); for (var i = 0; i < files.length; i++) { - promises.push(this.readFile(files[i])); + promises.push(this.getFile(files[i])); } this.clearForm(); return Promise.all(promises); }, + getFile: function(file) { + file = file || this.$input.prop('files')[0]; + if (file === undefined) { throw 'No file'; } + return this.autoScale(file).then(this.readFile); + }, + readFile: function(file) { var contentType = file.type; return new Promise(function(resolve, reject) { @@ -106,6 +150,10 @@ var Whisper = Whisper || {}; }, clearForm: function() { + if (this.oUrl) { + URL.revokeObjectURL(this.oUrl); + this.oUrl = null; + } this.thumb.remove(); },