diff --git a/js/models/conversations.js b/js/models/conversations.js index bb7239ffe..fc4dbd3b7 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -657,10 +657,13 @@ profileKey = storage.get('profileKey'); } + const loadData = Attachment.loadData(migrationContext.readAttachmentData); + const attachmentsWithData = + await Promise.all(messageWithSchema.attachments.map(loadData)); message.send(sendFunction( this.get('id'), body, - messageWithSchema.attachments, + attachmentsWithData, now, this.get('expireTimer'), profileKey diff --git a/js/modules/types/attachment.js b/js/modules/types/attachment.js index c1266d318..e3a125da7 100644 --- a/js/modules/types/attachment.js +++ b/js/modules/types/attachment.js @@ -1,3 +1,4 @@ +const isFunction = require('lodash/isFunction'); const isString = require('lodash/isString'); const MIME = require('./mime'); @@ -110,3 +111,34 @@ exports.removeSchemaVersion = (attachment) => { }; exports.migrateDataToFileSystem = migrateDataToFileSystem; + +// hasData :: Attachment -> Boolean +exports.hasData = attachment => + attachment.data instanceof ArrayBuffer || ArrayBuffer.isView(attachment.data); + +// loadData :: (RelativePath -> IO (Promise ArrayBuffer)) +// Attachment -> +// IO (Promise Attachment) +exports.loadData = (readAttachmentData) => { + if (!isFunction(readAttachmentData)) { + throw new TypeError('`readAttachmentData` must be a function'); + } + + return async (attachment) => { + if (!exports.isValid(attachment)) { + throw new TypeError('`attachment` is not valid'); + } + + const isAlreadyLoaded = exports.hasData(attachment); + if (isAlreadyLoaded) { + return attachment; + } + + if (!isString(attachment.path)) { + throw new TypeError('`attachment.path` is required'); + } + + const data = await readAttachmentData(attachment.path); + return Object.assign({}, attachment, { data }); + }; +};