From 46dac94ab80f9ba853a81cc9f85fe2736a892453 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Wed, 5 Sep 2018 17:47:21 -0700 Subject: [PATCH] Pop toast on attempted attach if image attachment is too large --- _locales/en/messages.json | 3 + js/views/file_input_view.js | 116 +++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 43 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 7a2232fe5..3b8f46c86 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -549,6 +549,9 @@ "fileSizeWarning": { "message": "Sorry, the selected file exceeds message size restrictions." }, + "unableToLoadAttachment": { + "message": "Unable to load selected attachment." + }, "disconnected": { "message": "Disconnected", "description": diff --git a/js/views/file_input_view.js b/js/views/file_input_view.js index 76e023881..d667d7ae8 100644 --- a/js/views/file_input_view.js +++ b/js/views/file_input_view.js @@ -24,6 +24,12 @@ }; }, }); + Whisper.UnableToLoadToast = Whisper.ToastView.extend({ + render_attributes() { + return { toastMessage: i18n('unableToLoadAttachment') }; + }, + }); + Whisper.UnsupportedFileTypeToast = Whisper.ToastView.extend({ template: i18n('unsupportedFileType'), }); @@ -88,14 +94,21 @@ this.thumb.$('img')[0].onload = () => { this.$el.trigger('force-resize'); }; + this.thumb.$('img')[0].onerror = () => { + this.unableToLoadAttachment(); + }; + }, + + unableToLoadAttachment() { + const toast = new Whisper.UnableToLoadToast(); + toast.$el.insertAfter(this.$el); + toast.render(); + + this.deleteFiles(); }, autoScale(file) { - if ( - file.type.split('/')[0] !== 'image' || - file.type === 'image/gif' || - file.type === 'image/tiff' - ) { + if (file.type.split('/')[0] !== 'image' || file.type === 'image/tiff') { // nothing to do return Promise.resolve(file); } @@ -111,14 +124,19 @@ const maxHeight = 4096; const maxWidth = 4096; if ( - img.width <= maxWidth && - img.height <= maxHeight && + img.naturalWidth <= maxWidth && + img.naturalHeight <= maxHeight && file.size <= maxSize ) { resolve(file); return; } + if (file.type === 'image/gif') { + reject(new Error('GIF is too large')); + return; + } + const canvas = loadImage.scale(img, { canvas: true, maxWidth, @@ -180,6 +198,9 @@ const renderImagePreview = async () => { if (!MIME.isJPEG(file.type)) { this.previewObjectUrl = URL.createObjectURL(file); + if (!this.previewObjectUrl) { + throw new Error('Failed to create object url for image!'); + } this.addThumb(this.previewObjectUrl); return; } @@ -206,42 +227,51 @@ this.addThumb('images/file.svg'); } - const blob = await this.autoScale(file); - let limitKb = 1000000; - const blobType = - file.type === 'image/gif' ? 'gif' : contentType.split('/')[0]; - - switch (blobType) { - case 'image': - limitKb = 6000; - break; - case 'gif': - limitKb = 25000; - break; - case 'audio': - limitKb = 100000; - break; - case 'video': - limitKb = 100000; - break; - default: - limitKb = 100000; - break; - } - if ((blob.size / 1024).toFixed(4) >= limitKb) { - const units = ['kB', 'MB', 'GB']; - let u = -1; - let limit = limitKb * 1000; - do { - limit /= 1000; - u += 1; - } while (limit >= 1000 && u < units.length - 1); - const toast = new Whisper.FileSizeToast({ - model: { limit, units: units[u] }, - }); - toast.$el.insertAfter(this.$el); - toast.render(); - this.deleteFiles(); + try { + const blob = await this.autoScale(file); + let limitKb = 1000000; + const blobType = + file.type === 'image/gif' ? 'gif' : contentType.split('/')[0]; + + switch (blobType) { + case 'image': + limitKb = 6000; + break; + case 'gif': + limitKb = 25000; + break; + case 'audio': + limitKb = 100000; + break; + case 'video': + limitKb = 100000; + break; + default: + limitKb = 100000; + break; + } + if ((blob.size / 1024).toFixed(4) >= limitKb) { + const units = ['kB', 'MB', 'GB']; + let u = -1; + let limit = limitKb * 1000; + do { + limit /= 1000; + u += 1; + } while (limit >= 1000 && u < units.length - 1); + const toast = new Whisper.FileSizeToast({ + model: { limit, units: units[u] }, + }); + toast.$el.insertAfter(this.$el); + toast.render(); + this.deleteFiles(); + } + } catch (error) { + window.log.error( + 'Error ensuring that image is properly sized:', + error && error.message ? error.message : error + ); + + this.unableToLoadAttachment(); } },