2018-02-08 15:50:12 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ImgPreview
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
2018-03-09 16:41:24 +01:00
|
|
|
import { get, has, isArray, isEmpty, size } from 'lodash';
|
2018-02-08 15:50:12 +01:00
|
|
|
import cn from 'classnames';
|
|
|
|
|
2018-02-13 16:28:58 +01:00
|
|
|
import BkgImg from 'assets/icons/icon_upload.svg';
|
2018-02-13 16:46:51 +01:00
|
|
|
import ImgPreviewArrow from 'components/ImgPreviewArrow';
|
2018-02-13 18:29:47 +01:00
|
|
|
import ImgPreviewHint from 'components/ImgPreviewHint';
|
2018-02-13 16:28:58 +01:00
|
|
|
|
2018-02-08 15:50:12 +01:00
|
|
|
import styles from './styles.scss';
|
|
|
|
|
2018-02-12 11:23:02 +01:00
|
|
|
class ImgPreview extends React.Component {
|
2018-02-13 16:28:58 +01:00
|
|
|
state = {
|
|
|
|
imgURL: '',
|
|
|
|
isDraging: false,
|
2018-02-13 18:46:54 +01:00
|
|
|
isOver: false,
|
2018-02-27 13:50:20 +01:00
|
|
|
isOverArrow: false,
|
2018-02-13 16:28:58 +01:00
|
|
|
isImg: false,
|
2018-02-27 18:26:16 +01:00
|
|
|
isInitValue: false,
|
2018-02-13 16:28:58 +01:00
|
|
|
};
|
2018-02-12 11:23:02 +01:00
|
|
|
|
|
|
|
componentDidMount() {
|
2018-02-12 15:12:58 +01:00
|
|
|
// We don't need the generateImgURL function here since the compo will
|
|
|
|
// always have an init value here
|
2018-02-12 11:23:02 +01:00
|
|
|
this.setState({
|
2018-03-02 11:49:23 +01:00
|
|
|
imgURL: get(this.props.files, ['0', 'url'], '') || get(this.props.files, 'url', ''),
|
2018-02-12 18:46:45 +01:00
|
|
|
isImg: this.isPictureType(get(this.props.files, ['0', 'name'], '')),
|
2018-02-12 11:23:02 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
if (nextProps.isUploading !== this.props.isUploading) {
|
2018-03-02 11:49:23 +01:00
|
|
|
const lastFile = this.props.multiple ? nextProps.files.slice(-1)[0] : nextProps.files[0] || nextProps.files;
|
2018-02-12 11:23:02 +01:00
|
|
|
this.generateImgURL(lastFile);
|
2018-02-28 18:49:19 +01:00
|
|
|
|
2018-03-02 11:49:23 +01:00
|
|
|
if (this.props.multiple) {
|
2018-02-28 18:49:19 +01:00
|
|
|
this.updateFilePosition(nextProps.files.length - 1);
|
|
|
|
}
|
2018-02-12 11:23:02 +01:00
|
|
|
}
|
2018-02-27 18:26:16 +01:00
|
|
|
// Update the preview or slide pictures or init the component
|
|
|
|
if (nextProps.didDeleteFile !== this.props.didDeleteFile || nextProps.position !== this.props.position || size(nextProps.files) !== size(this.props.files) && !this.state.isInitValue) {
|
2018-03-02 11:49:23 +01:00
|
|
|
const file = nextProps.files[nextProps.position] || nextProps.files || '';
|
2018-02-27 13:50:20 +01:00
|
|
|
this.generateImgURL(file)
|
|
|
|
|
2018-02-27 18:26:16 +01:00
|
|
|
if (!this.state.isInitValue) {
|
|
|
|
this.setState({ isInitValue: true });
|
|
|
|
}
|
2018-02-12 11:23:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-12 18:46:45 +01:00
|
|
|
getFileType = (fileName) => fileName.split('.').slice(-1)[0];
|
|
|
|
|
2018-02-26 16:24:55 +01:00
|
|
|
componentDidCatch(error, info) {
|
|
|
|
console.log('An error occured in ImgPreview', info);
|
|
|
|
}
|
|
|
|
|
2018-02-12 11:23:02 +01:00
|
|
|
/**
|
|
|
|
* [generateImgURL description]
|
|
|
|
* @param {FileList} files
|
|
|
|
* @return {URL}
|
|
|
|
*/
|
|
|
|
generateImgURL = (file) => {
|
2018-02-27 18:26:16 +01:00
|
|
|
if (this.isPictureType(file.name) && !has(file, 'url')) {
|
2018-02-12 18:46:45 +01:00
|
|
|
const reader = new FileReader();
|
|
|
|
reader.onloadend = () => {
|
|
|
|
this.setState({
|
|
|
|
imgURL: reader.result,
|
|
|
|
isImg: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
reader.readAsDataURL(file);
|
2018-02-27 18:26:16 +01:00
|
|
|
} else if (has(file, 'url')) {
|
|
|
|
const isImg = this.isPictureType(file.name);
|
2018-03-02 15:06:35 +01:00
|
|
|
const imgURL = file.url[0] === '/' ?`${strapi.backendURL}${file.url}` :file.url;
|
|
|
|
|
|
|
|
this.setState({ isImg, imgURL });
|
2018-02-12 18:46:45 +01:00
|
|
|
} else {
|
|
|
|
this.setState({ isImg: false, imgURL: file.name });
|
2018-02-12 11:23:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-12 15:12:58 +01:00
|
|
|
handleClick = (type) => {
|
2018-02-27 13:50:20 +01:00
|
|
|
const { files, position } = this.props;
|
2018-02-12 11:23:02 +01:00
|
|
|
let file;
|
|
|
|
let nextPosition;
|
|
|
|
|
2018-02-12 15:12:58 +01:00
|
|
|
switch (type) {
|
|
|
|
case 'right':
|
2018-02-12 11:23:02 +01:00
|
|
|
file = files[position + 1] || files[0];
|
|
|
|
nextPosition = files[position + 1] ? position + 1 : 0;
|
|
|
|
break;
|
2018-02-12 15:12:58 +01:00
|
|
|
case 'left':
|
2018-02-12 11:23:02 +01:00
|
|
|
file = files[position - 1] || files[files.length - 1];
|
|
|
|
nextPosition = files[position - 1] ? position - 1 : files.length - 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
|
2018-02-27 13:50:20 +01:00
|
|
|
// Update the parent position
|
2018-02-12 18:20:43 +01:00
|
|
|
this.updateFilePosition(nextPosition);
|
2018-02-12 11:23:02 +01:00
|
|
|
}
|
|
|
|
|
2018-02-13 16:28:58 +01:00
|
|
|
handleDragEnter = (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
this.setState({ isDraging: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
handleDragLeave = (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
this.setState({ isDraging: false });
|
|
|
|
}
|
|
|
|
|
2018-02-13 18:29:47 +01:00
|
|
|
handleDragOver = (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
|
|
|
|
2018-02-13 16:28:58 +01:00
|
|
|
handleDrop = (e) => {
|
|
|
|
this.setState({ isDraging: false });
|
|
|
|
this.props.onDrop(e);
|
|
|
|
}
|
|
|
|
|
2018-02-20 12:16:11 +01:00
|
|
|
// TODO change logic to depend on the type
|
2018-02-12 18:46:45 +01:00
|
|
|
isPictureType = (fileName) => /\.(jpe?g|png|gif)$/i.test(fileName);
|
|
|
|
|
2018-02-13 16:28:58 +01:00
|
|
|
renderContent = () => {
|
|
|
|
const fileType = this.getFileType(this.state.imgURL);
|
|
|
|
|
|
|
|
if (this.state.isImg) {
|
|
|
|
return (
|
|
|
|
<img src={this.state.imgURL} />
|
|
|
|
);
|
|
|
|
}
|
2018-02-20 12:16:11 +01:00
|
|
|
|
|
|
|
return (
|
2018-02-27 13:50:20 +01:00
|
|
|
<div className={styles.fileIcon} onDrop={this.handleDrop}>
|
2018-02-20 12:16:11 +01:00
|
|
|
<i className={`fa fa-file-${fileType}-o`} />
|
|
|
|
</div>
|
|
|
|
);
|
2018-02-13 16:28:58 +01:00
|
|
|
}
|
|
|
|
|
2018-02-12 18:20:43 +01:00
|
|
|
updateFilePosition = (newPosition) => {
|
2018-02-27 13:50:20 +01:00
|
|
|
// this.setState({ position: newPosition });
|
2018-02-12 18:20:43 +01:00
|
|
|
this.props.updateFilePosition(newPosition);
|
|
|
|
}
|
|
|
|
|
2018-02-12 11:23:02 +01:00
|
|
|
render() {
|
2018-02-13 18:46:54 +01:00
|
|
|
const { files, multiple, onBrowseClick } = this.props;
|
2018-02-13 16:28:58 +01:00
|
|
|
const { imgURL } = this.state;
|
2018-02-13 18:29:47 +01:00
|
|
|
const containerStyle = isEmpty(imgURL) ?
|
|
|
|
{
|
|
|
|
backgroundImage: `url(${BkgImg})`,
|
|
|
|
backgroundRepeat: 'no-repeat',
|
|
|
|
backgroundPosition: 'center',
|
|
|
|
zIndex: 9999,
|
|
|
|
} : {};
|
2018-02-12 18:46:45 +01:00
|
|
|
|
2018-02-12 11:23:02 +01:00
|
|
|
return (
|
2018-02-13 18:29:47 +01:00
|
|
|
<div
|
2018-02-13 18:46:54 +01:00
|
|
|
className={cn(
|
|
|
|
styles.imgPreviewContainer,
|
|
|
|
)}
|
2018-02-13 18:29:47 +01:00
|
|
|
onDragOver={this.handleDragOver}
|
|
|
|
onDragEnter={this.handleDragEnter}
|
|
|
|
style={containerStyle}
|
|
|
|
>
|
|
|
|
<div
|
2018-03-02 16:31:32 +01:00
|
|
|
className={cn(this.state.isDraging && styles.overlay)}
|
2018-02-13 18:29:47 +01:00
|
|
|
onDragLeave={this.handleDragLeave}
|
|
|
|
onDragOver={this.handleDragOver}
|
|
|
|
onDrop={this.handleDrop}
|
|
|
|
/>
|
|
|
|
<ImgPreviewHint
|
|
|
|
displayHint={isEmpty(files)}
|
2018-02-13 18:46:54 +01:00
|
|
|
onClick={onBrowseClick}
|
2018-02-27 13:50:20 +01:00
|
|
|
onDrop={this.handleDrop}
|
2018-03-02 16:31:32 +01:00
|
|
|
showWhiteHint={this.state.isDraging || isEmpty(files)}
|
2018-02-13 18:29:47 +01:00
|
|
|
/>
|
|
|
|
{ !isEmpty(imgURL) && this.renderContent() }
|
|
|
|
<ImgPreviewArrow
|
2018-03-02 16:31:32 +01:00
|
|
|
enable={isArray(files) && size(files) > 1}
|
2018-02-13 18:29:47 +01:00
|
|
|
onClick={this.handleClick}
|
2018-02-27 13:50:20 +01:00
|
|
|
onMouseEnter={(e) => this.setState({ isOverArrow: true })}
|
|
|
|
onMouseLeave={(e) => this.setState({ isOverArrow: false })}
|
2018-03-02 11:49:23 +01:00
|
|
|
show={isArray(files) && size(files) > 1}
|
2018-02-13 18:29:47 +01:00
|
|
|
type="right"
|
|
|
|
/>
|
|
|
|
<ImgPreviewArrow
|
2018-03-02 16:31:32 +01:00
|
|
|
enable={isArray(files) && size(files) > 1}
|
2018-02-13 18:29:47 +01:00
|
|
|
onClick={this.handleClick}
|
2018-02-27 13:50:20 +01:00
|
|
|
onMouseEnter={(e) => this.setState({ isOverArrow: true })}
|
|
|
|
onMouseLeave={(e) => this.setState({ isOverArrow: false })}
|
2018-03-02 11:49:23 +01:00
|
|
|
show={isArray(files) && size(files) > 1}
|
2018-02-13 18:29:47 +01:00
|
|
|
/>
|
|
|
|
</div>
|
2018-03-08 12:56:44 +01:00
|
|
|
|
2018-02-12 11:23:02 +01:00
|
|
|
);
|
|
|
|
}
|
2018-02-08 15:50:12 +01:00
|
|
|
}
|
|
|
|
|
2018-02-12 11:23:02 +01:00
|
|
|
ImgPreview.defaultProps = {
|
2018-02-27 13:50:20 +01:00
|
|
|
didDeleteFile: false,
|
2018-02-20 12:16:11 +01:00
|
|
|
files: [],
|
2018-02-12 11:23:02 +01:00
|
|
|
isUploading: false,
|
2018-02-12 15:12:58 +01:00
|
|
|
multiple: false,
|
|
|
|
name: '',
|
2018-02-13 18:46:54 +01:00
|
|
|
onBrowseClick: () => {},
|
2018-02-12 15:12:58 +01:00
|
|
|
onChange: () => {},
|
2018-02-13 16:28:58 +01:00
|
|
|
onDrop: () => {},
|
2018-02-27 13:50:20 +01:00
|
|
|
position: 0,
|
2018-02-12 18:20:43 +01:00
|
|
|
updateFilePosition: () => {},
|
2018-02-12 11:23:02 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
ImgPreview.propTypes = {
|
2018-02-27 13:50:20 +01:00
|
|
|
didDeleteFile: PropTypes.bool,
|
2018-02-28 18:49:19 +01:00
|
|
|
files: PropTypes.oneOfType([
|
|
|
|
PropTypes.object,
|
|
|
|
PropTypes.array,
|
|
|
|
]),
|
2018-02-12 11:23:02 +01:00
|
|
|
isUploading: PropTypes.bool,
|
2018-02-12 15:12:58 +01:00
|
|
|
multiple: PropTypes.bool,
|
|
|
|
name: PropTypes.string,
|
2018-02-13 18:46:54 +01:00
|
|
|
onBrowseClick: PropTypes.func,
|
2018-02-12 15:12:58 +01:00
|
|
|
onChange: PropTypes.func,
|
2018-02-13 16:28:58 +01:00
|
|
|
onDrop: PropTypes.func,
|
2018-02-27 13:50:20 +01:00
|
|
|
position: PropTypes.number,
|
2018-02-12 18:20:43 +01:00
|
|
|
updateFilePosition: PropTypes.func,
|
2018-02-12 11:23:02 +01:00
|
|
|
};
|
2018-02-08 15:50:12 +01:00
|
|
|
|
|
|
|
export default ImgPreview;
|