diff --git a/bun.lock b/bun.lock index add6771..b0a93a0 100644 --- a/bun.lock +++ b/bun.lock @@ -8,6 +8,7 @@ "@biomejs/biome": "1.9.4", "@fontsource-variable/geist": "^5.2.5", "@tailwindcss/vite": "^4.1.4", + "@types/node": "^22.14.1", "@yeskunall/astro-umami": "^0.0.4", "astro": "^5.7.4", "motion": "^12.7.4", @@ -281,6 +282,8 @@ "@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="], + "@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], @@ -837,6 +840,8 @@ "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + "unicode-properties": ["unicode-properties@1.4.1", "", { "dependencies": { "base64-js": "^1.3.0", "unicode-trie": "^2.0.0" } }, "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg=="], "unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="], diff --git a/package.json b/package.json index f567567..b1ce679 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,13 @@ "astro": "astro" }, "dependencies": { - "astro": "^5.7.4", "@astrojs/check": "^0.9.4", "@biomejs/biome": "1.9.4", "@fontsource-variable/geist": "^5.2.5", "@tailwindcss/vite": "^4.1.4", + "@types/node": "^22.14.1", "@yeskunall/astro-umami": "^0.0.4", + "astro": "^5.7.4", "motion": "^12.7.4", "tailwindcss": "^4.1.4" }, diff --git a/src/components/Music.astro b/src/components/Music.astro new file mode 100644 index 0000000..eb05d25 --- /dev/null +++ b/src/components/Music.astro @@ -0,0 +1,8 @@ +
+

Loading music data...

+
+ + diff --git a/src/js/index.ts b/src/js/index.ts index d9ab58e..484e9f1 100644 --- a/src/js/index.ts +++ b/src/js/index.ts @@ -1,7 +1,7 @@ import { animate, stagger } from "motion"; const elements = document.querySelectorAll( - ".motion-links, .motion-logo, .motion-text, .motion-footer", + ".motion-links, .motion-logo, .motion-text, .motion-music, .motion-footer", ); animate( @@ -20,9 +20,10 @@ document.addEventListener("keydown", ({ key }: KeyboardEvent) => { m: "a.matrix", }; - const link = document.querySelector( - shortcuts[key.toLowerCase()] || "", - ) as HTMLAnchorElement | null; + const selector = shortcuts[key.toLowerCase()]; + if (!selector) return; + + const link = document.querySelector(selector) as HTMLAnchorElement | null; if (!link?.href) return; const a = Object.assign(document.createElement("a"), { diff --git a/src/js/music.ts b/src/js/music.ts new file mode 100644 index 0000000..adb35e1 --- /dev/null +++ b/src/js/music.ts @@ -0,0 +1,77 @@ +interface Track { + artists: string[]; + title: string; + album: { albumtitle: string }; +} + +interface Scrobble { + time: number; + track: Track; +} + +async function fetchAndDisplayLastTrack() { + const container = document.getElementById("last-track-widget"); + + if (!container) { + console.error("Container element not found!"); + return; + } + + try { + let res: Response; + try { + res = await fetch("https://z0x.ca/music"); + if (!res.ok) throw new Error("WAN fetch failed"); + } catch (e) { + res = await fetch("https://z0x.home.arpa/music"); + } + + if (!res.ok) { + throw new Error(`HTTP error! status: ${res.status}`); + } + + const data: { status: string; list: Scrobble[] } = await res.json(); + + let lastTrack: Track | null = null; + if (data?.status === "ok" && data.list?.length) { + lastTrack = data.list.sort( + (a: Scrobble, b: Scrobble) => b.time - a.time, + )[0].track; + } + if (lastTrack) { + container.innerHTML = ` + + + + Last played.. + + + + ${lastTrack.title} + + + + by + + ${lastTrack.artists[0]} + + + + on + + ${lastTrack.album.albumtitle} + + `; + } else { + container.innerHTML = "

No tracks found.

"; + } + } catch (e) { + console.error("Fetch error:", e); + container.innerHTML = "

Error loading tracks.

"; + } finally { + container.classList.remove("opacity-0"); + container.classList.add("opacity-100"); + } +} + +fetchAndDisplayLastTrack(); diff --git a/src/pages/index.astro b/src/pages/index.astro index ab56a10..468deb2 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,6 +1,7 @@ --- import Links from "@/components/Links.astro"; import Logo from "@/components/Logo.astro"; +import Music from "@/components/Music.astro"; import Text from "@/components/Text.astro"; import Layout from "@/layouts/Layout.astro"; --- @@ -9,4 +10,5 @@ import Layout from "@/layouts/Layout.astro"; +