251 lines
6.6 KiB
JavaScript
Raw Normal View History

/**
*
*
* ImgPreview
*
*/
2018-03-14 22:20:39 +01:00
/* eslint-disable no-console */
import React from 'react';
import PropTypes from 'prop-types';
2018-07-06 14:15:59 +02:00
import { get, has, isArray, isEmpty, startsWith, size } from 'lodash';
import cn from 'classnames';
2019-02-22 10:22:21 +01:00
import ImgPreviewArrow from '../ImgPreviewArrow';
import ImgPreviewHint from '../ImgPreviewHint';
2019-12-13 17:02:14 +01:00
import IconUpload from './IconUpload';
2019-10-09 15:44:56 +02:00
import Wrapper from './Wrapper';
2018-05-04 18:02:35 +02:00
/* eslint-disable react/no-unused-state */
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,
isInitValue: false,
2018-02-13 16:28:58 +01:00
};
componentDidMount() {
// We don't need the generateImgURL function here since the compo will
// always have an init value here
2019-08-13 11:31:10 +02:00
const file = this.props.multiple
? get(this.props.files, ['0', 'name'], '')
: get(this.props.files, 'name');
this.setState({
2019-08-13 11:31:10 +02:00
imgURL:
get(this.props.files, ['0', 'url'], '') ||
get(this.props.files, 'url', ''),
2018-07-06 14:15:59 +02:00
isImg: this.isPictureType(file),
});
}
2019-08-13 11:31:10 +02:00
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.isUploading !== this.props.isUploading) {
2019-08-13 11:31:10 +02:00
const lastFile = this.props.multiple
? nextProps.files.slice(-1)[0]
: nextProps.files[0] || nextProps.files;
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);
}
}
// Update the preview or slide pictures or init the component
2019-08-13 11:31:10 +02:00
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-03-14 09:59:42 +01:00
this.generateImgURL(file);
2018-02-27 13:50:20 +01:00
if (!this.state.isInitValue) {
this.setState({ isInitValue: true });
}
}
if (isEmpty(nextProps.files)) {
this.setState({ isImg: false, imgURL: null });
}
}
2018-02-26 16:24:55 +01:00
componentDidCatch(error, info) {
console.log('An error occured in ImgPreview', info);
}
2019-08-13 11:31:10 +02:00
getFileType = fileName => fileName.split('.').slice(-1)[0];
2018-05-16 12:07:02 +02:00
/**
* [generateImgURL description]
* @param {FileList} files
* @return {URL}
*/
2019-08-13 11:31:10 +02:00
generateImgURL = file => {
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,
});
2018-03-14 09:59:42 +01:00
};
2018-02-12 18:46:45 +01:00
reader.readAsDataURL(file);
} else if (has(file, 'url')) {
const isImg = this.isPictureType(file.name);
2019-08-13 11:31:10 +02:00
const imgURL =
file.url[0] === '/' ? `${strapi.backendURL}${file.url}` : file.url;
2018-03-02 15:06:35 +01:00
this.setState({ isImg, imgURL });
2018-02-12 18:46:45 +01:00
} else {
this.setState({ isImg: false, imgURL: file.name });
}
2019-08-13 11:31:10 +02:00
};
2019-08-13 11:31:10 +02:00
handleClick = type => {
2018-02-27 13:50:20 +01:00
const { files, position } = this.props;
2018-03-14 09:59:42 +01:00
let file; // eslint-disable-line no-unused-vars
let nextPosition;
switch (type) {
case 'right':
file = files[position + 1] || files[0];
nextPosition = files[position + 1] ? position + 1 : 0;
break;
case 'left':
file = files[position - 1] || files[files.length - 1];
nextPosition = files[position - 1] ? position - 1 : files.length - 1;
break;
default:
2019-08-13 11:31:10 +02:00
// 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);
2019-08-13 11:31:10 +02:00
};
2019-08-13 11:31:10 +02:00
handleDragEnter = e => {
2018-02-13 16:28:58 +01:00
e.preventDefault();
e.stopPropagation();
this.setState({ isDraging: true });
2019-08-13 11:31:10 +02:00
};
2018-02-13 16:28:58 +01:00
2019-08-13 11:31:10 +02:00
handleDragLeave = e => {
2018-02-13 16:28:58 +01:00
e.preventDefault();
e.stopPropagation();
this.setState({ isDraging: false });
2019-08-13 11:31:10 +02:00
};
2018-02-13 16:28:58 +01:00
2019-08-13 11:31:10 +02:00
handleDragOver = e => {
2018-02-13 18:29:47 +01:00
e.preventDefault();
e.stopPropagation();
2019-08-13 11:31:10 +02:00
};
2018-02-13 18:29:47 +01:00
2019-08-13 11:31:10 +02:00
handleDrop = e => {
2018-02-13 16:28:58 +01:00
this.setState({ isDraging: false });
this.props.onDrop(e);
2019-08-13 11:31:10 +02:00
};
2018-02-13 16:28:58 +01:00
2018-02-20 12:16:11 +01:00
// TODO change logic to depend on the type
2019-08-13 11:31:10 +02:00
isPictureType = fileName => /\.(jpe?g|png|gif)$/i.test(fileName);
2018-02-12 18:46:45 +01:00
2019-08-13 11:31:10 +02:00
updateFilePosition = newPosition => {
2018-03-14 09:59:42 +01:00
this.props.updateFilePosition(newPosition);
2019-08-13 11:31:10 +02:00
};
2018-03-14 09:59:42 +01:00
2018-02-13 16:28:58 +01:00
renderContent = () => {
const fileType = this.getFileType(this.state.imgURL);
2019-08-13 11:31:10 +02:00
2018-02-13 16:28:58 +01:00
if (this.state.isImg) {
2019-08-13 11:31:10 +02:00
const imgURL = startsWith(this.state.imgURL, '/')
? `${strapi.backendURL}${this.state.imgURL}`
: this.state.imgURL;
2018-07-06 14:15:59 +02:00
2019-08-13 11:31:10 +02:00
return <img src={imgURL} alt="" />;
2018-02-13 16:28:58 +01:00
}
2018-02-20 12:16:11 +01:00
return (
2019-10-09 15:44:56 +02:00
<div className="fileIcon" onDrop={this.handleDrop}>
2019-11-27 10:28:28 +01:00
<i className={`far fa-file-${fileType}`} />
2018-02-20 12:16:11 +01:00
</div>
);
2019-08-13 11:31:10 +02:00
};
2018-02-13 16:28:58 +01:00
render() {
2018-03-14 09:59:42 +01:00
const { files, onBrowseClick } = this.props;
2018-02-13 16:28:58 +01:00
const { imgURL } = this.state;
2018-07-06 14:15:59 +02:00
2019-08-13 11:31:10 +02:00
const containerStyle = isEmpty(imgURL)
? {
2019-12-13 17:02:14 +01:00
display: 'flex',
2019-08-13 11:31:10 +02:00
zIndex: 9999,
}
: {};
2018-02-12 18:46:45 +01:00
return (
2019-10-09 15:44:56 +02:00
<Wrapper
2018-03-14 09:59:42 +01:00
onDragOver={this.handleDragOver}
onDragEnter={this.handleDragEnter}
style={containerStyle}
>
2019-12-13 17:02:14 +01:00
{isEmpty(imgURL) && <IconUpload />}
2018-02-13 18:29:47 +01:00
<div
2019-10-09 15:44:56 +02:00
className={cn(this.state.isDraging && 'overlay')}
2018-03-14 09:59:42 +01:00
onDragLeave={this.handleDragLeave}
2018-02-13 18:29:47 +01:00
onDragOver={this.handleDragOver}
2018-03-14 09:59:42 +01:00
onDrop={this.handleDrop}
/>
<ImgPreviewHint
displayHint={isEmpty(files)}
onClick={onBrowseClick}
onDrop={this.handleDrop}
showWhiteHint={this.state.isDraging || isEmpty(files)}
/>
2019-08-13 11:31:10 +02:00
{!isEmpty(imgURL) && this.renderContent()}
2018-03-14 09:59:42 +01:00
<ImgPreviewArrow
enable={isArray(files) && size(files) > 1}
onClick={this.handleClick}
onMouseEnter={() => this.setState({ isOverArrow: true })}
onMouseLeave={() => this.setState({ isOverArrow: false })}
show={isArray(files) && size(files) > 1}
type="right"
/>
<ImgPreviewArrow
enable={isArray(files) && size(files) > 1}
onClick={this.handleClick}
onMouseEnter={() => this.setState({ isOverArrow: true })}
onMouseLeave={() => this.setState({ isOverArrow: false })}
show={isArray(files) && size(files) > 1}
/>
2019-10-09 15:44:56 +02:00
</Wrapper>
);
}
}
ImgPreview.defaultProps = {
2018-02-27 13:50:20 +01:00
didDeleteFile: false,
2018-02-20 12:16:11 +01:00
files: [],
isUploading: false,
multiple: false,
2018-02-13 18:46:54 +01:00
onBrowseClick: () => {},
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: () => {},
};
ImgPreview.propTypes = {
2018-02-27 13:50:20 +01:00
didDeleteFile: PropTypes.bool,
2019-08-13 11:31:10 +02:00
files: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
isUploading: PropTypes.bool,
multiple: PropTypes.bool,
2018-02-13 18:46:54 +01:00
onBrowseClick: 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,
};
export default ImgPreview;