From a0753c6f69c35ed241065238d9b86284269ab537 Mon Sep 17 00:00:00 2001 From: Angel Wang Date: Sat, 10 Oct 2026 00:17:32 -0400 Subject: [PATCH] feat: steam now playing --- .gitignore | 3 ++ src/components/preact/LBNowPlaying.tsx | 29 ++++++-------- src/components/preact/NowPlaying.tsx | 24 ++++++++++++ src/components/preact/SteamNowPlaying.tsx | 42 ++++++++++++++++++++ src/pages/api/steam.ts | 47 +++++++++++++++++++++++ src/pages/index.astro | 4 +- tsconfig.json | 5 +-- 7 files changed, 131 insertions(+), 23 deletions(-) create mode 100644 src/components/preact/NowPlaying.tsx create mode 100644 src/components/preact/SteamNowPlaying.tsx create mode 100644 src/pages/api/steam.ts diff --git a/.gitignore b/.gitignore index d16d60e..74d2a53 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ pnpm-debug.log* content/journal/test.mdx # Local Netlify folder .netlify + +# secrets +.dev.vars \ No newline at end of file diff --git a/src/components/preact/LBNowPlaying.tsx b/src/components/preact/LBNowPlaying.tsx index 6c94a9d..83c78b1 100644 --- a/src/components/preact/LBNowPlaying.tsx +++ b/src/components/preact/LBNowPlaying.tsx @@ -1,6 +1,5 @@ import { Fragment } from "preact" import { useEffect, useState } from "preact/hooks" -import "../../styles/components/now_playing.scss" interface LBTrack { track_name: string @@ -71,22 +70,18 @@ export default function LBNowPlaying() { if (!song) return null - const content = - NOW LISTENING TO −{" "} - {song.title}{" "} - by - {song.release && ( - <> - {" "}on {song.release.title} - - )} [↗] {" • "} - - - return (
-
- {[content, content, content, content, content, content, content, content]} -
-
) + return ( + + NOW LISTENING TO −{" "} + {song.title}{" "} + by + {song.release && ( + <> + {" "}on {song.release.title} + + )} [↗] {" • "} + + ) } diff --git a/src/components/preact/NowPlaying.tsx b/src/components/preact/NowPlaying.tsx new file mode 100644 index 0000000..57513b2 --- /dev/null +++ b/src/components/preact/NowPlaying.tsx @@ -0,0 +1,24 @@ +import SteamNowPlaying from "./SteamNowPlaying" +import LBNowPlaying from "./LBNowPlaying" +import "../../styles/components/now_playing.scss" + +const REPEATS = 8 + +export default function NowPlaying() { + const steam = SteamNowPlaying() + const lb = LBNowPlaying() + const items = [steam, lb].filter(Boolean) + + if (items.length === 0) return null + + const repeated = Array.from({ length: REPEATS }, (_, i) => items[i % items.length]) + + return ( +
+
+ {repeated} +
+
+ ) +} + diff --git a/src/components/preact/SteamNowPlaying.tsx b/src/components/preact/SteamNowPlaying.tsx new file mode 100644 index 0000000..ac8616b --- /dev/null +++ b/src/components/preact/SteamNowPlaying.tsx @@ -0,0 +1,42 @@ +import { useEffect, useState } from "preact/hooks" + +interface Game { + name: string, + url?: string +} + +async function getJSON(url: string): Promise { + try { + const res = await fetch(url) + if (!res.ok) throw new Error(`${res.status} ${res.statusText}`) + return (await res.json()) as T + } catch { + return undefined + } +} + +export default function SteamNowPlaying() { + const [game, setGame] = useState() + + useEffect(() => { + const fetchData = async () => { + const gameData = await getJSON("/api/steam") + if (!gameData) return + setGame(gameData) + } + fetchData() + }, []) + + if (!game) return null + + return ( + + NOW PLAYING − {game.name}{" "} + on Steam [↗] {" • "} + + ) +} + +function MaybeLink({ href, children }: { href?: string; children: any }) { + return href ? {children} : <>{children} +} \ No newline at end of file diff --git a/src/pages/api/steam.ts b/src/pages/api/steam.ts new file mode 100644 index 0000000..d0304aa --- /dev/null +++ b/src/pages/api/steam.ts @@ -0,0 +1,47 @@ +import type { APIRoute } from 'astro'; +import { env } from 'cloudflare:workers'; + +export const prerender = false +const STEAM_ID = "76561199245582776" + +interface Game { + name: string, + url?: string +} + +async function getJSON(url: string): Promise { + try { + const res = await fetch(url) + if (!res.ok) throw new Error(`${res.status} ${res.statusText}`) + return (await res.json()) as T + } catch { + return undefined + } +} + +export const GET = (async () => { + const res = await getJSON( + `https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${env.STEAM_API_KEY}&steamids=${STEAM_ID}` + ).then(json => json?.response?.players[0]) + + if (!res || !res.gameextrainfo) { + return new Response(null, { + status: 204, + statusText: "No data" + }) + } + + const gameStatus = { + name: res.gameextrainfo, + url: res.gameid + ? `https://store.steampowered.com/app/${res.gameid}` + : undefined + } as Game + + return new Response(JSON.stringify(gameStatus), { + status: 200, + headers: { + "Content-Type": "application/json", + }, + }) +}) satisfies APIRoute; \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index 0e1daeb..2d1f47f 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,5 +1,5 @@ --- -import LBNowPlaying from "../components/preact/LBNowPlaying"; +import NowPlaying from "../components/preact/NowPlaying"; import "../styles/index.scss" --- @@ -16,7 +16,7 @@ import "../styles/index.scss" - +
diff --git a/tsconfig.json b/tsconfig.json index 98e6b5b..99df2e6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,5 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact" - }, - "include": [ - "./worker-configuration.d.ts" - ] + } } \ No newline at end of file -- 2.51.2