From 4ce0472b9ff092235c5a6617de0922cb4373f150 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Sat, 14 Apr 2018 20:09:52 -0400 Subject: [PATCH] Extract `Message.loadWithObjectURL` --- js/views/conversation_view.js | 29 +++-------- preload.js | 6 +++ ts/backbone/Conversation.ts | 2 +- .../media-gallery/propTypes/Message.tsx | 52 +++++++++++++++---- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 960afe54f..040a0d437 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -583,27 +583,14 @@ // - [ ] Fetch file attachments // - [ ] Add mechanism to fetch more data - const mediaWithoutAttachmentData = - await Signal.Backbone.Conversation.fetchVisualMediaAttachments({ - conversationId: this.model.get('id'), - WhisperMessageCollection: Whisper.MessageCollection, - }); - - const mediaWithAttachmentData = - await Promise.all(mediaWithoutAttachmentData.map(Signal.Migrations.loadMessage)); - - const withObjectURL = message => { - if (!message.attachments || message.attachments.length === 0) { - throw new TypeError('`message.attachments` cannot be empty'); - } - const attachment = message.attachments[0]; - const objectURL = Signal.Util.arrayBufferToObjectURL({ - data: attachment.data, - type: attachment.contentType, - }); - return Object.assign({}, message, {objectURL}); - } - const mediaWithObjectURLs = mediaWithAttachmentData.map(withObjectURL); + const media = await Signal.Backbone.Conversation.fetchVisualMediaAttachments({ + conversationId: this.model.get('id'), + WhisperMessageCollection: Whisper.MessageCollection, + }); + const loadMessages = Signal.Components.PropTypes.Message.loadWithObjectURL( + Signal.Migrations.loadMessage + ); + const mediaWithObjectURLs = await loadMessages(media); const props = { media: mediaWithObjectURLs, diff --git a/preload.js b/preload.js index e47f0dc39..8b6eaa2a3 100644 --- a/preload.js +++ b/preload.js @@ -166,8 +166,14 @@ const { MediaGallery } = require('./ts/components/conversation/media-gallery/MediaGallery'); const { Quote } = require('./ts/components/conversation/Quote'); +const PropTypesMessage = + require('./ts/components/conversation/media-gallery/propTypes/Message'); + window.Signal.Components = { MediaGallery, + PropTypes: { + Message: PropTypesMessage, + }, Quote, }; diff --git a/ts/backbone/Conversation.ts b/ts/backbone/Conversation.ts index 2d652029a..f687d72fd 100644 --- a/ts/backbone/Conversation.ts +++ b/ts/backbone/Conversation.ts @@ -3,8 +3,8 @@ */ import is from '@sindresorhus/is'; -import { deferredToPromise } from '../../js/modules/deferred_to_promise'; import { Collection as BackboneCollection } from '../types/backbone/Collection'; +import { deferredToPromise } from '../../js/modules/deferred_to_promise'; import { Message } from '../types/Message'; export const fetchVisualMediaAttachments = async ({ diff --git a/ts/components/conversation/media-gallery/propTypes/Message.tsx b/ts/components/conversation/media-gallery/propTypes/Message.tsx index c86a7e29f..b37b1cba3 100644 --- a/ts/components/conversation/media-gallery/propTypes/Message.tsx +++ b/ts/components/conversation/media-gallery/propTypes/Message.tsx @@ -1,15 +1,45 @@ /** * @prettier */ -export interface Message { - body?: string; +import is from '@sindresorhus/is'; + +import { arrayBufferToObjectURL } from '../../../../util/arrayBufferToObjectURL'; +import { Attachment } from '../../../../types/Attachment'; +import { MapAsync } from '../../../../types/MapAsync'; +import { MIMEType } from '../../../../types/MIME'; + +export type Message = { + attachments: Array; received_at: number; - attachments: Array<{ - data?: ArrayBuffer; - fileName?: string; - size?: number; - }>; - - // TODO: Revisit - objectURL?: string; -} +} & { objectURL?: string }; + +const DEFAULT_CONTENT_TYPE: MIMEType = 'application/octet-stream' as MIMEType; + +export const loadWithObjectURL = (loadMessage: MapAsync) => async ( + media: Array +): Promise> => { + if (!is.function_(loadMessage)) { + throw new TypeError("'loadMessage' must be a function"); + } + if (!is.array(media)) { + throw new TypeError("'media' must be a function"); + } + + const mediaWithAttachmentData = await Promise.all(media.map(loadMessage)); + return mediaWithAttachmentData.map(withObjectURL); +}; + +const withObjectURL = (message: Message): Message => { + if (message.attachments.length === 0) { + throw new TypeError('`message.attachments` cannot be empty'); + } + const attachment = message.attachments[0]; + const objectURL = arrayBufferToObjectURL({ + data: attachment.data, + type: attachment.contentType || DEFAULT_CONTENT_TYPE, + }); + return { + ...message, + objectURL, + }; +};