import React, { useEffect, useState, useRef } from 'react'; interface Metric { time: number; text: string; } interface LyricsDetailProps { track: any; currentTime: number; onClose: () => void; onSeek?: (time: number) => void; } const LyricsDetail: React.FC = ({ track, currentTime, onClose, onSeek }) => { const [lyrics, setLyrics] = useState([]); const [isLoading, setIsLoading] = useState(false); const scrollContainerRef = useRef(null); const activeLineRef = useRef(null); // Fetch Lyrics on Track Change useEffect(() => { const fetchLyrics = async () => { if (!track) return; setIsLoading(true); try { // Pass title and artist for LRCLIB fallback const apiUrl = process.env.NEXT_PUBLIC_API_URL || ''; const url = `${apiUrl}/api/lyrics?id=${track.id}&title=${encodeURIComponent(track.title)}&artist=${encodeURIComponent(track.artist)}`; const res = await fetch(url); const data = await res.json(); setLyrics(data || []); } catch (error) { console.error("Error fetching lyrics:", error); setLyrics([]); } finally { setIsLoading(false); } }; fetchLyrics(); }, [track?.id]); // Find active line index const activeIndex = lyrics.findIndex((line, index) => { const nextLine = lyrics[index + 1]; // Removing large offset to match music exactly. // using small buffer (0.05) just for rounding safety const timeWithOffset = currentTime + 0.05; return timeWithOffset >= line.time && (!nextLine || timeWithOffset < nextLine.time); }); // Auto-scroll to active line // Auto-scroll to active line useEffect(() => { if (activeLineRef.current && scrollContainerRef.current) { const container = scrollContainerRef.current; const activeLine = activeLineRef.current; // Calculate position to center (or offset) the active line // Reverted to center (50%) as requested const containerHeight = container.clientHeight; const lineTop = activeLine.offsetTop; const lineHeight = activeLine.offsetHeight; // Target scroll position: // Line Top - (Screen Height * 0.50) + (Half Line Height) const targetScrollTop = lineTop - (containerHeight * 0.50) + (lineHeight / 2); container.scrollTo({ top: targetScrollTop, behavior: 'smooth' }); } }, [activeIndex]); if (!track) return null; return (
{/* Header */}

Lyrics

{track.artist}

{/* Lyrics Container */}
{isLoading ? (
) : lyrics.length === 0 ? (

Looks like we don't have lyrics for this song.

Enjoy the vibe!

) : (
{/* Reverted to center padding, added max-width */} {lyrics.map((line, index) => { const isActive = index === activeIndex; const isPast = index < activeIndex; return (
{ if (onSeek) onSeek(line.time); }} > {line.text}
); })}
)}
); }; export default LyricsDetail;