Better selection of jump bar items

Show first, last and most common items
This commit is contained in:
ta264 2020-01-05 21:45:01 +00:00 committed by Mark McDowall
parent 792896c46b
commit 108f6fe393
3 changed files with 52 additions and 24 deletions

View File

@ -1,4 +1,3 @@
import _ from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import dimensions from 'Styles/Variables/dimensions'; import dimensions from 'Styles/Variables/dimensions';
@ -18,7 +17,7 @@ class PageJumpBar extends Component {
this.state = { this.state = {
height: 0, height: 0,
visibleItems: props.items visibleItems: props.items.order
}; };
} }
@ -52,29 +51,47 @@ class PageJumpBar extends Component {
minimumItems minimumItems
} = this.props; } = this.props;
if (!items) {
return;
}
const {
characters,
order
} = items;
const height = this.state.height; const height = this.state.height;
const maximumItems = Math.floor(height / ITEM_HEIGHT); const maximumItems = Math.floor(height / ITEM_HEIGHT);
const diff = items.length - maximumItems; const diff = order.length - maximumItems;
if (diff < 0) { if (diff < 0) {
this.setState({ visibleItems: items }); this.setState({ visibleItems: order });
return; return;
} }
if (items.length < minimumItems) { if (order.length < minimumItems) {
this.setState({ visibleItems: items }); this.setState({ visibleItems: order });
return; 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) => { const sorted = order.slice(1, -1).map((x) => characters[x]).sort((a, b) => b - a);
if (index % removeDiff === 0) { const minCount = sorted[maximumItems - 3];
acc.push(item); 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 }); this.setState({ visibleItems });
} }
@ -129,7 +146,7 @@ class PageJumpBar extends Component {
} }
PageJumpBar.propTypes = { PageJumpBar.propTypes = {
items: PropTypes.arrayOf(PropTypes.string).isRequired, items: PropTypes.object.isRequired,
minimumItems: PropTypes.number.isRequired, minimumItems: PropTypes.number.isRequired,
onItemPress: PropTypes.func.isRequired onItemPress: PropTypes.func.isRequired
}; };

View File

@ -1,5 +1,5 @@
.jumpBarItem { .jumpBarItem {
flex: 1 0 $jumpBarItemHeight; flex: 1 1 $jumpBarItemHeight;
border-bottom: 1px solid $borderColor; border-bottom: 1px solid $borderColor;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;

View File

@ -47,7 +47,7 @@ class SeriesIndex extends Component {
this.state = { this.state = {
contentBody: null, contentBody: null,
jumpBarItems: [], jumpBarItems: { order: [] },
jumpToCharacter: null, jumpToCharacter: null,
isPosterOptionsModalOpen: false, isPosterOptionsModalOpen: false,
isOverviewOptionsModalOpen: false, isOverviewOptionsModalOpen: false,
@ -95,28 +95,39 @@ class SeriesIndex extends Component {
// Reset if not sorting by sortTitle // Reset if not sorting by sortTitle
if (sortKey !== 'sortTitle') { if (sortKey !== 'sortTitle') {
this.setState({ jumpBarItems: [] }); this.setState({ jumpBarItems: { order: [] } });
return; return;
} }
const characters = _.reduce(items, (acc, item) => { const characters = _.reduce(items, (acc, item) => {
const firstCharacter = item.sortTitle.charAt(0); let char = item.sortTitle.charAt(0);
if (isNaN(firstCharacter)) { if (!isNaN(char)) {
acc.push(firstCharacter); char = '#';
}
if (char in acc) {
acc[char] = acc[char] + 1;
} else { } else {
acc.push('#'); acc[char] = 1;
} }
return acc; return acc;
}, []).sort(); }, {});
const order = Object.keys(characters).sort();
// Reverse if sorting descending // Reverse if sorting descending
if (sortDirection === sortDirections.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 {
</PageContentBodyConnector> </PageContentBodyConnector>
{ {
isLoaded && !!jumpBarItems.length && isLoaded && !!jumpBarItems.order.length &&
<PageJumpBar <PageJumpBar
items={jumpBarItems} items={jumpBarItems}
onItemPress={this.onJumpBarItemPress} onItemPress={this.onJumpBarItemPress}