Advertisement
Guest User

Why doesn't Masonry refresh indexes of cells (cellCount) on

a guest
Nov 22nd, 2017
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, {Component} from 'react';
  2. import {
  3.     CellMeasurer,
  4.     CellMeasurerCache,
  5.     createMasonryCellPositioner,
  6.     Masonry,
  7.     AutoSizer,
  8.     WindowScroller,
  9. } from 'react-virtualized';
  10.  
  11. import Modal from '../../../components/Modal';
  12. import Button from '../../../components/Button';
  13. import AddImageForm from '../AddImageForm';
  14.  
  15. import styles from './styles.css';
  16.  
  17. const API = process.env.API || 'http://localhost:3001/api';
  18.  
  19. class ImageList extends Component {
  20.     constructor(props) {
  21.         super(props);
  22.         this.columnCount = 0;
  23.         this.columnHeights = {};
  24.  
  25.         this.columnWidth = 238;
  26.         this.columnHeight = 132;
  27.         this.spacer = 20;
  28.  
  29.         this.state = {
  30.             modalIsOpen: false,
  31.             speed: 100,
  32.             skip: 0,
  33.             limit: 24
  34.         };
  35.         this.openModal = this.openModal.bind(this);
  36.         this.closeModal = this.closeModal.bind(this);
  37.     }
  38.  
  39.     componentDidMount() {
  40.         const search = this.props.location.search;
  41.  
  42.         if (search) {
  43.             let searchParams = new URLSearchParams(search);
  44.             searchParams.set('skip', this.state.skip);
  45.             searchParams.set('limit', this.state.limit);
  46.  
  47.             this.props.imagesActions.getImages(searchParams);
  48.         }
  49.     }
  50.  
  51.     componentWillReceiveProps(nextProps) {
  52.         const search = this.props.location.search;
  53.         const nextSearch = nextProps.location.search;
  54.  
  55.         if (search !== nextSearch) {
  56.             let searchParams = new URLSearchParams(nextSearch);
  57.             searchParams.set('skip', 0);
  58.             searchParams.set('limit', this.state.limit);
  59.  
  60.             this.props.imagesActions.getImages(searchParams);
  61.         }
  62.     };
  63.  
  64.     openModal() {
  65.         this.setState({modalIsOpen: true});
  66.     };
  67.  
  68.     closeModal() {
  69.         this.setState({modalIsOpen: false});
  70.     };
  71.  
  72.     addImage = (values) => {
  73.         this.closeModal();
  74.         return this.props.imagesActions.addImage(values);
  75.     };
  76.  
  77.     cellMeasurerCache = new CellMeasurerCache({
  78.         defaultWidth: this.columnWidth,
  79.         defaultHeight: this.columnHeight,
  80.         fixedWidth: true,
  81.     });
  82.  
  83.     cellPositioner = createMasonryCellPositioner({
  84.         cellMeasurerCache: this.cellMeasurerCache,
  85.         columnCount: this.columnCount,
  86.         columnWidth: this.columnWidth,
  87.         spacer: this.spacer,
  88.     });
  89.  
  90.     cellRenderer = ({index, key, parent, style, isScrolling}) => {
  91.         const image = this.props.images.items[index];
  92.  
  93.         if (!image) {
  94.             console.log('!image (empty image with index: ', index, 'style', style);
  95.             return;
  96.         }
  97.  
  98.         console.group('image: ', image.name, image);
  99.         console.log('cellImage:', index + 1, 'из', this.props.images.items.length);
  100.         console.log('style:', style);
  101.         console.log('isScrolling: ', isScrolling);
  102.         console.groupEnd();
  103.  
  104.         if (image.name === `addImage`) {
  105.             return (
  106.                 <CellMeasurer cache={this.cellMeasurerCache} index={index} key={key} parent={parent}>
  107.                     <div style={{
  108.                         ...style,
  109.                         width: this.columnWidth
  110.                     }}>
  111.                         <div className={styles.firstImage}>
  112.                             <button className={styles.openButton} onClick={this.openModal}>
  113.                                 <IconAppend/>
  114.                             </button>
  115.                             <div className={styles.addImage}>Add New Image</div>
  116.                         </div>
  117.                     </div>
  118.                 </CellMeasurer>
  119.             )
  120.         }
  121.  
  122.         return (
  123.             <CellMeasurer cache={this.cellMeasurerCache} index={index} key={key} parent={parent}>
  124.                 <div
  125.                     style={{
  126.                         ...style,
  127.                         width: this.columnWidth
  128.                     }}
  129.                 >
  130.                     <div
  131.                         className={styles.image}
  132.                         style={{backgroundImage: `url(${API}/static/${image.url})`}}
  133.                     />
  134.                 </div>
  135.             </CellMeasurer>
  136.         )
  137.     };
  138.  
  139.     onResize = ({width}) => {
  140.         this.columnCount = Math.floor((width + this.spacer) / (this.columnWidth + this.spacer));
  141.         this.resetCellPositioner();
  142.     };
  143.  
  144.     resetCellPositioner = () => {
  145.         console.log('START_resetCellPositioner', 'this.props.images', this.props.images);
  146.  
  147.         this.cellPositioner.reset({
  148.             columnCount: this.columnCount,
  149.             columnWidth: this.columnWidth,
  150.             spacer: this.spacer,
  151.         });
  152.  
  153.         if (this.masonry) {
  154.             this.masonry.recomputeCellPositions()
  155.         }
  156.         console.log('END_resetCellPositioner', 'this.props.images', this.props.images);
  157.     };
  158.  
  159.     listenScroll = ({clientHeight, scrollHeight, scrollTop}) => {
  160.         const infiniteBarrier = Math.abs(scrollHeight - clientHeight);
  161.         const isFinalImage = (this.props.images.items.length >= this.props.images.count);
  162.         const shouldLoadMore = scrollTop >= infiniteBarrier && !isFinalImage;
  163.  
  164.         if (!shouldLoadMore) {
  165.             return;
  166.         }
  167.  
  168.         const search = this.props.location.search;
  169.         let searchParams = new URLSearchParams(search);
  170.         let skip = this.state.skip + this.state.limit;
  171.         this.setState({skip: skip});
  172.         searchParams.set('skip', skip);
  173.         searchParams.set('limit', this.state.limit);
  174.  
  175.         this.props.imagesActions.getMoreImages(searchParams);
  176.     };
  177.  
  178.     render() {
  179.         const speed = this.state.speed;
  180.         console.log('length: ', this.props.images.items.length);
  181.  
  182.         return (
  183.             <div className={styles.wrapper}>
  184.                 <Modal
  185.                     isOpen={this.state.modalIsOpen}
  186.                     onClose={this.closeModal}
  187.                     onRequestClose={this.closeModal}
  188.                     closeTimeoutMS={speed}
  189.                     className={styles.modal}
  190.                     overlayClassName={styles.overlay}
  191.                 >
  192.                     <Button
  193.                         onClick={this.closeModal}
  194.                         type="button"
  195.                         disabled=''
  196.                         name="×"
  197.                         className={styles.closeButton}
  198.                     />
  199.                     <AddImageForm onSubmit={this.addImage}/>
  200.                 </Modal>
  201.  
  202.                 <WindowScroller>
  203.                     {
  204.                         ({height, scrollTop}) => (
  205.                             <AutoSizer
  206.                                 disableHeight
  207.                                 scrollTop={scrollTop}
  208.                                 onResize={this.onResize}
  209.                             >
  210.                                 {
  211.                                     ({width}) => (
  212.                                         <Masonry
  213.                                             forceUpdateMasonry={this.props.images.items}
  214.                                             autoHeight
  215.                                             cellCount={this.props.images.items.length}
  216.                                             cellMeasurerCache={this.cellMeasurerCache}
  217.                                             cellPositioner={this.cellPositioner}
  218.                                             cellRenderer={this.cellRenderer}
  219.                                             scrollTop={scrollTop}
  220.                                             onScroll={this.listenScroll}
  221.                                             scrollingResetTimeInterval={150}
  222.                                             height={height}
  223.                                             width={width}
  224.                                             ref={(ref) => {
  225.                                                 this.masonry = ref
  226.                                             }}
  227.                                             className={styles.masonry}
  228.                                         />
  229.                                     )
  230.                                 }
  231.                             </AutoSizer>
  232.                         )
  233.                     }
  234.                 </WindowScroller>
  235.             </div>
  236.         );
  237.     }
  238. }
  239.  
  240. const IconAppend = () => {
  241.     return (
  242.         <svg className={styles.iconAppend} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
  243.             <circle cx="64" cy="64" r="64"/>
  244.             <path fill='white'
  245.                   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"/>
  246.         </svg>
  247.     )
  248. };
  249.  
  250. export default ImageList;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement