[Video] Uploads (#4754)

* state for video uploads

* get upload working

* add a debug log

* add post progress

* progress

* fetch data

* add some progress info, web uploads

* post on finished uploading (wip)

* add a note

* add some todos

* clear video

* merge some stuff

* convert to `createUploadTask`

* patch expo modules core

* working native upload progress

* platform fork

* upload progress for web

* cleanup

* cleanup

* more tweaks

* simplify

* fix type errors

---------

Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
This commit is contained in:
Hailey 2024-07-30 08:25:31 -07:00 committed by GitHub
parent 43ba0f21f6
commit 8ddb28d3c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 594 additions and 112 deletions

View file

@ -0,0 +1,59 @@
import {createUploadTask, FileSystemUploadType} from 'expo-file-system'
import {useMutation} from '@tanstack/react-query'
import {nanoid} from 'nanoid/non-secure'
import {CompressedVideo} from 'lib/media/video/compress'
import {UploadVideoResponse} from 'lib/media/video/types'
import {createVideoEndpointUrl} from 'state/queries/video/util'
import {useSession} from 'state/session'
const UPLOAD_HEADER = process.env.EXPO_PUBLIC_VIDEO_HEADER ?? ''
export const useUploadVideoMutation = ({
onSuccess,
onError,
setProgress,
}: {
onSuccess: (response: UploadVideoResponse) => void
onError: (e: any) => void
setProgress: (progress: number) => void
}) => {
const {currentAccount} = useSession()
return useMutation({
mutationFn: async (video: CompressedVideo) => {
const uri = createVideoEndpointUrl('/upload', {
did: currentAccount!.did,
name: `${nanoid(12)}.mp4`, // @TODO what are we limiting this to?
})
const uploadTask = createUploadTask(
uri,
video.uri,
{
headers: {
'dev-key': UPLOAD_HEADER,
'content-type': 'video/mp4', // @TODO same question here. does the compression step always output mp4?
},
httpMethod: 'POST',
uploadType: FileSystemUploadType.BINARY_CONTENT,
},
p => {
setProgress(p.totalBytesSent / p.totalBytesExpectedToSend)
},
)
const res = await uploadTask.uploadAsync()
if (!res?.body) {
throw new Error('No response')
}
// @TODO rm, useful for debugging/getting video cid
console.log('[VIDEO]', res.body)
const responseBody = JSON.parse(res.body) as UploadVideoResponse
onSuccess(responseBody)
return responseBody
},
onError,
onSuccess,
})
}