@ -1,12 +1,9 @@
import _ from 'lodash' ;
import PropTypes from 'prop-types' ;
import React , { Component } from 'react' ;
import ReactDOM from 'react-dom' ;
import { Grid , WindowScroller } from 'react-virtualized' ;
import getIndexOfFirstCharacter from 'Utilities/Array/getIndexOfFirstCharacter' ;
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder' ;
import dimensions from 'Styles/Variables/dimensions' ;
import { sortDirections } from 'Helpers/Props' ;
import Measure from 'Components/Measure' ;
import ArtistIndexItemConnector from 'Artist/Index/ArtistIndexItemConnector' ;
import ArtistIndexOverview from './ArtistIndexOverview' ;
@ -66,56 +63,44 @@ class ArtistIndexOverviews extends Component {
rowHeight : calculateRowHeight ( 238 , null , props . isSmallScreen , { } )
} ;
this . _isInitialized = false ;
this . _grid = null ;
}
componentDidMount ( ) {
this . _contentBodyNode = ReactDOM . findDOMNode ( this . props . contentBody ) ;
}
componentDidUpdate ( prevProps ) {
componentDidUpdate ( prevProps , prevState ) {
const {
items ,
filters ,
sortKey ,
sortDirection ,
overviewOptions ,
jumpToCharacter
} = this . props ;
const itemsChanged = hasDifferentItemsOrOrder ( prevProps . items , items ) ;
const overviewOptionsChanged = ! _ . isMatch ( prevProps . overviewOptions , overviewOptions ) ;
const {
width ,
rowHeight
} = this . state ;
if (
prevProps . sortKey !== sortKey ||
prevProps . overviewOptions !== overviewOptions ||
itemsChanged
) {
if ( prevProps . sortKey !== sortKey ||
prevProps . overviewOptions !== overviewOptions ) {
this . calculateGrid ( ) ;
}
if (
prevProps . filters !== filters ||
prevProps . sortKey !== sortKey ||
prevProps . sortDirection !== sortDirection ||
itemsChanged ||
overviewOptionsChanged
) {
if ( this . _grid &&
( prevState . width !== width ||
prevState . rowHeight !== rowHeight ||
hasDifferentItemsOrOrder ( prevProps . items , items ) ) ) {
// recomputeGridSize also forces Grid to discard its cache of rendered cells
this . _grid . recomputeGridSize ( ) ;
}
if ( jumpToCharacter != null && jumpToCharacter !== prevProps . jumpToCharacter ) {
const index = getIndexOfFirstCharacter ( items , jumpToCharacter ) ;
if ( index != null ) {
const {
rowHeight
} = this . state ;
if ( this . _grid && index != null ) {
const scrollTop = rowHeight * index ;
this . props . onScroll ( { scrollTop } ) ;
this . _grid . scrollToCell ( {
rowIndex : index ,
columnIndex : 0
} ) ;
}
}
}
@ -123,21 +108,6 @@ class ArtistIndexOverviews extends Component {
//
// Control
scrollToFirstCharacter ( character ) {
const items = this . props . items ;
const {
rowHeight
} = this . state ;
const index = getIndexOfFirstCharacter ( items , character ) ;
if ( index != null ) {
const scrollTop = rowHeight * index ;
this . props . onScroll ( { scrollTop } ) ;
}
}
setGridRef = ( ref ) => {
this . _grid = ref ;
}
@ -217,22 +187,14 @@ class ArtistIndexOverviews extends Component {
this . calculateGrid ( width , this . props . isSmallScreen ) ;
}
onSectionRendered = ( ) => {
if ( ! this . _isInitialized && this . _contentBodyNode ) {
this . props . onRender ( ) ;
this . _isInitialized = true ;
}
}
//
// Render
render ( ) {
const {
items ,
scrollTop ,
isSmallScreen ,
onScroll
scroller
} = this . props ;
const {
@ -241,29 +203,39 @@ class ArtistIndexOverviews extends Component {
} = this . state ;
return (
< Measure onMeasure = { this . onMeasure } >
< Measure
whitelist = { [ 'width' ] }
onMeasure = { this . onMeasure }
>
< WindowScroller
scrollElement = { isSmallScreen ? undefined : this . _contentBodyNode }
onScroll = { onScroll }
scrollElement = { isSmallScreen ? undefined : scroller }
>
{ ( { height , isScrolling } ) => {
{ ( { height , registerChild , onChildScroll , scrollTop } ) => {
if ( ! height ) {
return < div / > ;
}
return (
< Grid
ref = { this . setGridRef }
className = { styles . grid }
autoHeight = { true }
height = { height }
columnCount = { 1 }
columnWidth = { width }
rowCount = { items . length }
rowHeight = { rowHeight }
width = { width }
scrollTop = { scrollTop }
overscanRowCount = { 2 }
cellRenderer = { this . cellRenderer }
onSectionRendered = { this . onSectionRendered }
isScrollingOptOut = { true }
/ >
< div ref = { registerChild } >
< Grid
ref = { this . setGridRef }
className = { styles . grid }
autoHeight = { true }
height = { height }
columnCount = { 1 }
columnWidth = { width }
rowCount = { items . length }
rowHeight = { rowHeight }
width = { width }
onScroll = { onChildScroll }
scrollTop = { scrollTop }
overscanRowCount = { 2 }
cellRenderer = { this . cellRenderer }
onSectionRendered = { this . onSectionRendered }
scrollToAlignment = { 'start' }
isScrollingOptOut = { true }
/ >
< / d i v >
) ;
}
}
@ -275,20 +247,16 @@ class ArtistIndexOverviews extends Component {
ArtistIndexOverviews . propTypes = {
items : PropTypes . arrayOf ( PropTypes . object ) . isRequired ,
filters : PropTypes . arrayOf ( PropTypes . object ) . isRequired ,
sortKey : PropTypes . string ,
sortDirection : PropTypes . oneOf ( sortDirections . all ) ,
overviewOptions : PropTypes . object . isRequired ,
scrollTop : PropTypes . number . isRequired ,
jumpToCharacter : PropTypes . string ,
contentBody: PropTypes . object . isRequired ,
scroller: PropTypes . instanceOf ( Element ) . isRequired ,
showRelativeDates : PropTypes . bool . isRequired ,
shortDateFormat : PropTypes . string . isRequired ,
longDateFormat : PropTypes . string . isRequired ,
isSmallScreen : PropTypes . bool . isRequired ,
timeFormat : PropTypes . string . isRequired ,
onRender : PropTypes . func . isRequired ,
onScroll : PropTypes . func . isRequired
timeFormat : PropTypes . string . isRequired
} ;
export default ArtistIndexOverviews ;