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