import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ChevronLeft, ChevronRight, Users } from 'lucide-react'; import { ArtistCoverArtImage } from '../../cover/ArtistCoverArtImage'; import { COVER_DENSE_GRID_MIN_CELL_CSS_PX } from '../../cover/layoutSizes'; import { coverServerScopeForServerId } from '../../cover/serverScope'; export interface TopFavoriteArtist { id: string; name: string; count: number; coverArtId: string; /** Present when favorites are merged across servers. */ serverId?: string; /** Raw artist id for song filtering (without server prefix). */ artistId?: string; } interface TopFavoriteArtistsRowProps { title: string; artists: TopFavoriteArtist[]; selectedKey: string | null; onToggle: (key: string) => void; } export function TopFavoriteArtistsRow({ title, artists, selectedKey, onToggle }: TopFavoriteArtistsRowProps) { const { t } = useTranslation(); const scrollRef = useRef(null); const [showLeft, setShowLeft] = useState(false); const [showRight, setShowRight] = useState(true); const handleScroll = () => { if (!scrollRef.current) return; const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current; setShowLeft(scrollLeft > 0); setShowRight(scrollLeft < scrollWidth - clientWidth - 5); }; useEffect(() => { handleScroll(); window.addEventListener('resize', handleScroll); return () => window.removeEventListener('resize', handleScroll); }, [artists]); const scroll = (dir: 'left' | 'right') => { if (!scrollRef.current) return; const amount = scrollRef.current.clientWidth * 0.75; scrollRef.current.scrollBy({ left: dir === 'left' ? -amount : amount, behavior: 'smooth' }); }; return (

{title}

{artists.map(a => ( onToggle(a.id)} songCountLabel={t('favorites.topArtistsSongCount', { count: a.count })} /> ))}
); } interface TopFavoriteArtistCardProps { artist: TopFavoriteArtist; isSelected: boolean; onClick: () => void; songCountLabel: string; } function TopFavoriteArtistCard({ artist, isSelected, onClick, songCountLabel }: TopFavoriteArtistCardProps) { const coverId = artist.coverArtId; const artistEntityId = artist.artistId ?? artist.coverArtId; return (
{coverId ? ( { e.currentTarget.style.display = 'none'; e.currentTarget.parentElement?.classList.add('fallback-visible'); }} /> ) : ( )}
{artist.name} {songCountLabel}
); }