diff --git a/keyserver/src/creators/upload-creator.js b/keyserver/src/creators/upload-creator.js --- a/keyserver/src/creators/upload-creator.js +++ b/keyserver/src/creators/upload-creator.js @@ -22,6 +22,7 @@ buffer: Buffer, dimensions: Dimensions, loop: boolean, + thread: string, }; async function createUploads( viewer: Viewer, @@ -35,10 +36,11 @@ const uploadRows = uploadInfos.map(uploadInfo => { const id = ids.shift(); const secret = crypto.randomBytes(8).toString('hex'); - const { dimensions, mediaType, loop } = uploadInfo; + const { dimensions, mediaType, loop, thread } = uploadInfo; return { uploadResult: { id, + thread, uri: shimUploadURI(getUploadURL(id, secret), viewer.platformDetails), dimensions, mediaType, @@ -46,6 +48,7 @@ }, insert: [ id, + thread, viewer.userID, mediaType, uploadInfo.name, @@ -59,7 +62,7 @@ }); const insertQuery = SQL` - INSERT INTO uploads(id, uploader, type, filename, + INSERT INTO uploads(id, thread, uploader, type, filename, mime, content, secret, creation_time, extra) VALUES ${uploadRows.map(({ insert }) => insert)} `; diff --git a/keyserver/src/uploads/media-utils.js b/keyserver/src/uploads/media-utils.js --- a/keyserver/src/uploads/media-utils.js +++ b/keyserver/src/uploads/media-utils.js @@ -35,6 +35,7 @@ inputDimensions: ?Dimensions, inputLoop: boolean, size: number, // in bytes + thread: string, ): Promise { const { mime, mediaType } = deepFileInfoFromData(initialBuffer); if (!mime || !mediaType) { @@ -57,6 +58,7 @@ buffer: initialBuffer, dimensions: inputDimensions, loop: inputLoop, + thread: thread, }; } @@ -72,6 +74,7 @@ inputDimensions, inputLoop, size, + thread, ); } @@ -82,6 +85,7 @@ inputDimensions: ?Dimensions, inputLoop: boolean, size: number, + thread: string, ): Promise { let sharpImage, metadata; try { @@ -116,6 +120,7 @@ buffer: initialBuffer, dimensions: initialDimensions, loop: inputLoop, + thread, }; } console.log(`processing image with ${JSON.stringify(plan)}`); @@ -168,6 +173,7 @@ buffer: convertedBuffer, dimensions: convertedDimensions, loop: inputLoop, + thread, }; } diff --git a/keyserver/src/uploads/uploads.js b/keyserver/src/uploads/uploads.js --- a/keyserver/src/uploads/uploads.js +++ b/keyserver/src/uploads/uploads.js @@ -57,6 +57,11 @@ const inputLoop = !!(files.length === 1 && body.loop); + let thread; + if (files.length === 1 && typeof body.thread === 'string') { + thread = body.thread; + } + const validationResults = await Promise.all( files.map(({ buffer, size, originalname }) => validateAndConvert( @@ -65,6 +70,7 @@ inputDimensions, inputLoop, size, + thread, ), ), ); diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js --- a/lib/actions/upload-actions.js +++ b/lib/actions/upload-actions.js @@ -10,7 +10,11 @@ abortHandler: (abort: () => void) => void, uploadBlob: UploadBlob, }>; -export type MultimediaUploadExtras = Shape<{ ...Dimensions, loop: boolean }>; +export type MultimediaUploadExtras = Shape<{ + thread: string, + ...Dimensions, + loop: boolean, +}>; const uploadMultimedia = ( callServerEndpoint: CallServerEndpoint, @@ -28,6 +32,9 @@ const uploadBlob = callbacks && callbacks.uploadBlob; const stringExtras = {}; + if (extras.thread !== null && extras.thread !== undefined) { + stringExtras.thread = extras.thread.toString(); + } if (extras.height !== null && extras.height !== undefined) { stringExtras.height = extras.height.toString(); } @@ -57,6 +64,7 @@ dimensions: uploadResult.dimensions, mediaType: uploadResult.mediaType, loop: uploadResult.loop, + thread: uploadResult.thread, }; }; diff --git a/lib/types/media-types.js b/lib/types/media-types.js --- a/lib/types/media-types.js +++ b/lib/types/media-types.js @@ -65,6 +65,7 @@ +dimensions: Dimensions, +mediaType: MediaType, +loop: boolean, + +thread: string, }; export type UpdateMultimediaMessageMediaPayload = { diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js --- a/native/input/input-state-container.react.js +++ b/native/input/input-state-container.react.js @@ -569,16 +569,17 @@ }, ); - await this.uploadFiles(localMessageID, uploadFileInputs); + await this.uploadFiles(localMessageID, threadInfo.id, uploadFileInputs); }; async uploadFiles( localMessageID: string, + threadID: string, uploadFileInputs: $ReadOnlyArray, ) { const results = await Promise.all( uploadFileInputs.map(uploadFileInput => - this.uploadFile(localMessageID, uploadFileInput), + this.uploadFile(localMessageID, threadID, uploadFileInput), ), ); const errors = [...new Set(results.filter(Boolean))]; @@ -589,6 +590,7 @@ async uploadFile( localMessageID: string, + threadID: string, uploadFileInput: UploadFileInput, ): Promise { const { ids, selection } = uploadFileInput; @@ -665,6 +667,7 @@ this.props.uploadMultimedia( { uri: uploadURI, name: filename, type: mime }, { + thread: threadID, ...processedMedia.dimensions, loop: processedMedia.mediaType === 'video' @@ -693,6 +696,7 @@ type: 'image/jpeg', }, { + thread: threadID, ...processedMedia.dimensions, loop: false, }, @@ -1266,7 +1270,7 @@ }; }); - await this.uploadFiles(localMessageID, uploadFileInputs); + await this.uploadFiles(localMessageID, threadInfo.id, uploadFileInputs); }; retryMessage = async (localMessageID: string, threadInfo: ThreadInfo) => {