My personal site hosted @ https://indexx.dev
1import { useEffect, useState } from "react"; 2 3export default function NowPlaying() { 4 const [data, setData] = useState(null); 5 const [error, setError] = useState(null); 6 7 useEffect(() => { 8 const fetchNowPlaying = async () => { 9 try { 10 const res = await fetch( 11 "https://indexx.dev/api/misc/lastfm", 12 ); 13 if (!res.ok) throw new Error(`HTTP ${res.status}`); 14 15 const json = await res.json(); 16 const status = { 17 song: json.track, 18 artist: json.artist, 19 albumArt: json.cover, 20 createdAt: json.createdAt, 21 link: json.url, 22 nowPlaying: !json.createdAt, 23 }; 24 setData(status); 25 } catch (err) { 26 console.error("Fetch failed:", err); 27 setError(err.message); 28 } 29 }; 30 31 fetchNowPlaying(); 32 }, []); 33 34 if (error) return <span>Error: {error}</span>; 35 if (!data) return null; 36 37 let timeAgo = ""; 38 let oldStatusClasses = ""; 39 40 if (!data.nowPlaying && data.createdAt) { 41 const date = new Date(data.createdAt); 42 const now = new Date(); 43 const diff = now.getTime() - date.getTime(); 44 45 const minutes = Math.floor(diff / 60000); 46 const hours = Math.floor(minutes / 60); 47 const days = Math.floor(hours / 24); 48 49 if (days > 0) timeAgo = `${days} days ago`; 50 else if (hours > 0) timeAgo = `${hours} hours ago`; 51 else if (minutes > 0) timeAgo = `${minutes} minutes ago`; 52 else timeAgo = "just now"; 53 54 oldStatusClasses = days > 3 55 ? "opacity-75 text-decoration-line-through" 56 : ""; 57 } 58 59 return ( 60 <a 61 id="now-playing" 62 href={data.link} 63 target="_blank" 64 className={oldStatusClasses} 65 > 66 <img 67 src={data.albumArt} 68 alt={`${data.album} cover`} 69 /> 70 <div 71 style={{ 72 display: "flex", 73 flexDirection: "column", 74 gap: "2px", 75 width: "100%", 76 }} 77 > 78 <div style={{ fontWeight: "bold" }}>{data.song}</div> 79 <div style={{ fontSize: "0.9em", marginTop: "-5px" }}> 80 {data.artist} 81 </div> 82 <div 83 style={{ 84 fontSize: "0.8em", 85 opacity: 0.7, 86 marginTop: "-5px", 87 }} 88 > 89 {data.nowPlaying 90 ? ( 91 <span style={{ color: "#22c55e" }}> 92 Now Playing 93 </span> 94 ) 95 : timeAgo} 96 </div> 97 </div> 98 </a> 99 ); 100}