diff --git a/native/account/registration/registration-server-call.js b/native/account/registration/registration-server-call.js --- a/native/account/registration/registration-server-call.js +++ b/native/account/registration/registration-server-call.js @@ -567,7 +567,10 @@ ({ updateUserAvatarRequest } = avatarData); } else { const { mediaSelection } = avatarData; - updateUserAvatarRequest = await uploadSelectedMedia(mediaSelection); + updateUserAvatarRequest = await uploadSelectedMedia( + mediaSelection, + 'keyserver', + ); if (!updateUserAvatarRequest) { return; } 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 @@ -19,10 +19,7 @@ extensionFromFilename, filenameFromPathOrURI, } from 'lib/media/file-utils.js'; -import type { - AvatarDBContent, - UpdateUserAvatarRequest, -} from 'lib/types/avatar-types.js'; +import type { UpdateUserAvatarRequest } from 'lib/types/avatar-types.js'; import type { NativeMediaSelection, MediaLibrarySelection, @@ -54,71 +51,85 @@ ); } -function useUploadProcessedMedia(): MediaResult => Promise { +function useUploadProcessedMedia(): ( + media: MediaResult, + metadataUploadLocation: 'keyserver' | 'none', +) => Promise { const callUploadMultimedia = useLegacyAshoatKeyserverCall(uploadMultimedia); const callBlobServiceUpload = useBlobServiceUpload(); - const uploadProcessedMultimedia: MediaResult => Promise = - React.useCallback( - async processedMedia => { - if (!useBlobServiceUploads) { - 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 }; + 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.'); - } + const { result: encryptionResult } = await encryptMedia(processedMedia); + if (!encryptionResult.success) { + throw new Error('Avatar media encryption failed.'); + } - invariant( - encryptionResult.mediaType === 'encrypted_photo', - 'Invalid mediaType after encrypting avatar', - ); - const { - uploadURI, - filename, - mime, + invariant( + encryptionResult.mediaType === 'encrypted_photo', + 'Invalid mediaType after encrypting avatar', + ); + const { + uploadURI, + filename, + mime, + blobHash, + encryptionKey, + dimensions, + thumbHash, + } = encryptionResult; + const { id, uri } = await callBlobServiceUpload({ + uploadInput: { + blobInput: { + type: 'uri', + uri: uploadURI, + filename, + mimeType: mime, + }, blobHash, encryptionKey, dimensions, thumbHash, - } = encryptionResult; - const { id } = await callBlobServiceUpload({ - uploadInput: { - blobInput: { - type: 'uri', - uri: uploadURI, - filename, - mimeType: mime, - }, - blobHash, - encryptionKey, - dimensions, - thumbHash, - loop: false, - }, - keyserverOrThreadID: authoritativeKeyserverID, - callbacks: { blobServiceUploadHandler }, - }); - if (!id) { - return undefined; - } - return { type: 'encrypted_image', uploadID: id }; - }, - [callUploadMultimedia, callBlobServiceUpload], - ); - return uploadProcessedMultimedia; + loop: false, + }, + keyserverOrThreadID: + metadataUploadLocation === 'keyserver' + ? authoritativeKeyserverID + : null, + callbacks: { blobServiceUploadHandler }, + }); + if (metadataUploadLocation !== 'keyserver') { + return { + type: 'non_keyserver_image', + blobURI: uri, + thumbHash, + encryptionKey, + }; + } + if (!id) { + return undefined; + } + return { type: 'encrypted_image', uploadID: id }; + }, + [callUploadMultimedia, callBlobServiceUpload], + ); } function useProcessSelectedMedia(): NativeMediaSelection => Promise< @@ -185,12 +196,15 @@ function useUploadSelectedMedia( setProcessingOrUploadInProgress?: (inProgress: boolean) => mixed, -): (selection: NativeMediaSelection) => Promise { +): ( + selection: NativeMediaSelection, + metadataUploadLocation: 'keyserver' | 'none', +) => Promise { const processSelectedMedia = useProcessSelectedMedia(); const uploadProcessedMedia = useUploadProcessedMedia(); return React.useCallback( - async (selection: NativeMediaSelection) => { + async (selection: NativeMediaSelection, metadataUploadLocation) => { setProcessingOrUploadInProgress?.(true); const urisToBeDisposed: Set = new Set([selection.uri]); @@ -220,10 +234,14 @@ return undefined; } - let uploadedMedia: ?AvatarDBContent; + let uploadedMedia: ?UpdateUserAvatarRequest; try { - uploadedMedia = await uploadProcessedMedia(processedMedia); + uploadedMedia = await uploadProcessedMedia( + processedMedia, + metadataUploadLocation, + ); urisToBeDisposed.forEach(filesystem.unlink); + setProcessingOrUploadInProgress?.(false); } catch { urisToBeDisposed.forEach(filesystem.unlink); Alert.alert( @@ -319,7 +337,10 @@ return; } - const imageAvatarUpdateRequest = await uploadSelectedMedia(selection); + const imageAvatarUpdateRequest = await uploadSelectedMedia( + selection, + 'keyserver', + ); if (!imageAvatarUpdateRequest) { return; } @@ -400,7 +421,10 @@ selection: NativeMediaSelection, threadID: string, ): Promise => { - const imageAvatarUpdateRequest = await uploadSelectedMedia(selection); + const imageAvatarUpdateRequest = await uploadSelectedMedia( + selection, + 'keyserver', + ); if (!imageAvatarUpdateRequest) { return; }