about summary refs log tree commit diff
path: root/src/state/queries/video/video-upload.shared.ts
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2024-10-03 11:41:23 +0900
committerGitHub <noreply@github.com>2024-10-03 11:41:23 +0900
commitd2392d2d64c46d0fd0b6d97b3b4715b5b8c825d3 (patch)
tree6c5aaa7e42f6543112140464d084db14b4495987 /src/state/queries/video/video-upload.shared.ts
parentc2dac855cc61e05d21b7dbb81f1fef26f1a9e1e7 (diff)
downloadvoidsky-d2392d2d64c46d0fd0b6d97b3b4715b5b8c825d3.tar.zst
Refactor video uploads (#5570)
* Remove unused video field

* Stop exposing video dispatch

* Move cancellation out of the reducer

* Make useUploadStatusQuery controlled by jobId

* Rename SetStatus to SetProcessing

This action only has one callsite and it's always passing "processing".

* Move jobId into video reducer state

* Make cancellation scoped

* Inline useCompressVideoMutation

* Move processVideo down the file

* Extract getErrorMessage

* useServiceAuthToken -> getServiceAuthToken

* useVideoAgent -> createVideoAgent

* useVideoUploadLimits -> getVideoUploadLimits

* useUploadVideoMutation -> uploadVideo

* Use async/await in processVideo

* Inline onVideoCompressed into processVideo

* Use async/await for uploadVideo

* Factor out error messages

* Guard dispatch with signal

This lets us remove the scattered signal checks around dispatch.

* Move job polling out of RQ

* Handle poll failures

* Remove unnecessary guards

* Slightly more accurate condition

* Move initVideoUri handling out of the hook

* Remove dead argument

It wasn't being used before either.

* Remove unused detailed status

This isn't being used because we're only respecting that state variable when isProcessing=true, but isProcessing is always false during video upload.

If we want to re-add this later, it should really just be derived from the reducer state.

* Harden the video reducer

* Tie all spawned work to a signal

* Preserve asset/media for nicer error state

* Rename actions to match states

* Inline useUploadVideo

This abstraction is getting in the way of some future work.

* Move MIME check to the only place that handles it
Diffstat (limited to 'src/state/queries/video/video-upload.shared.ts')
-rw-r--r--src/state/queries/video/video-upload.shared.ts88
1 files changed, 38 insertions, 50 deletions
diff --git a/src/state/queries/video/video-upload.shared.ts b/src/state/queries/video/video-upload.shared.ts
index 6b633bf21..8c217eadc 100644
--- a/src/state/queries/video/video-upload.shared.ts
+++ b/src/state/queries/video/video-upload.shared.ts
@@ -1,73 +1,61 @@
-import {useCallback} from 'react'
+import {BskyAgent} from '@atproto/api'
+import {I18n} from '@lingui/core'
 import {msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
 
 import {VIDEO_SERVICE_DID} from '#/lib/constants'
 import {UploadLimitError} from '#/lib/media/video/errors'
 import {getServiceAuthAudFromUrl} from '#/lib/strings/url-helpers'
-import {useAgent} from '#/state/session'
-import {useVideoAgent} from './util'
+import {createVideoAgent} from './util'
 
-export function useServiceAuthToken({
+export async function getServiceAuthToken({
+  agent,
   aud,
   lxm,
   exp,
 }: {
+  agent: BskyAgent
   aud?: string
   lxm: string
   exp?: number
 }) {
-  const agent = useAgent()
-
-  return useCallback(async () => {
-    const pdsAud = getServiceAuthAudFromUrl(agent.dispatchUrl)
-
-    if (!pdsAud) {
-      throw new Error('Agent does not have a PDS URL')
-    }
-
-    const {data: serviceAuth} = await agent.com.atproto.server.getServiceAuth({
-      aud: aud ?? pdsAud,
-      lxm,
-      exp,
-    })
-
-    return serviceAuth.token
-  }, [agent, aud, lxm, exp])
+  const pdsAud = getServiceAuthAudFromUrl(agent.dispatchUrl)
+  if (!pdsAud) {
+    throw new Error('Agent does not have a PDS URL')
+  }
+  const {data: serviceAuth} = await agent.com.atproto.server.getServiceAuth({
+    aud: aud ?? pdsAud,
+    lxm,
+    exp,
+  })
+  return serviceAuth.token
 }
 
-export function useVideoUploadLimits() {
-  const agent = useVideoAgent()
-  const getToken = useServiceAuthToken({
+export async function getVideoUploadLimits(agent: BskyAgent, _: I18n['_']) {
+  const token = await getServiceAuthToken({
+    agent,
     lxm: 'app.bsky.video.getUploadLimits',
     aud: VIDEO_SERVICE_DID,
   })
-  const {_} = useLingui()
-
-  return useCallback(async () => {
-    const {data: limits} = await agent.app.bsky.video
-      .getUploadLimits(
-        {},
-        {headers: {Authorization: `Bearer ${await getToken()}`}},
-      )
-      .catch(err => {
-        if (err instanceof Error) {
-          throw new UploadLimitError(err.message)
-        } else {
-          throw err
-        }
-      })
-
-    if (!limits.canUpload) {
-      if (limits.message) {
-        throw new UploadLimitError(limits.message)
+  const videoAgent = createVideoAgent()
+  const {data: limits} = await videoAgent.app.bsky.video
+    .getUploadLimits({}, {headers: {Authorization: `Bearer ${token}`}})
+    .catch(err => {
+      if (err instanceof Error) {
+        throw new UploadLimitError(err.message)
       } else {
-        throw new UploadLimitError(
-          _(
-            msg`You have temporarily reached the limit for video uploads. Please try again later.`,
-          ),
-        )
+        throw err
       }
+    })
+
+  if (!limits.canUpload) {
+    if (limits.message) {
+      throw new UploadLimitError(limits.message)
+    } else {
+      throw new UploadLimitError(
+        _(
+          msg`You have temporarily reached the limit for video uploads. Please try again later.`,
+        ),
+      )
     }
-  }, [agent, _, getToken])
+  }
 }