"use client"; import * as React from "react"; import { motion } from "framer-motion"; import { Play, Pause } from "lucide-react"; import { api, mmss, type Track } from "@/lib/api"; import { usePlayer } from "@/components/player"; import { useToast } from "@/components/toast"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; export function TrackRow({ track, index, showNumber, showArtist = true, showAlbum = true, onAlbum, onArtist, onQueued, }: { track: Track; index: number; showNumber?: boolean; showArtist?: boolean; showAlbum?: boolean; onAlbum?: (id: number) => void; onArtist?: (id: number) => void; onQueued?: () => void; }) { const { playing, toggle } = usePlayer(); const toast = useToast(); const [state, setState] = React.useState<"idle" | "busy" | "done">("idle"); const isPlaying = playing === track.deezer_id; const queue = async () => { setState("busy"); try { await api.request(track); setState("done"); toast(`Queued ${track.artist} — ${track.title}`); onQueued?.(); } catch (e) { setState("idle"); toast(`Could not queue: ${(e as Error).message}`, true); } }; const facts: React.ReactNode[] = []; if (showAlbum && track.album) facts.push( track.album_id && onAlbum ? ( onAlbum(track.album_id!)} className="hover:text-accent hover:underline cursor-pointer" > {track.album} ) : ( {track.album} ), ); if (track.year) facts.push({track.year}); if (track.genre) facts.push({track.genre}); return ( {showNumber && ( {track.track ?? ""} )} toggle(track)} disabled={!track.preview} aria-label={track.preview ? `Preview ${track.title}` : "No preview available"} className={cn( "relative w-[50px] h-[50px] shrink-0 rounded-[9px] overflow-hidden bg-faint group", track.preview ? "cursor-pointer" : "cursor-default", )} > {track.cover && ( /* eslint-disable-next-line @next/next/no-img-element */ (e.currentTarget.style.visibility = "hidden")} /> )} {track.preview && ( {isPlaying ? ( ) : ( )} )} {track.title} {track.explicit && ( E )} {showArtist && track.artist_id && onArtist ? ( onArtist(track.artist_id!)} className="hover:text-accent hover:underline cursor-pointer" > {track.artist} ) : showArtist ? ( {track.artist} ) : null} {facts.map((f, i) => ( {(showArtist || i > 0) && ·} {f} ))} {track.length ? mmss(track.length) : ""} {state === "idle" ? "Get" : state === "busy" ? "…" : "Queued"} ); }