/ src / modules / Dapps / Dapps.jsx
Dapps.jsx
  1  import React from 'react'
  2  import PropTypes from 'prop-types'
  3  import { debounce } from 'debounce'
  4  import DappList from '../../common/components/DappList'
  5  import CategoryHeader from '../CategoryHeader'
  6  import styles from './Dapps.module.scss'
  7  import { headerElements, getYPosition } from './Dapps.utils'
  8  
  9  class Dapps extends React.Component {
 10    static scanHeaderPositions() {
 11      const headerPositions = headerElements().map(element => ({
 12        id: element.id,
 13        position: getYPosition(element),
 14      }))
 15      return headerPositions
 16    }
 17  
 18    constructor(props) {
 19      super(props)
 20      this.state = {
 21        currentCategoryIndex: 0,
 22      }
 23    }
 24  
 25    componentDidMount() {
 26      this.boundScroll = debounce(this.handleScroll.bind(this), 1)
 27      window.addEventListener('scroll', this.boundScroll)
 28      this.fetchDapps()
 29    }
 30  
 31    componentDidUpdate() {
 32      this.fetchDapps()
 33    }
 34  
 35    componentWillUnmount() {
 36      window.removeEventListener('scroll', this.boundScroll)
 37    }
 38  
 39    onFetchByCategory(category) {
 40      const { fetchByCategory } = this.props
 41      fetchByCategory(category)
 42    }
 43  
 44    getCategories() {
 45      const { dappsCategoryMap } = this.props
 46      return [...dappsCategoryMap.keys()]
 47    }
 48  
 49    fetchDapps() {
 50      const { dappsCategoryMap, fetchByCategory } = this.props
 51  
 52      dappsCategoryMap.forEach((dappState, category) => {
 53        if (dappState.canFetch() === false) return
 54        if (dappState.items.length >= 1) return
 55        fetchByCategory(category)
 56      })
 57    }
 58  
 59    handleScroll() {
 60      const currentHeader = document.getElementById(this.currentCategory())
 61      const headerPositions = Dapps.scanHeaderPositions()
 62      const categories = this.getCategories()
 63  
 64      const newHeader = [...headerPositions]
 65        .reverse()
 66        .find(header => header.position < window.scrollY)
 67  
 68      if (!newHeader) {
 69        return this.setState({ currentCategoryIndex: 0 })
 70      }
 71  
 72      if (newHeader.id === currentHeader.id) {
 73        return false
 74      }
 75  
 76      const newIndex = categories.indexOf(newHeader.id)
 77  
 78      return this.setState({ currentCategoryIndex: newIndex })
 79    }
 80  
 81    currentCategory() {
 82      const { currentCategoryIndex } = this.state
 83      const categories = this.getCategories()
 84      return categories[currentCategoryIndex]
 85    }
 86  
 87    isCurrentCategory(category) {
 88      return category === this.currentCategory()
 89    }
 90  
 91    render() {
 92      const { dappsCategoryMap } = this.props
 93      const categories = this.getCategories()
 94  
 95      return (
 96        <div className={styles.list}>
 97          {categories.map(category => (
 98            <div key={category}>
 99              <div id={category} className="category-header">
100                <CategoryHeader
101                  text={category}
102                  active={this.isCurrentCategory(category)}
103                />
104              </div>
105              <DappList dapps={dappsCategoryMap.get(category).items} />
106              {dappsCategoryMap.get(category).canFetch() && (
107                <div
108                  className={styles.loadMore}
109                  onClick={this.onFetchByCategory.bind(this, category)}
110                >
111                  Load more dApps from {category}{' '}
112                </div>
113              )}
114            </div>
115          ))}
116        </div>
117      )
118    }
119  }
120  
121  // Dapps.propTypes = {
122  //   categories: PropTypes.arrayOf(
123  //     PropTypes.shape({ category: PropTypes.string, dapps: DappListModel }),
124  //   ).isRequired,
125  // }
126  Dapps.propTypes = {
127    dappsCategoryMap: PropTypes.instanceOf(Map).isRequired,
128    fetchByCategory: PropTypes.func.isRequired,
129  }
130  
131  export default Dapps