Files
drive/apps/drive-web/src/files/use-upload-file.ts

56 lines
1.3 KiB
TypeScript
Raw Normal View History

import { api } from "@fileone/convex/api"
import type { Doc, Id } from "@fileone/convex/dataModel"
2025-10-12 00:43:31 +00:00
import { useMutation as useConvexMutation } from "convex/react"
import { useCallback } from "react"
function useUploadFile({
targetDirectory,
}: {
targetDirectory: Doc<"directories">
}) {
const generateUploadUrl = useConvexMutation(api.files.generateUploadUrl)
2025-11-02 18:12:33 +00:00
const saveFile = useConvexMutation(api.filesystem.saveFile)
2025-10-12 00:43:31 +00:00
async function upload({
file,
onStart,
onProgress,
}: {
file: File
onStart: (xhr: XMLHttpRequest) => void
onProgress: (progress: number) => void
}) {
const uploadUrl = await generateUploadUrl()
return new Promise<{ storageId: Id<"_storage"> }>((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener("progress", (e) => {
onProgress(e.loaded / e.total)
})
xhr.upload.addEventListener("error", reject)
xhr.addEventListener("load", () => {
resolve(
xhr.response as {
storageId: Id<"_storage">
},
)
})
xhr.open("POST", uploadUrl)
xhr.responseType = "json"
xhr.setRequestHeader("Content-Type", file.type)
xhr.send(file)
onStart(xhr)
}).then(({ storageId }) =>
saveFile({
storageId,
name: file.name,
directoryId: targetDirectory._id,
}),
)
}
return useCallback(upload, [])
}
export default useUploadFile