Skip to content

Instantly share code, notes, and snippets.

@wayanjimmy
Created February 21, 2019 03:42
Show Gist options
  • Save wayanjimmy/c96a80423ee5630cd3bc316dde5dd34b to your computer and use it in GitHub Desktop.
Save wayanjimmy/c96a80423ee5630cd3bc316dde5dd34b to your computer and use it in GitHub Desktop.
Media Uploader component
// @flow
import React from 'react';
import DropzoneComponent from 'react-dropzone-component';
import type {DropzoneState, DropzoneMedia} from 'react-dropzone-component';
import 'react-dropzone-component/styles/filepicker.css';
//$FlowFixMe
import 'dropzone/dist/min/dropzone.min.css';
import type {Media} from '../types/media';
import {getBaseURL, getHeader, request} from '../helpers/api';
import Alert from './Alert';
type Props = {
onUploaded: (files: Array<Media>) => void,
onRemoved: (file: Media) => void,
defaultMedia: Array<Media>,
maxFiles: number,
};
type State = {
errorMessage: ?string,
myDropzone: DropzoneState,
mockfileSetted: boolean,
};
class MediaUploader extends React.Component<Props, State> {
static defaultProps = {
defaultMedia: [],
maxFiles: 1,
};
state = {
errorMessage: null,
mockfileSetted: false,
myDropzone: {
removeFile: (file: File) => {},
options: {
addedfile: {
call: (myDropzoneState: DropzoneState, mockFile: DropzoneMedia) => {},
},
thumbnail: {
call: (
state: DropzoneState,
mockFile: DropzoneMedia,
url: string
) => {},
},
},
},
};
componentDidUpdate(prevProps: Props) {
if (this.props.defaultMedia.length >= 1 && !this.state.mockfileSetted) {
this.setState({mockfileSetted: true});
this.props.defaultMedia.forEach(media => {
const mockFile = {
name: media.name,
size: media.size,
type: media.mime_type,
previewElement: {
classList: {
add: (cn: string) => {},
},
},
};
this.state.myDropzone.options.addedfile.call(
this.state.myDropzone,
mockFile
);
this.state.myDropzone.options.thumbnail.call(
this.state.myDropzone,
mockFile,
media.url
);
mockFile.previewElement.classList.add('dz-succes');
mockFile.previewElement.classList.add('dz-complete');
});
}
}
render() {
let componentConfig = {
iconFiletypes: ['.jpg', '.png', 'jpeg'],
showFiletypeIcon: false,
postUrl: `${getBaseURL()}/products/v1/media`,
};
let djsConfig = {
addRemoveLinks: true,
paramName: 'media',
maxFiles: this.props.maxFiles,
dictDefaultMessage: '<i class="fa fa-file-image-o fa-5x"></i><br>Upload',
headers: {
...getHeader(),
'Content-Type': '',
},
};
let eventHandlers = {
init: dropzone => {
this.setState({myDropzone: dropzone});
},
removedfile: file => {
if (file.xhr && file.xhr.status === 200) {
let mediaId = JSON.parse(file.xhr.response).data.id;
request()
.delete(`/products/v1/media/${mediaId}`)
.then(() => this.props.onRemoved(file))
.catch();
} else {
let media = this.props.defaultMedia.find(
media => media.file_name === file.name
);
if (media) {
request()
.delete(`products/v1/media/${media.id}`)
.then(() => this.props.onRemoved(file))
.catch();
}
}
},
error: (file, response) => {
let {errorMessage} = this.state;
if (response.data) {
errorMessage = response.data.detail;
} else {
errorMessage = response;
}
this.state.myDropzone.removeFile(file);
this.setState({errorMessage});
},
success: (_file, response) => {
this.setState({errorMessage: null});
this.props.onUploaded([response.data]);
},
maxfilesexeeded: file => {
this.state.myDropzone.removeFile(file);
},
};
return (
<div className="dropzone">
{this.state.errorMessage && (
<Alert color="danger">{this.state.errorMessage}</Alert>
)}
<DropzoneComponent
ref="myDropzone"
config={componentConfig}
eventHandlers={eventHandlers}
djsConfig={djsConfig}
/>
</div>
);
}
}
export default MediaUploader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment