react-activestorage-provider
Version:
A React component that allows easy file upload using ActiveStorage
109 lines (92 loc) • 2.85 kB
Flow
/**
* This class handles the listeners for ActiveStorage’s direct upload events
*
* @providesModule Listeners
* @flow
*/
import type VirtualForm from './VirtualForm'
import type { ActiveStorageFileUpload } from './types'
type Props = {
virtualForm: VirtualForm,
onChangeFile: ({ [string]: ActiveStorageFileUpload }) => mixed,
onResetFiles: (uploading: boolean) => mixed,
onBeforeBlobRequest?: ({
id: string,
file: File,
xhr: XMLHttpRequest,
}) => mixed,
onBeforeStorageRequest?: ({
id: string,
file: File,
xhr: XMLHttpRequest,
}) => mixed,
}
class Listeners {
props: Props
constructor(props: Props) {
this.props = props
this._addUploadSetListeners()
this._addUploadInstanceListeners()
}
_addUploadSetListeners() {
const { onResetFiles } = this.props
this._f().addEventListener('direct-uploads:start', () => onResetFiles(true))
this._f().addEventListener('direct-uploads:end', () => onResetFiles(false))
}
_addUploadInstanceListeners() {
this._forwardRequestListeners()
this._addInitializeListener()
this._addProgressListeners()
this._addErrorListener()
this._addFinishListener()
}
_forwardRequestListeners() {
const { onBeforeBlobRequest, onBeforeStorageRequest } = this.props
onBeforeBlobRequest &&
this._f().addEventListener('direct-upload:before-blob-request', e =>
onBeforeBlobRequest(e.detail)
)
onBeforeStorageRequest &&
this._f().addEventListener('direct-upload:before-storage-request', e =>
onBeforeStorageRequest(e.detail)
)
}
_addInitializeListener() {
this._f().addEventListener('direct-upload:initialize', ({ detail }) => {
const { id, file } = detail
this.props.onChangeFile({
[id]: { state: 'waiting', file, id },
})
})
}
_addProgressListeners() {
this._f().addEventListener('direct-upload:start', ({ detail }) => {
const { id, file } = detail
this.props.onChangeFile({
[id]: { state: 'uploading', progress: 0, file, id },
})
})
this._f().addEventListener('direct-upload:progress', ({ detail }) => {
const { id, file, progress } = detail
this.props.onChangeFile({
[id]: { state: 'uploading', progress, file, id },
})
})
}
_addErrorListener() {
this._f().addEventListener('direct-upload:error', ({ detail }) => {
const { id, file, error } = detail
this.props.onChangeFile({ [id]: { state: 'error', file, error, id } })
})
}
_addFinishListener() {
this._f().addEventListener('direct-upload:end', ({ detail }) => {
const { id, file } = detail
this.props.onChangeFile({ [id]: { state: 'finished', file, id } })
})
}
_f(): $FlowIssue {
return this.props.virtualForm.form
}
}
export default Listeners