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,16 +2,25 @@ import * as React from 'react'; -import { uploadMultimedia } from 'lib/actions/upload-actions.js'; -import type { UploadMultimediaResult } from 'lib/types/media-types.js'; +import { + uploadMultimedia, + blobServiceUpload, +} from 'lib/actions/upload-actions.js'; +import type { UpdateUserAvatarRequest } from 'lib/types/avatar-types.js'; import { useServerCall } from 'lib/utils/action-utils.js'; +import { encryptFile } from '../media/encryption-utils.js'; +import { generateThumbHash } from '../media/image-utils.js'; import { validateFile } from '../media/media-utils.js'; -function useUploadAvatarMedia(): File => Promise { +// TODO: flip the switch +const useBlobServiceUploads = false; + +function useUploadAvatarMedia(): File => Promise { const callUploadMultimedia = useServerCall(uploadMultimedia); + const callBlobServiceUpload = useServerCall(blobServiceUpload); const uploadAvatarMedia = React.useCallback( - async (file: File): Promise => { + async file => { const validatedFile = await validateFile(file); const { result } = validatedFile; if (!result.success) { @@ -22,9 +31,48 @@ ...dimensions, loop: false, }; - return await callUploadMultimedia(fixedFile, uploadExtras); + if (!useBlobServiceUploads) { + const { id } = await callUploadMultimedia(fixedFile, uploadExtras); + return { type: 'image', uploadID: id }; + } + + const encryptionResponse = await encryptFile(fixedFile); + const { result: encryptionResult } = encryptionResponse; + if (!encryptionResult.success) { + throw new Error('Avatar media encryption failed.'); + } + const { + file: encryptedFile, + sha256Hash: blobHash, + encryptionKey, + } = encryptionResult; + + const { result: thumbHashResult } = await generateThumbHash( + fixedFile, + encryptionKey, + ); + const thumbHash = thumbHashResult.success + ? thumbHashResult.thumbHash + : null; + + const { id } = await callBlobServiceUpload({ + input: { + blobInput: { + type: 'file', + file: encryptedFile, + }, + blobHash, + encryptionKey, + dimensions, + loop: false, + thumbHash, + }, + callbacks: {}, + }); + + return { type: 'encrypted-image', uploadID: id }; }, - [callUploadMultimedia], + [callBlobServiceUpload, callUploadMultimedia], ); return uploadAvatarMedia; } diff --git a/web/avatars/edit-thread-avatar-menu.react.js b/web/avatars/edit-thread-avatar-menu.react.js --- a/web/avatars/edit-thread-avatar-menu.react.js +++ b/web/avatars/edit-thread-avatar-menu.react.js @@ -59,10 +59,7 @@ const onImageSelected = React.useCallback( async event => { const uploadResult = await uploadAvatarMedia(event.target.files[0]); - baseSetThreadAvatar(threadInfo.id, { - type: 'image', - uploadID: uploadResult.id, - }); + baseSetThreadAvatar(threadInfo.id, uploadResult); }, [baseSetThreadAvatar, threadInfo.id, uploadAvatarMedia], ); diff --git a/web/avatars/edit-user-avatar-menu.react.js b/web/avatars/edit-user-avatar-menu.react.js --- a/web/avatars/edit-user-avatar-menu.react.js +++ b/web/avatars/edit-user-avatar-menu.react.js @@ -71,7 +71,7 @@ const onImageSelected = React.useCallback( async event => { const uploadResult = await uploadAvatarMedia(event.target.files[0]); - baseSetUserAvatar({ type: 'image', uploadID: uploadResult.id }); + baseSetUserAvatar(uploadResult); }, [baseSetUserAvatar, uploadAvatarMedia], );