feat: add media upload progress bar (#479)
This commit is contained in:
parent
e78e2c2078
commit
9969ab2414
5 changed files with 229 additions and 49 deletions
|
|
@ -6,16 +6,25 @@ export default function Uploader({
|
|||
children,
|
||||
onUploadSuccess,
|
||||
onUploadingChange,
|
||||
onUploadStart,
|
||||
onUploadEnd,
|
||||
onProgress,
|
||||
onProvideCancel,
|
||||
className,
|
||||
accept = 'image/*'
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
onUploadSuccess: ({ url, tags }: { url: string; tags: string[][] }) => void
|
||||
onUploadingChange?: (uploading: boolean) => void
|
||||
onUploadStart?: (file: File) => void
|
||||
onUploadEnd?: () => void
|
||||
onProgress?: (progress: number, file: File) => void
|
||||
onProvideCancel?: (cancel: () => void) => void
|
||||
className?: string
|
||||
accept?: string
|
||||
}) {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const abortControllerRef = useRef<AbortController | null>(null)
|
||||
|
||||
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (!event.target.files) return
|
||||
|
|
@ -23,15 +32,29 @@ export default function Uploader({
|
|||
onUploadingChange?.(true)
|
||||
try {
|
||||
for (const file of event.target.files) {
|
||||
const result = await mediaUpload.upload(file)
|
||||
abortControllerRef.current = new AbortController()
|
||||
const cancel = () => abortControllerRef.current?.abort()
|
||||
onProvideCancel?.(cancel)
|
||||
onUploadStart?.(file)
|
||||
const result = await mediaUpload.upload(file, {
|
||||
onProgress: (p) => onProgress?.(p, file),
|
||||
signal: abortControllerRef.current.signal
|
||||
})
|
||||
onUploadSuccess(result)
|
||||
abortControllerRef.current = null
|
||||
onUploadEnd?.()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error uploading file', error)
|
||||
toast.error(`Failed to upload file: ${(error as Error).message}`)
|
||||
const message = (error as Error).message
|
||||
if (message !== 'Upload aborted') {
|
||||
toast.error(`Failed to upload file: ${message}`)
|
||||
}
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = ''
|
||||
}
|
||||
abortControllerRef.current = null
|
||||
onUploadEnd?.()
|
||||
} finally {
|
||||
onUploadingChange?.(false)
|
||||
}
|
||||
|
|
@ -45,8 +68,8 @@ export default function Uploader({
|
|||
}
|
||||
|
||||
return (
|
||||
<div onClick={handleUploadClick} className={className}>
|
||||
{children}
|
||||
<div className={className}>
|
||||
<div onClick={handleUploadClick}>{children}</div>
|
||||
<input
|
||||
type="file"
|
||||
ref={fileInputRef}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue