diff --git a/frontend/src/Components/Page/PageJumpBar.js b/frontend/src/Components/Page/PageJumpBar.js index 41df52dfc..4b73ad4cb 100644 --- a/frontend/src/Components/Page/PageJumpBar.js +++ b/frontend/src/Components/Page/PageJumpBar.js @@ -1,4 +1,3 @@ -import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import dimensions from 'Styles/Variables/dimensions'; @@ -18,7 +17,7 @@ class PageJumpBar extends Component { this.state = { height: 0, - visibleItems: props.items + visibleItems: props.items.order }; } @@ -52,29 +51,47 @@ class PageJumpBar extends Component { minimumItems } = this.props; + if (!items) { + return; + } + + const { + characters, + order + } = items; + const height = this.state.height; const maximumItems = Math.floor(height / ITEM_HEIGHT); - const diff = items.length - maximumItems; + const diff = order.length - maximumItems; if (diff < 0) { - this.setState({ visibleItems: items }); + this.setState({ visibleItems: order }); return; } - if (items.length < minimumItems) { - this.setState({ visibleItems: items }); + if (order.length < minimumItems) { + this.setState({ visibleItems: order }); return; } - const removeDiff = Math.ceil(items.length / maximumItems); + // get first, last, and most common in between to make up numbers + const visibleItems = [order[0]]; - const visibleItems = _.reduce(items, (acc, item, index) => { - if (index % removeDiff === 0) { - acc.push(item); + const sorted = order.slice(1, -1).map((x) => characters[x]).sort((a, b) => b - a); + const minCount = sorted[maximumItems - 3]; + const greater = sorted.reduce((acc, value) => acc + (value > minCount ? 1 : 0), 0); + let minAllowed = maximumItems - 2 - greater; + + for (let i = 1; i < order.length - 1; i++) { + if (characters[order[i]] > minCount) { + visibleItems.push(order[i]); + } else if (characters[order[i]] === minCount && minAllowed > 0) { + visibleItems.push(order[i]); + minAllowed--; } + } - return acc; - }, []); + visibleItems.push(order[order.length - 1]); this.setState({ visibleItems }); } @@ -129,7 +146,7 @@ class PageJumpBar extends Component { } PageJumpBar.propTypes = { - items: PropTypes.arrayOf(PropTypes.string).isRequired, + items: PropTypes.object.isRequired, minimumItems: PropTypes.number.isRequired, onItemPress: PropTypes.func.isRequired }; diff --git a/frontend/src/Components/Page/PageJumpBarItem.css b/frontend/src/Components/Page/PageJumpBarItem.css index e829dd31a..f1a0c3699 100644 --- a/frontend/src/Components/Page/PageJumpBarItem.css +++ b/frontend/src/Components/Page/PageJumpBarItem.css @@ -1,5 +1,5 @@ .jumpBarItem { - flex: 1 0 $jumpBarItemHeight; + flex: 1 1 $jumpBarItemHeight; border-bottom: 1px solid $borderColor; text-align: center; font-weight: bold; diff --git a/frontend/src/Series/Index/SeriesIndex.js b/frontend/src/Series/Index/SeriesIndex.js index c696786cf..45138b221 100644 --- a/frontend/src/Series/Index/SeriesIndex.js +++ b/frontend/src/Series/Index/SeriesIndex.js @@ -47,7 +47,7 @@ class SeriesIndex extends Component { this.state = { contentBody: null, - jumpBarItems: [], + jumpBarItems: { order: [] }, jumpToCharacter: null, isPosterOptionsModalOpen: false, isOverviewOptionsModalOpen: false, @@ -95,28 +95,39 @@ class SeriesIndex extends Component { // Reset if not sorting by sortTitle if (sortKey !== 'sortTitle') { - this.setState({ jumpBarItems: [] }); + this.setState({ jumpBarItems: { order: [] } }); return; } const characters = _.reduce(items, (acc, item) => { - const firstCharacter = item.sortTitle.charAt(0); + let char = item.sortTitle.charAt(0); - if (isNaN(firstCharacter)) { - acc.push(firstCharacter); + if (!isNaN(char)) { + char = '#'; + } + + if (char in acc) { + acc[char] = acc[char] + 1; } else { - acc.push('#'); + acc[char] = 1; } return acc; - }, []).sort(); + }, {}); + + const order = Object.keys(characters).sort(); // Reverse if sorting descending if (sortDirection === sortDirections.DESCENDING) { - characters.reverse(); + order.reverse(); } - this.setState({ jumpBarItems: _.sortedUniq(characters) }); + const jumpBarItems = { + characters, + order + }; + + this.setState({ jumpBarItems }); } // @@ -340,7 +351,7 @@ class SeriesIndex extends Component { { - isLoaded && !!jumpBarItems.length && + isLoaded && !!jumpBarItems.order.length &&