1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-22 22:16:13 -04:00
Files
Sonarr/frontend/src/Components/Page/PageJumpBar.tsx
T
2025-02-11 19:34:34 -08:00

91 lines
2.2 KiB
TypeScript

import React, { useMemo } from 'react';
import useMeasure from 'Helpers/Hooks/useMeasure';
import dimensions from 'Styles/Variables/dimensions';
import PageJumpBarItem, { PageJumpBarItemProps } from './PageJumpBarItem';
import styles from './PageJumpBar.css';
const ITEM_HEIGHT = parseInt(dimensions.jumpBarItemHeight);
export interface PageJumpBarItems {
characters: Record<string, number>;
order: string[];
}
interface PageJumpBarProps {
items: PageJumpBarItems;
minimumItems?: number;
onItemPress: PageJumpBarItemProps['onItemPress'];
}
function PageJumpBar({
items,
minimumItems = 5,
onItemPress,
}: PageJumpBarProps) {
const [jumpBarRef, { height }] = useMeasure();
const visibleItems = useMemo(() => {
const { characters, order } = items;
const maximumItems = Math.floor(height / ITEM_HEIGHT);
const diff = order.length - maximumItems;
if (diff < 0) {
return order;
}
if (order.length < minimumItems) {
return order;
}
// get first, last, and most common in between to make up numbers
const result = [order[0]];
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) {
result.push(order[i]);
} else if (characters[order[i]] === minCount && minAllowed > 0) {
result.push(order[i]);
minAllowed--;
}
}
result.push(order[order.length - 1]);
return result;
}, [items, height, minimumItems]);
if (!items.order.length || items.order.length < minimumItems) {
return null;
}
return (
<div ref={jumpBarRef} className={styles.jumpBar}>
<div className={styles.jumpBarItems}>
{visibleItems.map((item) => {
return (
<PageJumpBarItem
key={item}
label={item}
onItemPress={onItemPress}
/>
);
})}
</div>
</div>
);
}
export default PageJumpBar;