about summary refs log tree commit diff
path: root/src/state/queries/video/video-upload.web.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/queries/video/video-upload.web.ts')
-rw-r--r--src/state/queries/video/video-upload.web.ts137
1 files changed, 73 insertions, 64 deletions
diff --git a/src/state/queries/video/video-upload.web.ts b/src/state/queries/video/video-upload.web.ts
index c93e20603..bbae64199 100644
--- a/src/state/queries/video/video-upload.web.ts
+++ b/src/state/queries/video/video-upload.web.ts
@@ -1,86 +1,95 @@
 import {AppBskyVideoDefs} from '@atproto/api'
+import {BskyAgent} from '@atproto/api'
+import {I18n} from '@lingui/core'
 import {msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useMutation} from '@tanstack/react-query'
 import {nanoid} from 'nanoid/non-secure'
 
-import {cancelable} from '#/lib/async/cancelable'
+import {AbortError} from '#/lib/async/cancelable'
 import {ServerError} from '#/lib/media/video/errors'
 import {CompressedVideo} from '#/lib/media/video/types'
 import {createVideoEndpointUrl, mimeToExt} from '#/state/queries/video/util'
-import {useSession} from '#/state/session'
-import {useServiceAuthToken, useVideoUploadLimits} from './video-upload.shared'
+import {getServiceAuthToken, getVideoUploadLimits} from './video-upload.shared'
 
-export const useUploadVideoMutation = ({
-  onSuccess,
-  onError,
+export async function uploadVideo({
+  video,
+  agent,
+  did,
   setProgress,
   signal,
+  _,
 }: {
-  onSuccess: (response: AppBskyVideoDefs.JobStatus) => void
-  onError: (e: any) => void
+  video: CompressedVideo
+  agent: BskyAgent
+  did: string
   setProgress: (progress: number) => void
   signal: AbortSignal
-}) => {
-  const {currentAccount} = useSession()
-  const getToken = useServiceAuthToken({
+  _: I18n['_']
+}) {
+  if (signal.aborted) {
+    throw new AbortError()
+  }
+  await getVideoUploadLimits(agent, _)
+
+  const uri = createVideoEndpointUrl('/xrpc/app.bsky.video.uploadVideo', {
+    did,
+    name: `${nanoid(12)}.${mimeToExt(video.mimeType)}`,
+  })
+
+  let bytes = video.bytes
+  if (!bytes) {
+    if (signal.aborted) {
+      throw new AbortError()
+    }
+    bytes = await fetch(video.uri).then(res => res.arrayBuffer())
+  }
+
+  if (signal.aborted) {
+    throw new AbortError()
+  }
+  const token = await getServiceAuthToken({
+    agent,
     lxm: 'com.atproto.repo.uploadBlob',
     exp: Date.now() / 1000 + 60 * 30, // 30 minutes
   })
-  const checkLimits = useVideoUploadLimits()
-  const {_} = useLingui()
-
-  return useMutation({
-    mutationKey: ['video', 'upload'],
-    mutationFn: cancelable(async (video: CompressedVideo) => {
-      await checkLimits()
 
-      const uri = createVideoEndpointUrl('/xrpc/app.bsky.video.uploadVideo', {
-        did: currentAccount!.did,
-        name: `${nanoid(12)}.${mimeToExt(video.mimeType)}`,
+  if (signal.aborted) {
+    throw new AbortError()
+  }
+  const xhr = new XMLHttpRequest()
+  const res = await new Promise<AppBskyVideoDefs.JobStatus>(
+    (resolve, reject) => {
+      xhr.upload.addEventListener('progress', e => {
+        const progress = e.loaded / e.total
+        setProgress(progress)
       })
-
-      let bytes = video.bytes
-      if (!bytes) {
-        bytes = await fetch(video.uri).then(res => res.arrayBuffer())
+      xhr.onloadend = () => {
+        if (signal.aborted) {
+          reject(new AbortError())
+        } else if (xhr.readyState === 4) {
+          const uploadRes = JSON.parse(
+            xhr.responseText,
+          ) as AppBskyVideoDefs.JobStatus
+          resolve(uploadRes)
+        } else {
+          reject(new ServerError(_(msg`Failed to upload video`)))
+        }
       }
-
-      const token = await getToken()
-
-      const xhr = new XMLHttpRequest()
-      const res = await new Promise<AppBskyVideoDefs.JobStatus>(
-        (resolve, reject) => {
-          xhr.upload.addEventListener('progress', e => {
-            const progress = e.loaded / e.total
-            setProgress(progress)
-          })
-          xhr.onloadend = () => {
-            if (xhr.readyState === 4) {
-              const uploadRes = JSON.parse(
-                xhr.responseText,
-              ) as AppBskyVideoDefs.JobStatus
-              resolve(uploadRes)
-            } else {
-              reject(new ServerError(_(msg`Failed to upload video`)))
-            }
-          }
-          xhr.onerror = () => {
-            reject(new ServerError(_(msg`Failed to upload video`)))
-          }
-          xhr.open('POST', uri)
-          xhr.setRequestHeader('Content-Type', video.mimeType)
-          xhr.setRequestHeader('Authorization', `Bearer ${token}`)
-          xhr.send(bytes)
-        },
-      )
-
-      if (!res.jobId) {
-        throw new ServerError(res.error || _(msg`Failed to upload video`))
+      xhr.onerror = () => {
+        reject(new ServerError(_(msg`Failed to upload video`)))
       }
+      xhr.open('POST', uri)
+      xhr.setRequestHeader('Content-Type', video.mimeType)
+      xhr.setRequestHeader('Authorization', `Bearer ${token}`)
+      xhr.send(bytes)
+    },
+  )
 
-      return res
-    }, signal),
-    onError,
-    onSuccess,
-  })
+  if (!res.jobId) {
+    throw new ServerError(res.error || _(msg`Failed to upload video`))
+  }
+
+  if (signal.aborted) {
+    throw new AbortError()
+  }
+  return res
 }