My personal site hosted @ https://indexx.dev

feat: show last.fm instead of teal.fm

Changed files
+106 -5
src
components
pages
+100
src/components/islands/Lastfm.jsx
···
+
import { useEffect, useState } from "react";
+
+
export default function Lastfm() {
+
const [data, setData] = useState(null);
+
const [error, setError] = useState(null);
+
+
useEffect(() => {
+
const fetchLastfmData = async () => {
+
try {
+
const res = await fetch(
+
"https://workers.indexx.dev/misc/lastfm",
+
);
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
+
+
const json = await res.json();
+
const status = {
+
song: json.track,
+
artist: json.artist,
+
albumArt: json.cover,
+
createdAt: json.createdAt,
+
link: json.url,
+
nowPlaying: !json.createdAt,
+
};
+
setData(status);
+
} catch (err) {
+
console.error("Fetch failed:", err);
+
setError(err.message);
+
}
+
};
+
+
fetchLastfmData();
+
}, []);
+
+
if (error) return <span>Error: {error}</span>;
+
if (!data) return null;
+
+
let timeAgo = "";
+
let oldStatusClasses = "";
+
+
if (!data.nowPlaying && data.createdAt) {
+
const date = new Date(data.createdAt);
+
const now = new Date();
+
const diff = now.getTime() - date.getTime();
+
+
const minutes = Math.floor(diff / 60000);
+
const hours = Math.floor(minutes / 60);
+
const days = Math.floor(hours / 24);
+
+
if (days > 0) timeAgo = `${days} days ago`;
+
else if (hours > 0) timeAgo = `${hours} hours ago`;
+
else if (minutes > 0) timeAgo = `${minutes} minutes ago`;
+
else timeAgo = "just now";
+
+
oldStatusClasses = days > 3
+
? "opacity-75 text-decoration-line-through"
+
: "";
+
}
+
+
return (
+
<a
+
id="now-playing"
+
href={data.link}
+
target="_blank"
+
className={oldStatusClasses}
+
>
+
<img
+
src={data.albumArt}
+
alt={`${data.album} cover`}
+
/>
+
<div
+
style={{
+
display: "flex",
+
flexDirection: "column",
+
gap: "2px",
+
width: "100%",
+
}}
+
>
+
<div style={{ fontWeight: "bold" }}>{data.song}</div>
+
<div style={{ fontSize: "0.9em", marginTop: "-5px" }}>
+
{data.artist}
+
</div>
+
<div
+
style={{
+
fontSize: "0.8em",
+
opacity: 0.7,
+
marginTop: "-5px",
+
}}
+
>
+
{data.nowPlaying
+
? (
+
<span style={{ color: "#22c55e" }}>
+
▶ Now Playing
+
</span>
+
)
+
: timeAgo}
+
</div>
+
</div>
+
</a>
+
);
+
}
+1 -1
src/components/islands/Tealfm.jsx
···
import { useEffect, useState } from "react";
-
export default function NowPlaying() {
+
export default function Tealfm() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
+5 -4
src/pages/index.astro
···
import Header from "../components/Header.astro";
import SocialLinks from "../components/SocialLinks.astro";
-
//import ProjectsPane from "../components/ProjectsPane.astro";
+
import ProjectsPane from "../components/islands/ProjectsPane.jsx";
import Status from "../components/islands/Status.jsx";
-
import Tealfm from "../components/islands/Tealfm.jsx";
-
import ProjectsPane from "../components/islands/ProjectsPane.jsx";
+
import Lastfm from "../components/islands/Lastfm";
---
<Layout title="hello" description="insert wave emoji">
<main id="page" class="text-center">
<Header />
<Status client:load />
-
<Tealfm client:load />
+
<Lastfm client:load />
<SocialLinks />
+
<!--
<img
src="https://ziit.indexx.dev/api/public/badge/cmh6t4rlk0001lz1wau6e8c83/all/month"
alt="Ziit Coding Statistics"
/>
+
-->
<br />
<a
id="projects-button"