import { MarqueeText } from '@/components/ui/marquee-text' import { cn } from '@/lib/utils' import { usePlayerStore } from '@/stores/playerStore' import { Disc3 } from 'lucide-react' import { motion } from 'motion/react' import { useEffect, useState } from 'react' import { LAYOUT_TRANSITION, SONG_INFO_TRANSITION } from './constants' interface NowPlayingProps { /** Compact mode: small cover + song info in a single row (lyric view top bar) */ compact?: boolean /** Called when the cover art is tapped (toggle lyric view) */ onCoverClick?: () => void } export function NowPlaying({ compact = false, onCoverClick }: NowPlayingProps) { const currentTrack = usePlayerStore((s) => s.currentTrack) const [failedCoverTrackId, setFailedCoverTrackId] = useState(null) // Skip layoutId on first frame to prevent unwanted entry animation const [ready, setReady] = useState(false) useEffect(() => { const frame = requestAnimationFrame(() => setReady(true)) return () => cancelAnimationFrame(frame) }, []) const layoutId = ready ? 'cover-art' : undefined const showCover = currentTrack?.cover && failedCoverTrackId !== currentTrack.id const coverContent = showCover ? ( {currentTrack.title} setFailedCoverTrackId(currentTrack.id)} /> ) : (
) // --------------------------------------------------------------------------- // Compact mode: small cover + song info in a horizontal row (lyric view) // --------------------------------------------------------------------------- if (compact) { return (
{coverContent} {currentTrack?.title ?? '暂无歌曲'} {currentTrack ? currentTrack.artist.join(' / ') : '...'}
) } // --------------------------------------------------------------------------- // Default mode: cover only (song info is handled by SongInfoBar) // --------------------------------------------------------------------------- return ( {coverContent} ) }