diff --git a/native/avatars/avatar-hooks.js b/native/avatars/avatar-hooks.js --- a/native/avatars/avatar-hooks.js +++ b/native/avatars/avatar-hooks.js @@ -8,13 +8,9 @@ import filesystem from 'react-native-fs'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { - uploadMultimedia, - useBlobServiceUpload, -} from 'lib/actions/upload-actions.js'; +import { useBlobServiceUpload } from 'lib/actions/upload-actions.js'; import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js'; import { EditUserAvatarContext } from 'lib/components/edit-user-avatar-provider.react.js'; -import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; import { extensionFromFilename, filenameFromPathOrURI, @@ -44,8 +40,6 @@ import blobServiceUploadHandler from '../utils/blob-service-upload.js'; import { useStaffCanSee } from '../utils/staff-utils.js'; -const useBlobServiceUploads = true; - function displayAvatarUpdateFailureAlert(): void { Alert.alert( 'Couldn’t save avatar', @@ -59,28 +53,9 @@ media: MediaResult, metadataUploadLocation: 'keyserver' | 'none', ) => Promise { - const callUploadMultimedia = useLegacyAshoatKeyserverCall(uploadMultimedia); const callBlobServiceUpload = useBlobServiceUpload(); return React.useCallback( async (processedMedia, metadataUploadLocation) => { - const useBlobService = - metadataUploadLocation !== 'keyserver' || useBlobServiceUploads; - if (!useBlobService) { - const { uploadURI, filename, mime, dimensions } = processedMedia; - const { id } = await callUploadMultimedia( - { - uri: uploadURI, - name: filename, - type: mime, - }, - dimensions, - ); - if (!id) { - return undefined; - } - return { type: 'image', uploadID: id }; - } - const { result: encryptionResult } = await encryptMedia(processedMedia); if (!encryptionResult.success) { throw new Error('Avatar media encryption failed.'); @@ -132,7 +107,7 @@ } return { type: 'encrypted_image', uploadID: id }; }, - [callUploadMultimedia, callBlobServiceUpload], + [callBlobServiceUpload], ); } 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 @@ -16,10 +16,7 @@ import { type BlobServiceUploadAction, type BlobServiceUploadResult, - type MultimediaUploadCallbacks, - type MultimediaUploadExtras, updateMultimediaMessageMediaActionType, - uploadMultimedia, useBlobServiceUpload, } from 'lib/actions/upload-actions.js'; import { @@ -32,7 +29,6 @@ CallSingleKeyserverEndpointOptions, CallSingleKeyserverEndpointResponse, } from 'lib/keyserver-conn/call-single-keyserver-endpoint.js'; -import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; import { pathFromURI, replaceExtension } from 'lib/media/file-utils.js'; import { getNextLocalUploadID, @@ -62,7 +58,6 @@ MediaMissionResult, MediaMissionStep, NativeMediaSelection, - UploadMultimediaResult, } from 'lib/types/media-types.js'; import { messageTypes } from 'lib/types/message-types-enum.js'; import { @@ -146,11 +141,6 @@ +dispatch: Dispatch, +staffCanSee: boolean, +dispatchActionPromise: DispatchActionPromise, - +uploadMultimedia: ( - multimedia: Object, - extras: MultimediaUploadExtras, - callbacks: MultimediaUploadCallbacks, - ) => Promise, +blobServiceUpload: BlobServiceUploadAction, +sendMultimediaMessage: ( messageInfo: RawMultimediaMessageInfo, @@ -192,8 +182,6 @@ > = new Map(); pendingThreadUpdateHandlers: Map mixed> = new Map(); - useBlobServiceUploads = true; - // When the user sends a multimedia message that triggers the creation of a // sidebar, the sidebar gets created right away, but the message needs to wait // for the uploads to complete before sending. We use this Set to track the @@ -629,11 +617,6 @@ } } - // eslint-disable-next-line no-unused-vars - shouldEncryptMedia(threadInfo: ThreadInfo): boolean { - return true; - } - sendMultimediaMessage = async ( selections: $ReadOnlyArray, threadInfo: ThreadInfo, @@ -722,7 +705,7 @@ creatorID, media, }, - { forceMultimediaMessageType: this.shouldEncryptMedia(threadInfo) }, + { forceMultimediaMessageType: true }, ); this.props.dispatch({ type: createLocalMessageActionType, @@ -825,29 +808,27 @@ }); } - if (this.shouldEncryptMedia(threadInfo)) { - const encryptionStart = Date.now(); - try { - const { result: encryptionResult, ...encryptionReturn } = - await encryptMedia(processedMedia); - encryptionSteps = encryptionReturn.steps; - if (!encryptionResult.success) { - onUploadFailed(encryptionResult.reason); - return await onUploadFinished(encryptionResult); - } - if (encryptionResult.shouldDisposePath) { - filesToDispose.push(encryptionResult.shouldDisposePath); - } - processedMedia = encryptionResult; - } catch (e) { - onUploadFailed('encryption failed'); - return await onUploadFinished({ - success: false, - reason: 'encryption_exception', - time: Date.now() - encryptionStart, - exceptionMessage: getMessageForException(e), - }); + const encryptionStart = Date.now(); + try { + const { result: encryptionResult, ...encryptionReturn } = + await encryptMedia(processedMedia); + encryptionSteps = encryptionReturn.steps; + if (!encryptionResult.success) { + onUploadFailed(encryptionResult.reason); + return await onUploadFinished(encryptionResult); + } + if (encryptionResult.shouldDisposePath) { + filesToDispose.push(encryptionResult.shouldDisposePath); } + processedMedia = encryptionResult; + } catch (e) { + onUploadFailed('encryption failed'); + return await onUploadFinished({ + success: false, + reason: 'encryption_exception', + time: Date.now() - encryptionStart, + exceptionMessage: getMessageForException(e), + }); } const { uploadURI, filename, mime } = processedMedia; @@ -861,136 +842,76 @@ mediaMissionResult; const isThickThread = threadTypeIsThick(threadInfo.type); - const useBlobService = isThickThread || this.useBlobServiceUploads; try { - if ( - useBlobService && - (processedMedia.mediaType === 'encrypted_photo' || - processedMedia.mediaType === 'encrypted_video') - ) { - const uploadMetadataToKeyserver = !isThickThread; - const uploadPromise = this.props.blobServiceUpload({ - uploadInput: { - blobInput: { - type: 'uri', - uri: uploadURI, - filename: filename, - mimeType: mime, - }, - blobHash: processedMedia.blobHash, - encryptionKey: processedMedia.encryptionKey, - dimensions: processedMedia.dimensions, - thumbHash: - processedMedia.mediaType === 'encrypted_photo' - ? processedMedia.thumbHash - : null, - }, - keyserverOrThreadID: uploadMetadataToKeyserver ? threadInfo.id : null, - callbacks: { - blobServiceUploadHandler, - onProgress: (percent: number) => { - this.setProgress( - localMessageID, - localMediaID, - 'uploading', - percent, - ); - }, - }, - }); - - const uploadThumbnailPromise: Promise = - (async () => { - if (processedMedia.mediaType !== 'encrypted_video') { - return undefined; - } - return await this.props.blobServiceUpload({ - uploadInput: { - blobInput: { - type: 'uri', - uri: processedMedia.uploadThumbnailURI, - filename: replaceExtension(`thumb${filename}`, 'jpg'), - mimeType: 'image/jpeg', - }, - blobHash: processedMedia.thumbnailBlobHash, - encryptionKey: processedMedia.thumbnailEncryptionKey, - loop: false, - dimensions: processedMedia.dimensions, - thumbHash: processedMedia.thumbHash, - }, - keyserverOrThreadID: uploadMetadataToKeyserver - ? threadInfo.id - : null, - callbacks: { - blobServiceUploadHandler, - }, - }); - })(); - - [uploadResult, uploadThumbnailResult] = await Promise.all([ - uploadPromise, - uploadThumbnailPromise, - ]); - } else { - const uploadPromise = this.props.uploadMultimedia( - { uri: uploadURI, name: filename, type: mime }, - { - ...processedMedia.dimensions, - loop: - processedMedia.mediaType === 'video' || - processedMedia.mediaType === 'encrypted_video' - ? processedMedia.loop - : undefined, - encryptionKey: processedMedia.encryptionKey, - thumbHash: - processedMedia.mediaType === 'photo' || - processedMedia.mediaType === 'encrypted_photo' - ? processedMedia.thumbHash - : null, + invariant( + processedMedia.mediaType === 'encrypted_photo' || + processedMedia.mediaType === 'encrypted_video', + 'uploaded media should be encrypted', + ); + const uploadMetadataToKeyserver = !isThickThread; + const uploadPromise = this.props.blobServiceUpload({ + uploadInput: { + blobInput: { + type: 'uri', + uri: uploadURI, + filename: filename, + mimeType: mime, }, - { - onProgress: (percent: number) => - this.setProgress( - localMessageID, - localMediaID, - 'uploading', - percent, - ), - performHTTPMultipartUpload: this.performHTTPMultipartUpload, + blobHash: processedMedia.blobHash, + encryptionKey: processedMedia.encryptionKey, + dimensions: processedMedia.dimensions, + thumbHash: + processedMedia.mediaType === 'encrypted_photo' + ? processedMedia.thumbHash + : null, + }, + keyserverOrThreadID: uploadMetadataToKeyserver ? threadInfo.id : null, + callbacks: { + blobServiceUploadHandler, + onProgress: (percent: number) => { + this.setProgress( + localMessageID, + localMediaID, + 'uploading', + percent, + ); }, - ); + }, + }); - const uploadThumbnailPromise: Promise = - (async () => { - if ( - processedMedia.mediaType !== 'video' && - processedMedia.mediaType !== 'encrypted_video' - ) { - return undefined; - } - return await this.props.uploadMultimedia( - { + const uploadThumbnailPromise: Promise = + (async () => { + if (processedMedia.mediaType !== 'encrypted_video') { + return undefined; + } + return await this.props.blobServiceUpload({ + uploadInput: { + blobInput: { + type: 'uri', uri: processedMedia.uploadThumbnailURI, - name: replaceExtension(`thumb${filename}`, 'jpg'), - type: 'image/jpeg', - }, - { - ...processedMedia.dimensions, - loop: false, - encryptionKey: processedMedia.thumbnailEncryptionKey, - thumbHash: processedMedia.thumbHash, + filename: replaceExtension(`thumb${filename}`, 'jpg'), + mimeType: 'image/jpeg', }, - { - performHTTPMultipartUpload: this.performHTTPMultipartUpload, - }, - ); - })(); + blobHash: processedMedia.thumbnailBlobHash, + encryptionKey: processedMedia.thumbnailEncryptionKey, + loop: false, + dimensions: processedMedia.dimensions, + thumbHash: processedMedia.thumbHash, + }, + keyserverOrThreadID: uploadMetadataToKeyserver + ? threadInfo.id + : null, + callbacks: { + blobServiceUploadHandler, + }, + }); + })(); + + [uploadResult, uploadThumbnailResult] = await Promise.all([ + uploadPromise, + uploadThumbnailPromise, + ]); - [uploadResult, uploadThumbnailResult] = await Promise.all([ - uploadPromise, - uploadThumbnailPromise, - ]); - } mediaMissionResult = { success: true }; } catch (e) { uploadExceptionMessage = getMessageForException(e); @@ -1776,7 +1697,6 @@ ); const hasWiFi = useSelector(state => state.connectivity.hasWiFi); const calendarQuery = useCalendarQuery(); - const callUploadMultimedia = useLegacyAshoatKeyserverCall(uploadMultimedia); const callBlobServiceUpload = useBlobServiceUpload(); const callSendMultimediaMessage = useInputStateContainerSendMultimediaMessage(); @@ -1799,7 +1719,6 @@ hasWiFi={hasWiFi} mediaReportsEnabled={mediaReportsEnabled} calendarQuery={calendarQuery} - uploadMultimedia={callUploadMultimedia} blobServiceUpload={callBlobServiceUpload} sendMultimediaMessage={callSendMultimediaMessage} sendTextMessage={callSendTextMessage} diff --git a/web/avatars/avatar-hooks.react.js b/web/avatars/avatar-hooks.react.js --- a/web/avatars/avatar-hooks.react.js +++ b/web/avatars/avatar-hooks.react.js @@ -2,11 +2,7 @@ import * as React from 'react'; -import { - uploadMultimedia, - useBlobServiceUpload, -} from 'lib/actions/upload-actions.js'; -import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; +import { useBlobServiceUpload } from 'lib/actions/upload-actions.js'; import type { UpdateUserAvatarRequest } from 'lib/types/avatar-types.js'; import { authoritativeKeyserverID } from '../authoritative-keyserver.js'; @@ -14,8 +10,6 @@ import { generateThumbHash } from '../media/image-utils.js'; import { validateFile } from '../media/media-utils.js'; -const useBlobServiceUploads = true; - type AvatarMediaUploadOptions = { +uploadMetadataToKeyserver?: boolean, }; @@ -25,7 +19,6 @@ ): File => Promise { const { uploadMetadataToKeyserver = true } = options; - const callUploadMultimedia = useLegacyAshoatKeyserverCall(uploadMultimedia); const callBlobServiceUpload = useBlobServiceUpload(); const uploadAvatarMedia = React.useCallback( async (file: File): Promise => { @@ -35,16 +28,6 @@ throw new Error('Avatar media validation failed.'); } const { file: fixedFile, dimensions } = result; - const uploadExtras = { - ...dimensions, - loop: false, - }; - const useBlobService = - !uploadMetadataToKeyserver || useBlobServiceUploads; - if (!useBlobService) { - const { id } = await callUploadMultimedia(fixedFile, uploadExtras); - return { type: 'image', uploadID: id }; - } const encryptionResponse = await encryptFile(fixedFile); const { result: encryptionResult } = encryptionResponse; @@ -94,7 +77,7 @@ encryptionKey, }; }, - [callBlobServiceUpload, callUploadMultimedia, uploadMetadataToKeyserver], + [callBlobServiceUpload, uploadMetadataToKeyserver], ); return uploadAvatarMedia; } diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js --- a/web/input/input-state-container.react.js +++ b/web/input/input-state-container.react.js @@ -20,10 +20,7 @@ import { type BlobServiceUploadAction, type DeleteUploadInput, - type MultimediaUploadCallbacks, - type MultimediaUploadExtras, updateMultimediaMessageMediaActionType, - uploadMultimedia, useBlobServiceUpload, useDeleteUpload, } from 'lib/actions/upload-actions.js'; @@ -38,7 +35,6 @@ useInputStateContainerSendTextMessage, } from 'lib/hooks/input-state-container-hooks.js'; import { useNewThickThread } from 'lib/hooks/thread-hooks.js'; -import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; import { getNextLocalUploadID } from 'lib/media/media-utils.js'; import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors.js'; import { IdentityClientContext } from 'lib/shared/identity-client-context.js'; @@ -63,7 +59,6 @@ MediaMissionFailure, MediaMissionResult, MediaMissionStep, - UploadMultimediaResult, } from 'lib/types/media-types.js'; import { messageTypes } from 'lib/types/message-types-enum.js'; import { @@ -140,11 +135,6 @@ +dispatch: Dispatch, +dispatchActionPromise: DispatchActionPromise, +calendarQuery: () => CalendarQuery, - +uploadMultimedia: ( - multimedia: Object, - extras: MultimediaUploadExtras, - callbacks: MultimediaUploadCallbacks, - ) => Promise, +blobServiceUpload: BlobServiceUploadAction, +deleteUpload: (input: DeleteUploadInput) => Promise, +sendMultimediaMessage: ( @@ -213,8 +203,6 @@ }>, >(); - useBlobServiceUploads = true; - // When the user sends a multimedia message that triggers the creation of a // sidebar, the sidebar gets created right away, but the message needs to wait // for the uploads to complete before sending. We use this Set to track the @@ -311,7 +299,6 @@ string, { +threadID: string, - +shouldEncrypt: boolean, +uploads: PendingMultimediaUpload[], }, >(); @@ -327,26 +314,18 @@ ) { continue; } - const { shouldEncrypt } = upload; let assignedUploads = newlyAssignedUploads.get(messageID); if (!assignedUploads) { - assignedUploads = { threadID, shouldEncrypt, uploads: [] }; + assignedUploads = { threadID, uploads: [] }; newlyAssignedUploads.set(messageID, assignedUploads); } - if (shouldEncrypt !== assignedUploads.shouldEncrypt) { - console.warn( - `skipping upload ${localUploadID} ` + - "because shouldEncrypt doesn't match", - ); - continue; - } assignedUploads.uploads.push(upload); } } const newMessageInfos = new Map(); for (const [messageID, assignedUploads] of newlyAssignedUploads) { - const { uploads, threadID, shouldEncrypt } = assignedUploads; + const { uploads, threadID } = assignedUploads; const creatorID = this.props.viewerID; invariant(creatorID, 'need viewer ID in order to send a message'); const media = uploads.map( @@ -401,7 +380,7 @@ creatorID, media, }, - { forceMultimediaMessageType: shouldEncrypt }, + { forceMultimediaMessageType: true }, ); newMessageInfos.set(messageID, messageInfo); } @@ -445,11 +424,6 @@ return rawMessageInfo; } - // eslint-disable-next-line no-unused-vars - shouldEncryptMedia(threadInfo: ThreadInfo): boolean { - return true; - } - async sendMultimediaMessage( messageInfo: RawMultimediaMessageInfo, ): Promise { @@ -817,29 +791,26 @@ } const { uri, file: fixedFile, mediaType, dimensions } = result; - const shouldEncrypt = this.shouldEncryptMedia(threadInfo); - - let encryptionResult; - if (shouldEncrypt) { - let encryptionResponse; - const encryptionStart = Date.now(); - try { - encryptionResponse = await encryptFile(fixedFile); - } catch (e) { - return { - steps, - result: { - success: false, - reason: 'encryption_exception', - time: Date.now() - encryptionStart, - exceptionMessage: getMessageForException(e), - }, - }; - } - steps.push(...encryptionResponse.steps); - encryptionResult = encryptionResponse.result; + let encryptionResponse; + const encryptionStart = Date.now(); + try { + encryptionResponse = await encryptFile(fixedFile); + } catch (e) { + return { + steps, + result: { + success: false, + reason: 'encryption_exception', + time: Date.now() - encryptionStart, + exceptionMessage: getMessageForException(e), + }, + }; } - if (encryptionResult && !encryptionResult.success) { + const { result: encryptionResult, steps: encryptionSteps } = + encryptionResponse; + steps.push(...encryptionSteps); + + if (!encryptionResult.success) { return { steps, result: encryptionResult }; } @@ -874,7 +845,6 @@ abort: null, steps, selectTime, - shouldEncrypt, }, }, }; @@ -934,48 +904,32 @@ abortHandler: (abort: () => void) => this.handleAbortCallback(threadID, localID, abort), }; - const useBlobService = isThickThread || this.useBlobServiceUploads; - if ( - useBlobService && - (upload.mediaType === 'encrypted_photo' || - upload.mediaType === 'encrypted_video') - ) { - const { blobHash, dimensions, thumbHash } = upload; - invariant( - encryptionKey && blobHash && dimensions, - 'incomplete encrypted upload', - ); - uploadResult = await this.props.blobServiceUpload({ - uploadInput: { - blobInput: { - type: 'file', - file: upload.file, - }, - blobHash, - encryptionKey, - dimensions, - loop: false, - thumbHash, + const { mediaType, blobHash, dimensions, thumbHash } = upload; + invariant( + mediaType === 'encrypted_photo' || mediaType === 'encrypted_video', + 'uploaded media should be encrypted', + ); + invariant( + encryptionKey && blobHash && dimensions, + 'incomplete encrypted upload', + ); + + uploadResult = await this.props.blobServiceUpload({ + uploadInput: { + blobInput: { + type: 'file', + file: upload.file, }, - keyserverOrThreadID: isThickThread ? null : threadID, - callbacks, - }); - } else { - let uploadExtras = { - ...upload.dimensions, + blobHash, + encryptionKey, + dimensions, loop: false, - thumbHash: upload.thumbHash, - }; - if (encryptionKey) { - uploadExtras = { ...uploadExtras, encryptionKey }; - } - uploadResult = await this.props.uploadMultimedia( - upload.file, - uploadExtras, - callbacks, - ); - } + thumbHash, + }, + keyserverOrThreadID: isThickThread ? null : threadID, + callbacks, + }); } catch (e) { uploadExceptionMessage = getMessageForException(e); this.handleUploadFailure(threadID, localID); @@ -1711,7 +1665,6 @@ pendingToRealizedThreadIDsSelector(state.threadStore.threadInfos), ); const calendarQuery = useSelector(nonThreadCalendarQuery); - const callUploadMultimedia = useLegacyAshoatKeyserverCall(uploadMultimedia); const callBlobServiceUpload = useBlobServiceUpload(); const callDeleteUpload = useDeleteUpload(); const callSendMultimediaMessage = @@ -1750,7 +1703,6 @@ messageStoreMessages={messageStoreMessages} pendingRealizedThreadIDs={pendingToRealizedThreadIDs} calendarQuery={calendarQuery} - uploadMultimedia={callUploadMultimedia} blobServiceUpload={callBlobServiceUpload} deleteUpload={callDeleteUpload} sendMultimediaMessage={callSendMultimediaMessage} diff --git a/web/input/input-state.js b/web/input/input-state.js --- a/web/input/input-state.js +++ b/web/input/input-state.js @@ -42,7 +42,6 @@ +abort: ?() => void, +steps: MediaMissionStep[], +selectTime: number, - +shouldEncrypt: boolean, }; export type TypeaheadState = {