import React from 'react'; import type { NavigateFunction } from 'react-router-dom'; import type { Virtualizer } from '@tanstack/react-virtual'; import type { TFunction } from 'i18next'; import type { SubsonicArtist } from '../../api/subsonicTypes'; import type { PlayerState } from '../../store/playerStoreTypes'; import type { ArtistListFlatRow } from '../../utils/componentHelpers/artistsHelpers'; import { ArtistRowAvatar } from './ArtistAvatars'; interface RowProps { artist: SubsonicArtist; selectionMode: boolean; selectedIds: Set; selectedArtists: SubsonicArtist[]; showArtistImages: boolean; toggleSelect: (id: string) => void; navigate: NavigateFunction; openContextMenu: PlayerState['openContextMenu']; t: TFunction; } function ArtistListRow({ artist, selectionMode, selectedIds, selectedArtists, showArtistImages, toggleSelect, navigate, openContextMenu, t, }: RowProps) { return ( ); } interface Props { virtualized: boolean; groups: Record; letters: string[]; artistListFlatRows: ArtistListFlatRow[]; artistListVirtualizer: Virtualizer; selectionMode: boolean; selectedIds: Set; selectedArtists: SubsonicArtist[]; showArtistImages: boolean; toggleSelect: (id: string) => void; navigate: NavigateFunction; openContextMenu: PlayerState['openContextMenu']; t: TFunction; } /** * List view for the artists page. Two render paths: * - Non-virtualized — emits one `
` per starting * letter, used when the `disableMainstageVirtualLists` perf flag is on * (mostly for low-end devices where translate-Y positioning costs more * than the saved DOM nodes). * - Virtualized — flat `letter / artist / artist / …` row stream sitting * on a single absolutely-positioned `
` whose height matches the * virtualizer's totalSize. * * Both paths share `ArtistListRow` so click + context-menu behaviour is * identical regardless of the rendering path. */ export function ArtistsListView({ virtualized, groups, letters, artistListFlatRows, artistListVirtualizer, selectionMode, selectedIds, selectedArtists, showArtistImages, toggleSelect, navigate, openContextMenu, t, }: Props) { const rowCommonProps = { selectionMode, selectedIds, selectedArtists, showArtistImages, toggleSelect, navigate, openContextMenu, t, }; if (!virtualized) { return ( <> {letters.map(letter => (

{letter}

{groups[letter].map(artist => ( ))}
))} ); } return (
{artistListVirtualizer.getVirtualItems().map(vi => { const row = artistListFlatRows[vi.index]; if (!row) return null; if (row.kind === 'letter') { return (

{row.letter}

); } const artist = row.artist; return (
); })}
); }