import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { ChevronDown, ChevronRight, Disc3, ListMusic, Loader2, Shuffle, Users, Zap, } from 'lucide-react'; import type { SubsonicAlbum, SubsonicArtist, SubsonicPlaylist, } from '@/lib/api/subsonicTypes'; import type { DeviceSyncSource } from '@/features/deviceSync/store/deviceSyncStore'; import type { SourceTab } from '@/features/deviceSync/utils/deviceSyncHelpers'; import BrowserRow from '@/features/deviceSync/components/BrowserRow'; interface Props { activeTab: SourceTab; setActiveTab: (t: SourceTab) => void; search: string; setSearch: (v: string) => void; playlists: SubsonicPlaylist[]; randomAlbums: SubsonicAlbum[]; albumSearchResults: SubsonicAlbum[]; albumSearchLoading: boolean; artists: SubsonicArtist[]; loadingBrowser: boolean; expandedArtistIds: Set; artistAlbumsMap: Map; loadingArtistIds: Set; toggleArtistExpand: (artistId: string) => Promise; sources: DeviceSyncSource[]; pendingDeletion: string[]; handleToggleSource: (source: DeviceSyncSource) => void; } export default function DeviceSyncBrowserPanel({ activeTab, setActiveTab, search, setSearch, playlists, randomAlbums, albumSearchResults, albumSearchLoading, artists, loadingBrowser, expandedArtistIds, artistAlbumsMap, loadingArtistIds, toggleArtistExpand, sources, pendingDeletion, handleToggleSource, }: Props) { const { t } = useTranslation(); const tabs: { key: SourceTab; icon: React.ReactNode; label: string }[] = [ { key: 'playlists', icon: , label: t('deviceSync.tabPlaylists') }, { key: 'albums', icon: , label: t('deviceSync.tabAlbums') }, { key: 'artists', icon: , label: t('deviceSync.tabArtists') }, ]; const q = search.toLowerCase(); const filteredPlaylists = useMemo(() => playlists.filter(p => p.name.toLowerCase().includes(q)), [playlists, q]); const filteredArtists = useMemo(() => artists.filter(a => a.name.toLowerCase().includes(q)), [artists, q]); return (
{tabs.map(tab => ( ))}
setSearch(e.target.value)} /> {activeTab === 'albums' && ( {t('deviceSync.liveSearch')} )}
{(loadingBrowser || albumSearchLoading) && (
)} {activeTab === 'albums' && !search.trim() && !loadingBrowser && randomAlbums.length > 0 && (
{t('deviceSync.randomAlbumsLabel')}
)} {activeTab === 'playlists' && filteredPlaylists.map(pl => ( s.id === pl.id) && !pendingDeletion.includes(pl.id)} onToggle={() => handleToggleSource({ type: 'playlist', id: pl.id, name: pl.name })} /> ))} {activeTab === 'albums' && (search.trim() ? albumSearchResults : randomAlbums).map(al => ( s.id === al.id) && !pendingDeletion.includes(al.id)} onToggle={() => handleToggleSource({ type: 'album', id: al.id, name: al.name, artist: al.artist })} /> ))} {activeTab === 'artists' && filteredArtists.map(ar => (
{ar.name} {ar.albumCount != null && {ar.albumCount} Albums}
{expandedArtistIds.has(ar.id) && artistAlbumsMap.has(ar.id) && artistAlbumsMap.get(ar.id)!.map(al => ( s.id === al.id) && !pendingDeletion.includes(al.id)} indent onToggle={() => handleToggleSource({ type: 'album', id: al.id, name: al.name, artist: al.artist || ar.name })} /> )) }
))}
); }