/** * Virtualized Discovery Grid * High-performance grid component for large discovery datasets */ import React, { useState, useEffect, useMemo, useCallback } from 'react' import { FixedSizeGrid as Grid } from 'react-window' import { MediaItem } from '../api/jellyfin' import { MediaCard } from './MediaCard' interface VirtualizedDiscoveryGridProps { items: MediaItem[] onDiscoverDownload: (item: MediaItem) => void type: 'song' | 'album' containerHeight?: number itemWidth?: number itemHeight?: number } interface GridCellProps { columnIndex: number rowIndex: number style: React.CSSProperties data: { items: MediaItem[] columnsPerRow: number onDiscoverDownload: (item: MediaItem) => void type: 'song' | 'album' } } const GridCell: React.FC = ({ columnIndex, rowIndex, style, data }) => { const { items, columnsPerRow, onDiscoverDownload, type } = data const itemIndex = rowIndex * columnsPerRow + columnIndex const item = items[itemIndex] if (!item) { return
} return (
) } export const VirtualizedDiscoveryGrid: React.FC = ({ items, onDiscoverDownload, type, containerHeight = 600, itemWidth = 200, itemHeight = 280 }) => { const [containerWidth, setContainerWidth] = useState(0) const containerRef = useRef(null) // Calculate grid dimensions const columnsPerRow = useMemo(() => { if (containerWidth === 0) return 1 return Math.floor(containerWidth / itemWidth) }, [containerWidth, itemWidth]) const rowCount = useMemo(() => { return Math.ceil(items.length / columnsPerRow) }, [items.length, columnsPerRow]) // Update container width on resize useEffect(() => { const updateWidth = () => { if (containerRef.current) { setContainerWidth(containerRef.current.offsetWidth) } } updateWidth() window.addEventListener('resize', updateWidth) return () => window.removeEventListener('resize', updateWidth) }, []) // Grid data for react-window const gridData = useMemo(() => ({ items, columnsPerRow, onDiscoverDownload, type }), [items, columnsPerRow, onDiscoverDownload, type]) if (items.length === 0) { return (

No items to display

) } return (
{containerWidth > 0 && ( {GridCell} )}
) }