Skip to content

Instantly share code, notes, and snippets.

@sqrtsanta
Created February 27, 2017 13:14
Show Gist options
  • Save sqrtsanta/375f0480b56a0fbcfd3ccf74ef5858e3 to your computer and use it in GitHub Desktop.
Save sqrtsanta/375f0480b56a0fbcfd3ccf74ef5858e3 to your computer and use it in GitHub Desktop.
React component: dropzone, check - paste/delete pictures from editor
import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import Dropzone from 'react-dropzone';
import pictureable from 'shared/pictures/components/pictureable.jsx';
const _getPictureIds = (pictureCheckStatuses) => R.filter(key =>
pictureCheckStatuses[key], R.keys(pictureCheckStatuses)
);
export class ImageManagerModal extends Component {
constructor() {
super();
this.state = {
isOpen: false,
pictureCheckStatuses: {},
};
this.open = this._open.bind(this);
this.close = this._close.bind(this);
this.check = this._check.bind(this);
this.add = this._add.bind(this);
this.remove = this._remove.bind(this);
this.pasteToEditor = this._pasteToEditor.bind(this);
}
_open() {
this.setState({ isOpen: true });
}
_close() {
this.setState({ isOpen: false, pictureCheckStatuses: {} });
}
_add(files) {
const { addMultiplePictures, klass, note: { id } } = this.props;
const formData = new FormData();
for (let i = 0; i < files.length; i += 1) {
formData.append('pictures[]', files[i]);
}
addMultiplePictures(klass, id, formData);
}
_check(event, id) {
event.preventDefault();
event.stopPropagation();
const { pictureCheckStatuses } = this.state;
this.setState({
pictureCheckStatuses: {
...pictureCheckStatuses,
[id]: !pictureCheckStatuses[id],
},
});
}
_remove() {
const { pictureCheckStatuses } = this.state;
const { removeMultiplePictures, cutImages, klass, note: { id } } = this.props;
const picture_ids = _getPictureIds(pictureCheckStatuses);
removeMultiplePictures(klass, id, picture_ids);
cutImages(picture_ids);
this.setState({ pictureCheckStatuses: {} });
}
_pasteToEditor() {
const { pictureCheckStatuses } = this.state;
const { pasteImages } = this.props;
const picture_ids = _getPictureIds(pictureCheckStatuses);
pasteImages(picture_ids);
this.close();
}
render() {
const { isOpen, pictureCheckStatuses } = this.state;
const { note, progressbar_percent } = this.props;
const picture_ids = _getPictureIds(pictureCheckStatuses);
if (!isOpen) {
return null;
}
return (
<layer className={`modal -content-center ${isOpen ? 'show' : ''}`}>
<middle>
<content>
<column width="100vw md:560px">
<column className="modalCard">
<row className="modalCardHeader -content-justify -items-center" cellPadding="16px">
<div>Каталог фотографий</div>
<button shape="circle" onClick={this.close}>
<icon className="icon-18px icon-light icon-close" />
</button>
</row>
<column className="-split" data-position="relative">
{
note.pictures.length === 0 ?
<Dropzone
className="dropzone -clickable"
activeClassName="-hover"
ref="dropzone"
onDrop={this.add}
accept="image/*"
data-padding="32px"
>
<placeholder data-padding="32px" cellSpacing="4px">
<icon className="icon-36px icon-image" />
<div className="h3">Добавьте фотографии</div>
<div>Нажмите или переместите фотографии сюда</div>
</placeholder>
</Dropzone>
: null
}
{
note.pictures.length > 0 ?
<Dropzone
className="dropzone -scroll"
activeClassName="-hover"
ref="dropzone"
onDrop={this.add}
accept="image/*"
disableClick
>
<row cellPadding="8px" data-padding="24px">
<column onClick={() => this.refs.dropzone.open()} className="photoCheckable" width="25%">
<card shape="square">
<layer className="-content-center -items-center">
<icon className="icon-48px icon-dark icon-plus" />
</layer>
</card>
</column>
{
note.pictures.map(pic =>
<column width="25%" className="photoCheckable" key={pic.id} >
<card
data-padding="8px"
className={`${pictureCheckStatuses[pic.id] ? '-checked' : ''}`}
onClick={(event) => this.check(event, pic.id)}
>
<div>
<photo
shape="square" placeholder="photo"
style={pic.image_thumb_url ? {
backgroundImage: `url(${pic.image_thumb_url})`,
backgroundSize: 'cover',
} : null}
/>
</div>
</card>
</column>
)
}
</row>
<layer className="modalCardPlaceholderLayer" data-padding="32px">
<placeholder className="-flex-grow" data-padding="20px" cellSpacing="4px">
<icon className="icon-36px icon-image" />
<div>Отпустите, чтобы начать загрузку</div>
</placeholder>
</layer>
</Dropzone>
: null
}
</column>
{
progressbar_percent > 0 ? <progress max="100" value={progressbar_percent} /> : null
}
{
note.pictures.length > 0 ?
<row className="modalCardFooter -content-end" cellSpacing="4px" data-padding="12px">
<button
onClick={this.remove}
className="button -neutral"
disabled={progressbar_percent > 0 || picture_ids.length === 0}
>
Удалить
</button>
<button
onClick={this.pasteToEditor}
className="button -success"
disabled={progressbar_percent > 0 || picture_ids.length === 0}
>
Вставить
</button>
</row>
: null
}
</column>
</column>
</content>
</middle>
</layer>
);
}
}
ImageManagerModal.propTypes = {
klass: PropTypes.string.isRequired,
note: PropTypes.object.isRequired,
pasteImages: PropTypes.func.isRequired,
cutImages: PropTypes.func.isRequired,
progressbar_percent: PropTypes.number.isRequired,
addMultiplePictures: PropTypes.func.isRequired,
removeMultiplePictures: PropTypes.func.isRequired,
};
function select(state) {
return {
progressbar_percent: state.client.ui_state.progressbar_percent,
};
}
const enhance = R.compose(
connect(select, null, null, { withRef: true }),
pictureable
);
export default enhance(ImageManagerModal);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment