diff --git a/js/modules/types/attachment.js b/js/modules/types/attachment.js index 95104d3e09..5202a6b5fd 100644 --- a/js/modules/types/attachment.js +++ b/js/modules/types/attachment.js @@ -1,4 +1,4 @@ -// Copyright 2018-2020 Signal Messenger, LLC +// Copyright 2018-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only const is = require('@sindresorhus/is'); @@ -217,6 +217,7 @@ exports.isImage = AttachmentTS.isImage; exports.isVideo = AttachmentTS.isVideo; exports.isAudio = AttachmentTS.isAudio; exports.isVoiceMessage = AttachmentTS.isVoiceMessage; +exports.getUploadSizeLimitKb = AttachmentTS.getUploadSizeLimitKb; exports.save = AttachmentTS.save; const THUMBNAIL_SIZE = 150; diff --git a/ts/test-node/types/Attachment_test.ts b/ts/test-node/types/Attachment_test.ts index 3724e6da40..8be1f8073b 100644 --- a/ts/test-node/types/Attachment_test.ts +++ b/ts/test-node/types/Attachment_test.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2020 Signal Messenger, LLC +// Copyright 2018-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import { assert } from 'chai'; @@ -9,6 +9,31 @@ import { SignalService } from '../../protobuf'; import { stringToArrayBuffer } from '../../../js/modules/string_to_array_buffer'; describe('Attachment', () => { + describe('getUploadSizeLimitKb', () => { + const { getUploadSizeLimitKb } = Attachment; + + it('returns 6000 kilobytes for supported non-GIF images', () => { + assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_JPEG), 6000); + assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_PNG), 6000); + assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_WEBP), 6000); + }); + + it('returns 25000 kilobytes for GIFs', () => { + assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_GIF), 25000); + }); + + it('returns 100000 for other file types', () => { + assert.strictEqual(getUploadSizeLimitKb(MIME.APPLICATION_JSON), 100000); + assert.strictEqual(getUploadSizeLimitKb(MIME.AUDIO_AAC), 100000); + assert.strictEqual(getUploadSizeLimitKb(MIME.AUDIO_MP3), 100000); + assert.strictEqual(getUploadSizeLimitKb(MIME.VIDEO_MP4), 100000); + assert.strictEqual( + getUploadSizeLimitKb('image/vnd.adobe.photoshop' as MIME.MIMEType), + 100000 + ); + }); + }); + describe('getFileExtension', () => { it('should return file extension from content type', () => { const input: Attachment.Attachment = { diff --git a/ts/test-node/types/MIME_test.ts b/ts/test-node/types/MIME_test.ts new file mode 100644 index 0000000000..c8f8fcd63b --- /dev/null +++ b/ts/test-node/types/MIME_test.ts @@ -0,0 +1,19 @@ +// Copyright 2021 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { assert } from 'chai'; + +import * as MIME from '../../types/MIME'; + +describe('MIME', () => { + describe('isGif', () => { + it('returns true for GIFs', () => { + assert.isTrue(MIME.isGif('image/gif')); + }); + + it('returns false for non-GIFs', () => { + assert.isFalse(MIME.isGif('image/jpeg')); + assert.isFalse(MIME.isGif('text/plain')); + }); + }); +}); diff --git a/ts/types/Attachment.ts b/ts/types/Attachment.ts index 3baef32611..e5e392d798 100644 --- a/ts/types/Attachment.ts +++ b/ts/types/Attachment.ts @@ -431,3 +431,13 @@ export const getFileExtension = ( return attachment.contentType.split('/')[1]; } }; + +export const getUploadSizeLimitKb = (contentType: MIME.MIMEType): number => { + if (MIME.isGif(contentType)) { + return 25000; + } + if (isImageTypeSupported(contentType)) { + return 6000; + } + return 100000; +}; diff --git a/ts/types/MIME.ts b/ts/types/MIME.ts index d07b1d4670..1513060c21 100644 --- a/ts/types/MIME.ts +++ b/ts/types/MIME.ts @@ -17,6 +17,8 @@ export const VIDEO_MP4 = 'video/mp4' as MIMEType; export const VIDEO_QUICKTIME = 'video/quicktime' as MIMEType; export const LONG_MESSAGE = 'text/x-signal-plain' as MIMEType; +export const isGif = (value: string): value is MIMEType => + value === 'image/gif'; export const isJPEG = (value: string): value is MIMEType => value === 'image/jpeg'; export const isImage = (value: string): value is MIMEType => diff --git a/ts/views/conversation_view.ts b/ts/views/conversation_view.ts index 24eb9eb062..1b2877a8ce 100644 --- a/ts/views/conversation_view.ts +++ b/ts/views/conversation_view.ts @@ -1695,29 +1695,9 @@ Whisper.ConversationView = Whisper.View.extend({ }, isSizeOkay(attachment: any) { - let limitKb = 1000000; - const type = - attachment.contentType === 'image/gif' - ? 'gif' - : attachment.contentType.split('/')[0]; - - switch (type) { - case 'image': - limitKb = 6000; - break; - case 'gif': - limitKb = 25000; - break; - case 'audio': - limitKb = 100000; - break; - case 'video': - limitKb = 100000; - break; - default: - limitKb = 100000; - break; - } + const limitKb = window.Signal.Types.Attachment.getUploadSizeLimitKb( + attachment.contentType + ); // this needs to be cast properly // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/ts/window.d.ts b/ts/window.d.ts index 1325cbd6b3..36993f7728 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -358,6 +358,8 @@ declare global { isImage: typeof Attachment.isImage; isVideo: typeof Attachment.isVideo; isAudio: typeof Attachment.isAudio; + + getUploadSizeLimitKb: typeof Attachment.getUploadSizeLimitKb; }; MIME: typeof MIME; Contact: typeof Contact;