about summary refs log tree commit diff
path: root/src/state/queries/video/video.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/queries/video/video.ts')
-rw-r--r--src/state/queries/video/video.ts91
1 files changed, 57 insertions, 34 deletions
diff --git a/src/state/queries/video/video.ts b/src/state/queries/video/video.ts
index 3c5094c71..87f315640 100644
--- a/src/state/queries/video/video.ts
+++ b/src/state/queries/video/video.ts
@@ -6,7 +6,8 @@ import {useLingui} from '@lingui/react'
 import {QueryClient, useQuery, useQueryClient} from '@tanstack/react-query'
 
 import {logger} from '#/logger'
-import {VideoTooLargeError} from 'lib/media/video/errors'
+import {isWeb} from '#/platform/detection'
+import {ServerError, VideoTooLargeError} from 'lib/media/video/errors'
 import {CompressedVideo} from 'lib/media/video/types'
 import {useCompressVideoMutation} from 'state/queries/video/compress-video'
 import {useVideoAgent} from 'state/queries/video/util'
@@ -58,7 +59,12 @@ function reducer(queryClient: QueryClient) {
         abortController: new AbortController(),
       }
     } else if (action.type === 'SetAsset') {
-      updatedState = {...state, asset: action.asset}
+      updatedState = {
+        ...state,
+        asset: action.asset,
+        status: 'compressing',
+        error: undefined,
+      }
     } else if (action.type === 'SetDimensions') {
       updatedState = {
         ...state,
@@ -67,11 +73,11 @@ function reducer(queryClient: QueryClient) {
           : undefined,
       }
     } else if (action.type === 'SetVideo') {
-      updatedState = {...state, video: action.video}
+      updatedState = {...state, video: action.video, status: 'uploading'}
     } else if (action.type === 'SetJobStatus') {
       updatedState = {...state, jobStatus: action.jobStatus}
     } else if (action.type === 'SetBlobRef') {
-      updatedState = {...state, blobRef: action.blobRef}
+      updatedState = {...state, blobRef: action.blobRef, status: 'done'}
     }
     return updatedState
   }
@@ -108,10 +114,6 @@ export function useUploadVideo({
         type: 'SetBlobRef',
         blobRef,
       })
-      dispatch({
-        type: 'SetStatus',
-        status: 'idle',
-      })
       onSuccess()
     },
   })
@@ -125,10 +127,17 @@ export function useUploadVideo({
       setJobId(response.jobId)
     },
     onError: e => {
-      dispatch({
-        type: 'SetError',
-        error: _(msg`An error occurred while uploading the video.`),
-      })
+      if (e instanceof ServerError) {
+        dispatch({
+          type: 'SetError',
+          error: e.message,
+        })
+      } else {
+        dispatch({
+          type: 'SetError',
+          error: _(msg`An error occurred while uploading the video.`),
+        })
+      }
       logger.error('Error uploading video', {safeMessage: e})
     },
     setProgress: p => {
@@ -141,6 +150,13 @@ export function useUploadVideo({
     onProgress: p => {
       dispatch({type: 'SetProgress', progress: p})
     },
+    onSuccess: (video: CompressedVideo) => {
+      dispatch({
+        type: 'SetVideo',
+        video,
+      })
+      onVideoCompressed(video)
+    },
     onError: e => {
       if (e instanceof VideoTooLargeError) {
         dispatch({
@@ -150,36 +166,28 @@ export function useUploadVideo({
       } else {
         dispatch({
           type: 'SetError',
-          // @TODO better error message from server, left untranslated on purpose
-          error: 'An error occurred while compressing the video.',
+          error: _(msg`An error occurred while compressing the video.`),
         })
         logger.error('Error compressing video', {safeMessage: e})
       }
     },
-    onSuccess: (video: CompressedVideo) => {
-      dispatch({
-        type: 'SetVideo',
-        video,
-      })
-      dispatch({
-        type: 'SetStatus',
-        status: 'uploading',
-      })
-      onVideoCompressed(video)
-    },
     signal: state.abortController.signal,
   })
 
   const selectVideo = (asset: ImagePickerAsset) => {
-    dispatch({
-      type: 'SetAsset',
-      asset,
-    })
-    dispatch({
-      type: 'SetStatus',
-      status: 'compressing',
-    })
-    onSelectVideo(asset)
+    switch (getMimeType(asset)) {
+      case 'video/mp4':
+      case 'video/mpeg':
+      case 'video/webm':
+        dispatch({
+          type: 'SetAsset',
+          asset,
+        })
+        onSelectVideo(asset)
+        break
+      default:
+        throw new Error(_(msg`Unsupported video type: ${getMimeType(asset)}`))
+    }
   }
 
   const clearVideo = () => {
@@ -241,6 +249,21 @@ const useUploadStatusQuery = ({
     isError,
     setJobId: (_jobId: string) => {
       setJobId(_jobId)
+      setEnabled(true)
     },
   }
 }
+
+function getMimeType(asset: ImagePickerAsset) {
+  if (isWeb) {
+    const [mimeType] = asset.uri.slice('data:'.length).split(';base64,')
+    if (!mimeType) {
+      throw new Error('Could not determine mime type')
+    }
+    return mimeType
+  }
+  if (!asset.mimeType) {
+    throw new Error('Could not determine mime type')
+  }
+  return asset.mimeType
+}