feishin/src/renderer/components/virtual-grid/virtual-grid-wrapper.tsx

128 lines
2.8 KiB
TypeScript
Raw Normal View History

2022-12-19 15:59:14 -08:00
import type { Ref } from 'react';
import debounce from 'lodash/debounce';
import memoize from 'memoize-one';
import type { FixedSizeListProps } from 'react-window';
import { FixedSizeList } from 'react-window';
import styled from 'styled-components';
import { GridCard } from '/@/renderer/components/virtual-grid/grid-card';
2023-01-05 21:59:07 -08:00
import type { CardRow, ListDisplayType, CardRoute, PlayQueueAddOptions } from '/@/renderer/types';
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
2022-12-19 15:59:14 -08:00
const createItemData = memoize(
(
cardRows,
columnCount,
display,
itemCount,
itemData,
itemGap,
itemHeight,
itemType,
itemWidth,
route,
2022-12-20 04:11:06 -08:00
handlePlayQueueAdd,
2023-01-08 00:52:53 -08:00
handleFavorite,
2022-12-19 15:59:14 -08:00
) => ({
cardRows,
columnCount,
display,
2023-01-08 00:52:53 -08:00
handleFavorite,
2022-12-20 04:11:06 -08:00
handlePlayQueueAdd,
2022-12-19 15:59:14 -08:00
itemCount,
itemData,
itemGap,
itemHeight,
itemType,
itemWidth,
route,
}),
);
const createScrollHandler = memoize((onScroll) => debounce(onScroll, 250));
export const VirtualGridWrapper = ({
refInstance,
cardRows,
itemGap,
itemType,
itemWidth,
display,
itemHeight,
itemCount,
columnCount,
rowCount,
initialScrollOffset,
2023-01-08 00:52:53 -08:00
handleFavorite,
2022-12-20 04:11:06 -08:00
handlePlayQueueAdd,
2022-12-19 15:59:14 -08:00
itemData,
route,
onScroll,
2023-05-10 20:00:39 -07:00
height,
width,
2022-12-19 15:59:14 -08:00
...rest
2023-05-10 20:00:39 -07:00
}: Omit<FixedSizeListProps, 'ref' | 'itemSize' | 'children' | 'height' | 'width'> & {
2022-12-24 13:44:52 -08:00
cardRows: CardRow<Album | AlbumArtist | Artist>[];
2022-12-19 15:59:14 -08:00
columnCount: number;
2022-12-26 04:47:40 -08:00
display: ListDisplayType;
2023-01-08 00:52:53 -08:00
handleFavorite?: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void;
2022-12-20 04:11:06 -08:00
handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void;
2023-05-10 20:00:39 -07:00
height?: number;
2022-12-19 15:59:14 -08:00
itemData: any[];
itemGap: number;
itemHeight: number;
itemType: LibraryItem;
itemWidth: number;
refInstance: Ref<any>;
route?: CardRoute;
rowCount: number;
2023-05-10 20:00:39 -07:00
width?: number;
2022-12-19 15:59:14 -08:00
}) => {
const memoizedItemData = createItemData(
cardRows,
columnCount,
display,
itemCount,
itemData,
itemGap,
itemHeight,
itemType,
itemWidth,
route,
2022-12-20 04:11:06 -08:00
handlePlayQueueAdd,
2023-01-08 00:52:53 -08:00
handleFavorite,
2022-12-19 15:59:14 -08:00
);
const memoizedOnScroll = createScrollHandler(onScroll);
return (
<FixedSizeList
ref={refInstance}
{...rest}
2023-05-10 20:00:39 -07:00
height={(height && Number(height)) || 0}
2022-12-19 15:59:14 -08:00
initialScrollOffset={initialScrollOffset}
itemCount={rowCount}
itemData={memoizedItemData}
itemSize={itemHeight}
overscanCount={5}
2023-05-10 20:00:39 -07:00
width={(width && Number(width)) || 0}
2022-12-19 15:59:14 -08:00
onScroll={memoizedOnScroll}
>
{GridCard}
</FixedSizeList>
);
};
VirtualGridWrapper.defaultProps = {
route: undefined,
};
export const VirtualGridContainer = styled.div`
display: flex;
flex-direction: column;
height: 100%;
`;
export const VirtualGridAutoSizerContainer = styled.div`
flex: 1;
`;