import { Cast, Heart, Maximize2, Music } from 'lucide-react'; import type { TFunction } from 'i18next'; import { queueSongRating } from '../../store/pendingStarSync'; import type { InternetRadioStation, SubsonicAlbum, SubsonicOpenArtistRef } from '../../api/subsonicTypes'; import type { PlayerState, Track } from '../../store/playerStoreTypes'; import type { RadioMetadata } from '../../hooks/useRadioMetadata'; import type { PreviewingTrack } from '../../store/previewStore'; import CachedImage from '../CachedImage'; import LastfmIcon from '../LastfmIcon'; import MarqueeText from '../MarqueeText'; import { OpenArtistRefInline } from '../OpenArtistRefInline'; import StarRating from '../StarRating'; import { PlaybackBufferingOverlay } from '../playback/PlaybackBufferingOverlay'; import { usePlayerStore } from '../../store/playerStore'; import { usePlayerBarLayoutStore, type PlayerBarLayoutItemId, } from '../../store/playerBarLayoutStore'; interface Props { currentTrack: Track | null; currentRadio: InternetRadioStation | null; isRadio: boolean; radioMeta: RadioMetadata; radioCoverSrc: string; radioCoverKey: string; coverSrc: string; coverKey: string; displayCoverArt: string | undefined; displayTitle: string; displayArtist: string; /** When set (OpenSubsonic `artists` on the playing track), render split links like album track rows. */ displayArtistRefs?: SubsonicOpenArtistRef[]; showPreviewMeta: boolean; previewingTrack: PreviewingTrack | null; isStarred: boolean; toggleStar: () => void; lastfmSessionKey: string | null; lastfmLoved: boolean; toggleLastfmLove: () => void; userRatingOverrides: Record; toggleFullscreen: () => void; navigate: (to: string) => void | Promise; openContextMenu: PlayerState['openContextMenu']; t: TFunction; } export function PlayerTrackInfo({ currentTrack, currentRadio, isRadio, radioMeta, radioCoverSrc, radioCoverKey, coverSrc, coverKey, displayCoverArt, displayTitle, displayArtist, displayArtistRefs, showPreviewMeta, previewingTrack, isStarred, toggleStar, lastfmSessionKey, lastfmLoved, toggleLastfmLove, userRatingOverrides, toggleFullscreen, navigate, openContextMenu, t, }: Props) { const showBufferingOverlay = usePlayerStore(s => s.isPlaybackBuffering); const layoutItems = usePlayerBarLayoutStore(s => s.items); const isLayoutVisible = (id: PlayerBarLayoutItemId) => layoutItems.find(i => i.id === id)?.visible !== false; return (
!isRadio && !showPreviewMeta && currentTrack && toggleFullscreen()} data-tooltip={!isRadio && !showPreviewMeta && currentTrack ? t('player.openFullscreen') : undefined} > {isRadio ? ( currentRadio?.coverArt ? ( ) : (
) ) : displayCoverArt ? ( ) : (
)} {currentTrack && !isRadio && !showPreviewMeta && ( )} {showBufferingOverlay && !isRadio && !showPreviewMeta && ( )}
{showPreviewMeta && ( {t('player.previewLabel')} )} !isRadio && !showPreviewMeta && currentTrack?.albumId && navigate(`/album/${currentTrack.albumId}`)} onContextMenu={!isRadio && !showPreviewMeta && currentTrack?.albumId ? (e) => { e.preventDefault(); const album: SubsonicAlbum = { id: currentTrack.albumId!, name: currentTrack.album, artist: currentTrack.artist, artistId: currentTrack.artistId ?? '', coverArt: currentTrack.coverArt, songCount: 0, duration: 0, }; openContextMenu(e.clientX, e.clientY, album, 'album', undefined, undefined, undefined, undefined, true); } : undefined} /> {!isRadio && displayArtistRefs && displayArtistRefs.length > 0 ? (
navigate(`/artist/${id}`)} as="none" linkTag="span" linkClassName="player-artist-link" />
) : ( !isRadio && !showPreviewMeta && currentTrack?.artistId && navigate(`/artist/${currentTrack.artistId}`)} /> )} {currentTrack && !isRadio && !showPreviewMeta && isLayoutVisible('starRating') && ( queueSongRating(currentTrack.id, r)} className="player-track-rating" ariaLabel={t('albumDetail.ratingLabel')} /> )} {isRadio && radioMeta.listeners != null && ( {t('radio.listenerCount', { count: radioMeta.listeners })} )}
{currentTrack && !isRadio && isLayoutVisible('favorite') && ( )} {currentTrack && !isRadio && lastfmSessionKey && isLayoutVisible('lastfmLove') && ( )}
); }