rsnext/examples/with-mux-video/components/upload-form.js
Dylan Jhaveri d5f5b5f29b
with-mux-video update (#13992)
* function rename
* update package.json dependencies to use `^` for semver. I noticed the package-lock.json is not committed in these examples, which seems to be intentional. Is it advisable to use semver for dependencies? This could actually break if someone clones, installs and a newer version of something has a breakage, but in general it might be nice to have folks installing the latest patch releases for deps.
* use Upchunk 2.0.0. with 1000x [better progress reporting on uploads](https://github.com/muxinc/upchunk/releases/tag/v2.0.0)

**Notice the progress %**

Upchunk pre 2.0:

![before-loading](https://user-images.githubusercontent.com/764988/84232581-70fa5080-aaa5-11ea-8db8-2cfe50339b43.gif)

Upchunk 2.0:

![after-loading](https://user-images.githubusercontent.com/764988/84232620-85d6e400-aaa5-11ea-82cc-b348ead1f5de.gif)
2020-06-10 07:05:14 +00:00

109 lines
2.7 KiB
JavaScript

import { useEffect, useRef, useState } from 'react'
import Router from 'next/router'
import * as UpChunk from '@mux/upchunk'
import useSwr from 'swr'
import Button from './button'
import Spinner from './spinner'
import ErrorMessage from './error-message'
const fetcher = (url) => {
return fetch(url).then((res) => res.json())
}
const UploadForm = () => {
const [isUploading, setIsUploading] = useState(false)
const [isPreparing, setIsPreparing] = useState(false)
const [uploadId, setUploadId] = useState(null)
const [progress, setProgress] = useState(null)
const [errorMessage, setErrorMessage] = useState('')
const inputRef = useRef(null)
const { data, error } = useSwr(
() => (isPreparing ? `/api/upload/${uploadId}` : null),
fetcher,
{ refreshInterval: 5000 }
)
const upload = data && data.upload
useEffect(() => {
if (upload && upload.asset_id) {
Router.push({
pathname: `/asset/${upload.asset_id}`,
scroll: false,
})
}
}, [upload])
if (error) return <ErrorMessage message="Error fetching api" />
if (data && data.error) return <ErrorMessage message={data.error} />
const createUpload = async () => {
try {
return fetch('/api/upload', {
method: 'POST',
})
.then((res) => res.json())
.then(({ id, url }) => {
setUploadId(id)
return url
})
} catch (e) {
console.error('Error in createUpload', e)
setErrorMessage('Error creating upload')
}
}
const startUpload = (evt) => {
setIsUploading(true)
const upload = UpChunk.createUpload({
endpoint: createUpload,
file: inputRef.current.files[0],
})
upload.on('error', (err) => {
setErrorMessage(err.detail)
})
upload.on('progress', (progress) => {
setProgress(Math.floor(progress.detail))
})
upload.on('success', () => {
setIsPreparing(true)
})
}
if (errorMessage) return <ErrorMessage message={errorMessage} />
return (
<>
<div className="container">
{isUploading ? (
<>
{isPreparing ? (
<div>Preparing..</div>
) : (
<div>Uploading...{progress ? `${progress}%` : ''}</div>
)}
<Spinner />
</>
) : (
<label>
<Button type="button" onClick={() => inputRef.current.click()}>
Select a video file
</Button>
<input type="file" onChange={startUpload} ref={inputRef} />
</label>
)}
</div>
<style jsx>{`
input {
display: none;
}
`}</style>
</>
)
}
export default UploadForm