"use client"; import { useRef, useCallback } from "react"; import Image from "next/image"; import Link from "next/link"; import { motion, AnimatePresence } from "framer-motion"; import { IoPlayOutline, IoPauseOutline, IoPlaySkipForwardOutline, IoPlaySkipBackOutline, IoCloseOutline, } from "react-icons/io5"; import { IconButton } from "@/components/IconButton"; import { usePlayer } from "./PlayerContext"; import { urlFor } from "@/lib/sanityImage"; function formatTime(seconds: number): string { if (!seconds || !isFinite(seconds)) return "0:00"; const m = Math.floor(seconds / 60); const s = Math.floor(seconds % 60); return `${m}:${s.toString().padStart(2, "0")}`; } export function Player() { const { playlist, currentIndex, isPlaying, currentTime, audioDuration, togglePlayback, next, previous, seekTo, stop, } = usePlayer(); const progressRef = useRef(null); const track = currentIndex !== null ? playlist[currentIndex] : null; const hasPrev = currentIndex !== null && currentIndex > 0; const hasNext = currentIndex !== null && currentIndex < playlist.length - 1; const displayDuration = track?.trackDuration || audioDuration; const progress = audioDuration > 0 ? currentTime / audioDuration : 0; const handleProgressClick = useCallback( (e: React.MouseEvent) => { const bar = progressRef.current; if (!bar) return; const rect = bar.getBoundingClientRect(); const fraction = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width)); seekTo(fraction); }, [seekTo], ); const coverUrl = track?.albumCover ? urlFor(track.albumCover).width(96).height(96).url() : null; return ( {track && ( {/* Progress bar at top edge of player */}
{/* Album cover */} {track.releaseSlug ? ( {coverUrl ? ( ) : (
)} ) : (
{coverUrl ? ( ) : (
)}
)} {/* Track info */}

{track.title} {track.movement && : {track.movement}}

{track.subtitle}

{/* Time */} {formatTime(currentTime)} / {formatTime(displayDuration)} {/* Controls */}
{isPlaying ? : }
)} ); }