import PropTypes from 'prop-types'; import React, { Component } from 'react'; 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 Measure from 'Components/Measure'; import ArtistIndexItemConnector from 'Artist/Index/ArtistIndexItemConnector'; import ArtistIndexOverview from './ArtistIndexOverview'; import styles from './ArtistIndexOverviews.css'; // Poster container dimensions const columnPadding = parseInt(dimensions.artistIndexColumnPadding); const columnPaddingSmallScreen = parseInt(dimensions.artistIndexColumnPaddingSmallScreen); const progressBarHeight = parseInt(dimensions.progressBarSmallHeight); const detailedProgressBarHeight = parseInt(dimensions.progressBarMediumHeight); function calculatePosterWidth(posterSize, isSmallScreen) { const maxiumPosterWidth = isSmallScreen ? 192 : 202; if (posterSize === 'large') { return maxiumPosterWidth; } if (posterSize === 'medium') { return Math.floor(maxiumPosterWidth * 0.75); } return Math.floor(maxiumPosterWidth * 0.5); } function calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions) { const { detailedProgressBar } = overviewOptions; const heights = [ posterHeight, detailedProgressBar ? detailedProgressBarHeight : progressBarHeight, isSmallScreen ? columnPaddingSmallScreen : columnPadding ]; return heights.reduce((acc, height) => acc + height, 0); } function calculatePosterHeight(posterWidth) { return posterWidth; } class ArtistIndexOverviews extends Component { // // Lifecycle constructor(props, context) { super(props, context); this.state = { width: 0, columnCount: 1, posterWidth: 238, posterHeight: 238, rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {}) }; this._grid = null; } componentDidUpdate(prevProps, prevState) { const { items, sortKey, overviewOptions, jumpToCharacter } = this.props; const { width, rowHeight } = this.state; if (prevProps.sortKey !== sortKey || prevProps.overviewOptions !== overviewOptions) { this.calculateGrid(); } 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 (this._grid && index != null) { this._grid.scrollToCell({ rowIndex: index, columnIndex: 0 }); } } } // // Control setGridRef = (ref) => { this._grid = ref; } calculateGrid = (width = this.state.width, isSmallScreen) => { const { sortKey, overviewOptions } = this.props; const posterWidth = calculatePosterWidth(overviewOptions.size, isSmallScreen); const posterHeight = calculatePosterHeight(posterWidth); const rowHeight = calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions); this.setState({ width, posterWidth, posterHeight, rowHeight }); } cellRenderer = ({ key, rowIndex, style }) => { const { items, sortKey, overviewOptions, showRelativeDates, shortDateFormat, longDateFormat, timeFormat, isSmallScreen } = this.props; const { posterWidth, posterHeight, rowHeight } = this.state; const artist = items[rowIndex]; if (!artist) { return null; } return (
); } // // Listeners onMeasure = ({ width }) => { this.calculateGrid(width, this.props.isSmallScreen); } // // Render render() { const { items, isSmallScreen, scroller } = this.props; const { width, rowHeight } = this.state; return ( {({ height, registerChild, onChildScroll, scrollTop }) => { if (!height) { return
; } return (
); } } ); } } ArtistIndexOverviews.propTypes = { items: PropTypes.arrayOf(PropTypes.object).isRequired, sortKey: PropTypes.string, overviewOptions: PropTypes.object.isRequired, scrollTop: PropTypes.number.isRequired, jumpToCharacter: PropTypes.string, 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 }; export default ArtistIndexOverviews;