UNPKG

modules-pack

Version:

JavaScript Modules for Modern Frontend & Backend Projects

76 lines (67 loc) 2.5 kB
import { connect } from 'modules-pack/redux' import { FILE } from 'modules-pack/variables' import PropTypes from 'prop-types' import React, { PureComponent } from 'react' import Image from 'react-ui-pack/Image' import { isEqual, toList } from 'utils-pack' import select from '../selectors' import Upload from './Upload' /** * MAP STATE & ACTIONS TO PROPS ------------------------------------------------ * ----------------------------------------------------------------------------- */ const mapStateToProps = (state) => ({ files: select.images(state) }) /** * VIEW TEMPLATE --------------------------------------------------------------- * Image uploader connected to redux-state for the last uploaded file * ----------------------------------------------------------------------------- */ @connect(mapStateToProps) export default class UploadImage extends PureComponent { static propTypes = { // Upload file type, default is 'image' fileType: PropTypes.string, // Show first uploaded image preview, default is true hasPreview: PropTypes.bool, // list of Dropzone file objects to override default selector files: PropTypes.arrayOf(PropTypes.object).isRequired, // Allow multiple file uploads, default is false multiple: PropTypes.bool, // Remove File preview when another uploaded autoClean: PropTypes.bool, // Placeholder content to render if no preview children: PropTypes.any, // @Note: see Upload module for other props (src/web/modules/upload/_View.js) } static defaultProps = { fileType: FILE.TYPE.IMAGE } get file () { const {files} = this.props return toList(files)[0] || {} } UNSAFE_componentWillReceiveProps (nextProps, _) { // Prevent memory leak (this clears last uploaded files in redux state, if no `files` prop given) const {autoClean, files} = this.props if (autoClean && !isEqual(files, nextProps.files)) this.garbageClean() } componentWillUnmount () { this.props.autoClean && this.garbageClean() } garbageClean = ({files} = this.props) => { for (const file of files) { if (file.preview) URL.revokeObjectURL(file.preview) } } render () { const {hasPreview = true, children, dispatch: _, autoClean: __, ...props} = this.props const {preview} = this.file return ( <Upload hasHeader={false} multiple={false} {...props}> {(hasPreview && preview) ? <Image name='preview' src={preview}/> : children} </Upload> ) } }