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 import { DappState } from '../../common/data/dapp' 9 10 class Dapps extends React.Component { 11 static scanHeaderPositions() { 12 const headerPositions = headerElements().map(element => ({ 13 id: element.id, 14 position: getYPosition(element), 15 })) 16 return headerPositions 17 } 18 19 constructor(props) { 20 super(props) 21 this.state = { 22 currentCategoryIndex: 0, 23 } 24 } 25 26 componentDidMount() { 27 this.boundScroll = debounce(this.handleScroll.bind(this), 150) 28 window.addEventListener('scroll', this.boundScroll) 29 } 30 31 componentWillUnmount() { 32 window.removeEventListener('scroll', this.boundScroll) 33 } 34 35 getCategories() { 36 const { dappState } = this.props 37 return [...dappState.categoryMap.keys()] 38 } 39 40 handleScroll() { 41 const currentHeader = document.getElementById(this.currentCategory()) 42 const headerPositions = Dapps.scanHeaderPositions() 43 const categories = this.getCategories() 44 45 const newHeader = [...headerPositions] 46 .reverse() 47 .find(header => header.position < window.scrollY) 48 49 if (!newHeader) { 50 return this.setState({ currentCategoryIndex: 0 }) 51 } 52 53 if (newHeader.id === currentHeader.id) { 54 return false 55 } 56 57 const newIndex = categories.indexOf(newHeader.id) 58 59 return this.setState({ currentCategoryIndex: newIndex }) 60 } 61 62 currentCategory() { 63 const { currentCategoryIndex } = this.state 64 const categories = this.getCategories() 65 return categories[currentCategoryIndex] 66 } 67 68 isCurrentCategory(category) { 69 return category === this.currentCategory() 70 } 71 72 render() { 73 const { dappState } = this.props 74 const categories = this.getCategories() 75 76 return ( 77 <div className={styles.list}> 78 {categories.map(category => ( 79 <div key={category}> 80 <div id={category} className="category-header"> 81 <CategoryHeader 82 text={category} 83 active={this.isCurrentCategory(category)} 84 /> 85 </div> 86 <DappList dapps={dappState.getDappsByCategory(category)} /> 87 </div> 88 ))} 89 </div> 90 ) 91 } 92 } 93 94 Dapps.propTypes = { 95 dappState: PropTypes.instanceOf(DappState).isRequired, 96 } 97 98 export default Dapps