Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, {Component} from 'react';
- import {
- CellMeasurer,
- CellMeasurerCache,
- createMasonryCellPositioner,
- Masonry,
- AutoSizer,
- WindowScroller,
- } from 'react-virtualized';
- import Modal from '../../../components/Modal';
- import Button from '../../../components/Button';
- import AddImageForm from '../AddImageForm';
- import styles from './styles.css';
- const API = process.env.API || 'http://localhost:3001/api';
- class ImageList extends Component {
- constructor(props) {
- super(props);
- this.columnCount = 0;
- this.columnHeights = {};
- this.columnWidth = 238;
- this.columnHeight = 132;
- this.spacer = 20;
- this.state = {
- modalIsOpen: false,
- speed: 100,
- skip: 0,
- limit: 24
- };
- this.openModal = this.openModal.bind(this);
- this.closeModal = this.closeModal.bind(this);
- }
- componentDidMount() {
- const search = this.props.location.search;
- if (search) {
- let searchParams = new URLSearchParams(search);
- searchParams.set('skip', this.state.skip);
- searchParams.set('limit', this.state.limit);
- this.props.imagesActions.getImages(searchParams);
- }
- }
- componentWillReceiveProps(nextProps) {
- const search = this.props.location.search;
- const nextSearch = nextProps.location.search;
- if (search !== nextSearch) {
- let searchParams = new URLSearchParams(nextSearch);
- searchParams.set('skip', 0);
- searchParams.set('limit', this.state.limit);
- this.props.imagesActions.getImages(searchParams);
- }
- };
- openModal() {
- this.setState({modalIsOpen: true});
- };
- closeModal() {
- this.setState({modalIsOpen: false});
- };
- addImage = (values) => {
- this.closeModal();
- return this.props.imagesActions.addImage(values);
- };
- cellMeasurerCache = new CellMeasurerCache({
- defaultWidth: this.columnWidth,
- defaultHeight: this.columnHeight,
- fixedWidth: true,
- });
- cellPositioner = createMasonryCellPositioner({
- cellMeasurerCache: this.cellMeasurerCache,
- columnCount: this.columnCount,
- columnWidth: this.columnWidth,
- spacer: this.spacer,
- });
- cellRenderer = ({index, key, parent, style, isScrolling}) => {
- const image = this.props.images.items[index];
- if (!image) {
- console.log('!image (empty image with index: ', index, 'style', style);
- return;
- }
- console.group('image: ', image.name, image);
- console.log('cellImage:', index + 1, 'из', this.props.images.items.length);
- console.log('style:', style);
- console.log('isScrolling: ', isScrolling);
- console.groupEnd();
- if (image.name === `addImage`) {
- return (
- <CellMeasurer cache={this.cellMeasurerCache} index={index} key={key} parent={parent}>
- <div style={{
- ...style,
- width: this.columnWidth
- }}>
- <div className={styles.firstImage}>
- <button className={styles.openButton} onClick={this.openModal}>
- <IconAppend/>
- </button>
- <div className={styles.addImage}>Add New Image</div>
- </div>
- </div>
- </CellMeasurer>
- )
- }
- return (
- <CellMeasurer cache={this.cellMeasurerCache} index={index} key={key} parent={parent}>
- <div
- style={{
- ...style,
- width: this.columnWidth
- }}
- >
- <div
- className={styles.image}
- style={{backgroundImage: `url(${API}/static/${image.url})`}}
- />
- </div>
- </CellMeasurer>
- )
- };
- onResize = ({width}) => {
- this.columnCount = Math.floor((width + this.spacer) / (this.columnWidth + this.spacer));
- this.resetCellPositioner();
- };
- resetCellPositioner = () => {
- console.log('START_resetCellPositioner', 'this.props.images', this.props.images);
- this.cellPositioner.reset({
- columnCount: this.columnCount,
- columnWidth: this.columnWidth,
- spacer: this.spacer,
- });
- if (this.masonry) {
- this.masonry.recomputeCellPositions()
- }
- console.log('END_resetCellPositioner', 'this.props.images', this.props.images);
- };
- listenScroll = ({clientHeight, scrollHeight, scrollTop}) => {
- const infiniteBarrier = Math.abs(scrollHeight - clientHeight);
- const isFinalImage = (this.props.images.items.length >= this.props.images.count);
- const shouldLoadMore = scrollTop >= infiniteBarrier && !isFinalImage;
- if (!shouldLoadMore) {
- return;
- }
- const search = this.props.location.search;
- let searchParams = new URLSearchParams(search);
- let skip = this.state.skip + this.state.limit;
- this.setState({skip: skip});
- searchParams.set('skip', skip);
- searchParams.set('limit', this.state.limit);
- this.props.imagesActions.getMoreImages(searchParams);
- };
- render() {
- const speed = this.state.speed;
- console.log('length: ', this.props.images.items.length);
- return (
- <div className={styles.wrapper}>
- <Modal
- isOpen={this.state.modalIsOpen}
- onClose={this.closeModal}
- onRequestClose={this.closeModal}
- closeTimeoutMS={speed}
- className={styles.modal}
- overlayClassName={styles.overlay}
- >
- <Button
- onClick={this.closeModal}
- type="button"
- disabled=''
- name="×"
- className={styles.closeButton}
- />
- <AddImageForm onSubmit={this.addImage}/>
- </Modal>
- <WindowScroller>
- {
- ({height, scrollTop}) => (
- <AutoSizer
- disableHeight
- scrollTop={scrollTop}
- onResize={this.onResize}
- >
- {
- ({width}) => (
- <Masonry
- forceUpdateMasonry={this.props.images.items}
- autoHeight
- cellCount={this.props.images.items.length}
- cellMeasurerCache={this.cellMeasurerCache}
- cellPositioner={this.cellPositioner}
- cellRenderer={this.cellRenderer}
- scrollTop={scrollTop}
- onScroll={this.listenScroll}
- scrollingResetTimeInterval={150}
- height={height}
- width={width}
- ref={(ref) => {
- this.masonry = ref
- }}
- className={styles.masonry}
- />
- )
- }
- </AutoSizer>
- )
- }
- </WindowScroller>
- </div>
- );
- }
- }
- const IconAppend = () => {
- return (
- <svg className={styles.iconAppend} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
- <circle cx="64" cy="64" r="64"/>
- <path fill='white'
- d="M103 57H71V25c0-.6-.4-1-1-1H58c-.6 0-1 .4-1 1v32H25c-.6 0-1 .4-1 1v12c0 .6.4 1 1 1h32v32c0 .6.4 1 1 1h12c.6 0 1-.4 1-1V71h32c.6 0 1-.4 1-1V58c0-.6-.4-1-1-1z"/>
- </svg>
- )
- };
- export default ImageList;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement