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 @@ -4,11 +4,8 @@ import blobService from '../facts/blob-service.js'; import type { Shape } from '../types/core.js'; -import type { - UploadMediaMetadataRequest, - UploadMultimediaResult, - Dimensions, -} from '../types/media-types'; +import type { UploadMultimediaResult, Dimensions } from '../types/media-types'; +import { extractKeyserverIDFromID } from '../utils/action-utils.js'; import { toBase64URL } from '../utils/base64.js'; import { blobServiceUploadHandler, @@ -17,6 +14,8 @@ import { makeBlobServiceEndpointURL } from '../utils/blob-service.js'; import type { CallServerEndpoint } from '../utils/call-server-endpoint.js'; import { getMessageForException } from '../utils/errors.js'; +import { useKeyserverCall } from '../utils/keyserver-call.js'; +import type { CallKeyserverEndpoint } from '../utils/keyserver-call.js'; import { handleHTTPResponseError } from '../utils/services-utils.js'; import { type UploadBlob } from '../utils/upload-blob.js'; @@ -34,21 +33,6 @@ thumbHash: ?string, }>; -const uploadMediaMetadata = - ( - callServerEndpoint: CallServerEndpoint, - ): ((input: UploadMediaMetadataRequest) => Promise) => - async input => { - const response = await callServerEndpoint('upload_media_metadata', input); - return { - id: response.id, - uri: response.uri, - mediaType: response.mediaType, - dimensions: response.dimensions, - loop: response.loop, - }; - }; - const uploadMultimedia = ( callServerEndpoint: CallServerEndpoint, @@ -106,15 +90,29 @@ }; }; +export type DeleteUploadInput = { + +id: string, + +threadID: string, +}; + const updateMultimediaMessageMediaActionType = 'UPDATE_MULTIMEDIA_MESSAGE_MEDIA'; const deleteUpload = - (callServerEndpoint: CallServerEndpoint): ((id: string) => Promise) => - async id => { - await callServerEndpoint('delete_upload', { id }); + ( + callKeyserverEndpoint: CallKeyserverEndpoint, + ): ((input: DeleteUploadInput) => Promise) => + async input => { + const { id, threadID } = input; + const keyserverID = extractKeyserverIDFromID(threadID); + const requests = { [keyserverID]: { id } }; + await callKeyserverEndpoint('delete_upload', requests); }; +function useDeleteUpload(): (input: DeleteUploadInput) => Promise { + return useKeyserverCall(deleteUpload); +} + export type BlobServiceUploadFile = | { +type: 'file', +file: File } | { @@ -133,18 +131,20 @@ +loop?: boolean, }; -export type BlobServiceUploadAction = (args: { - +input: BlobServiceUploadInput, +export type BlobServiceUploadAction = (input: { + +uploadInput: BlobServiceUploadInput, + +threadID: string, +callbacks?: MultimediaUploadCallbacks, }) => Promise<{ ...UploadMultimediaResult, blobHolder: ?string }>; const blobServiceUpload = - (callServerEndpoint: CallServerEndpoint): BlobServiceUploadAction => - async args => { - const { input, callbacks } = args; - const { encryptionKey, loop, dimensions, thumbHash, blobInput } = input; + (callKeyserverEndpoint: CallKeyserverEndpoint): BlobServiceUploadAction => + async input => { + const { uploadInput, callbacks, threadID } = input; + const { encryptionKey, loop, dimensions, thumbHash, blobInput } = + uploadInput; const blobHolder = uuid.v4(); - const blobHash = toBase64URL(input.blobHash); + const blobHash = toBase64URL(uploadInput.blobHash); // 1. Assign new holder for blob with given blobHash let blobAlreadyExists: boolean; @@ -202,18 +202,26 @@ } // 3. Upload metadata to keyserver - const response = await callServerEndpoint('upload_media_metadata', { - blobHash, - blobHolder, - encryptionKey, - filename: - blobInput.type === 'file' ? blobInput.file.name : blobInput.filename, - mimeType: - blobInput.type === 'file' ? blobInput.file.type : blobInput.mimeType, - loop, - thumbHash, - ...dimensions, - }); + const keyserverID = extractKeyserverIDFromID(threadID); + const requests = { + [keyserverID]: { + blobHash, + blobHolder, + encryptionKey, + filename: + blobInput.type === 'file' ? blobInput.file.name : blobInput.filename, + mimeType: + blobInput.type === 'file' ? blobInput.file.type : blobInput.mimeType, + loop, + thumbHash, + ...dimensions, + }, + }; + const responses = await callKeyserverEndpoint( + 'upload_media_metadata', + requests, + ); + const response = responses[keyserverID]; return { id: response.id, @@ -225,10 +233,13 @@ }; }; +function useBlobServiceUpload(): BlobServiceUploadAction { + return useKeyserverCall(blobServiceUpload); +} + export { uploadMultimedia, - blobServiceUpload, - uploadMediaMetadata, + useBlobServiceUpload, updateMultimediaMessageMediaActionType, - deleteUpload, + useDeleteUpload, }; 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 @@ -22,9 +22,8 @@ import { useNewThread } from 'lib/actions/thread-actions.js'; import { uploadMultimedia, - uploadMediaMetadata, updateMultimediaMessageMediaActionType, - blobServiceUpload, + useBlobServiceUpload, type MultimediaUploadCallbacks, type MultimediaUploadExtras, type BlobServiceUploadAction, @@ -60,7 +59,6 @@ NativeMediaSelection, MediaMissionResult, MediaMission, - UploadMediaMetadataRequest, } from 'lib/types/media-types.js'; import { messageTypes } from 'lib/types/message-types-enum.js'; import { @@ -145,9 +143,6 @@ extras: MultimediaUploadExtras, callbacks: MultimediaUploadCallbacks, ) => Promise, - +uploadMediaMetadata: ( - input: UploadMediaMetadataRequest, - ) => Promise, +blobServiceUpload: BlobServiceUploadAction, +sendMultimediaMessage: ( input: SendMultimediaMessageInput, @@ -827,7 +822,7 @@ ) { uploadPromises.push( this.props.blobServiceUpload({ - input: { + uploadInput: { blobInput: { type: 'uri', uri: uploadURI, @@ -842,6 +837,7 @@ ? processedMedia.thumbHash : null, }, + threadID: threadInfo.id, callbacks: { blobServiceUploadHandler, onProgress: (percent: number) => { @@ -859,7 +855,7 @@ if (processedMedia.mediaType === 'encrypted_video') { uploadPromises.push( this.props.blobServiceUpload({ - input: { + uploadInput: { blobInput: { type: 'uri', uri: processedMedia.uploadThumbnailURI, @@ -872,6 +868,7 @@ dimensions: processedMedia.dimensions, thumbHash: processedMedia.thumbHash, }, + threadID: threadInfo.id, callbacks: { blobServiceUploadHandler, }, @@ -1693,8 +1690,7 @@ const hasWiFi = useSelector(state => state.connectivity.hasWiFi); const calendarQuery = useCalendarQuery(); const callUploadMultimedia = useServerCall(uploadMultimedia); - const callUploadMediaMetadata = useServerCall(uploadMediaMetadata); - const callBlobServiceUpload = useServerCall(blobServiceUpload); + const callBlobServiceUpload = useBlobServiceUpload(); const callSendMultimediaMessage = useSendMultimediaMessage(); const callSendTextMessage = useSendTextMessage(); const callNewThread = useNewThread(); @@ -1708,7 +1704,6 @@ return ( Promise, +blobServiceUpload: BlobServiceUploadAction, - +uploadMediaMetadata: ( - input: UploadMediaMetadataRequest, - ) => Promise, - +deleteUpload: (id: string) => Promise, + +deleteUpload: (input: DeleteUploadInput) => Promise, +sendMultimediaMessage: ( input: LegacySendMultimediaMessageInput, ) => Promise, @@ -877,7 +873,7 @@ 'incomplete encrypted upload', ); uploadResult = await this.props.blobServiceUpload({ - input: { + uploadInput: { blobInput: { type: 'file', file: upload.file, @@ -888,6 +884,7 @@ loop: false, thumbHash, }, + threadID, callbacks, }); } else { @@ -1165,7 +1162,7 @@ abortRequest = pendingUpload.abort; } if (pendingUpload.serverID) { - this.props.deleteUpload(pendingUpload.serverID); + this.props.deleteUpload({ id: pendingUpload.serverID, threadID }); if (isBlobServiceURI(pendingUpload.uri)) { invariant( pendingUpload.blobHolder, @@ -1611,9 +1608,8 @@ ); const calendarQuery = useSelector(nonThreadCalendarQuery); const callUploadMultimedia = useServerCall(uploadMultimedia); - const callBlobServiceUpload = useServerCall(blobServiceUpload); - const callUploadMediaMetadata = useServerCall(uploadMediaMetadata); - const callDeleteUpload = useServerCall(deleteUpload); + const callBlobServiceUpload = useBlobServiceUpload(); + const callDeleteUpload = useDeleteUpload(); const callSendMultimediaMessage = useLegacySendMultimediaMessage(); const callSendTextMessage = useSendTextMessage(); const callNewThread = useNewThread(); @@ -1648,7 +1644,6 @@ pendingRealizedThreadIDs={pendingToRealizedThreadIDs} calendarQuery={calendarQuery} uploadMultimedia={callUploadMultimedia} - uploadMediaMetadata={callUploadMediaMetadata} blobServiceUpload={callBlobServiceUpload} deleteUpload={callDeleteUpload} sendMultimediaMessage={callSendMultimediaMessage}