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

140 lines
3.2 KiB
TypeScript
Raw Normal View History

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