feat: add now happening that shows lastfm and steam status
This commit is contained in:
parent
c626a322cb
commit
405dacf1c4
@ -46,7 +46,9 @@
|
|||||||
"nanoid": "^5.0.8",
|
"nanoid": "^5.0.8",
|
||||||
"rehype-autolink-headings": "^7.1.0",
|
"rehype-autolink-headings": "^7.1.0",
|
||||||
"rehype-slug": "^6.0.0",
|
"rehype-slug": "^6.0.0",
|
||||||
"typescript-svelte-plugin": "^0.3.42"
|
"steamgriddb": "^2.2.0",
|
||||||
|
"typescript-svelte-plugin": "^0.3.42",
|
||||||
|
"xml-js": "^1.6.11"
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
"@sveltejs/kit",
|
"@sveltejs/kit",
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import type { Cookies } from '@sveltejs/kit'
|
import type { Cookies } from '@sveltejs/kit'
|
||||||
import { env } from '$env/dynamic/private'
|
import { env } from '$env/dynamic/private'
|
||||||
import { writable } from 'svelte/store'
|
import { get, writable } from 'svelte/store'
|
||||||
import { existsSync, readFileSync } from 'fs'
|
import { existsSync, readFileSync } from 'fs'
|
||||||
import { Agent, CredentialSession } from '@atproto/api'
|
import { Agent, CredentialSession } from '@atproto/api'
|
||||||
|
import { xml2json } from 'xml-js'
|
||||||
|
import SGDB from 'steamgriddb'
|
||||||
|
|
||||||
export const scopeCookies = (cookies: Cookies, path: string) => {
|
export const scopeCookies = (cookies: Cookies, path: string) => {
|
||||||
return {
|
return {
|
||||||
@ -27,3 +29,63 @@ export const loginToBsky = async () => {
|
|||||||
return new Agent(creds)
|
return new Agent(creds)
|
||||||
}
|
}
|
||||||
export const bskyClient = writable<null | Agent>(null)
|
export const bskyClient = writable<null | Agent>(null)
|
||||||
|
|
||||||
|
const cachedLastTrack = writable<{track: LastTrack | null, since: number}>({track: null, since: 0})
|
||||||
|
export type LastTrack = {name: string, artist: string, image: string | null, link: string}
|
||||||
|
export const lastFmGetNowPlaying: () => Promise<LastTrack | null> = async () => {
|
||||||
|
var cached = get(cachedLastTrack)
|
||||||
|
if (Date.now() - cached.since < 10 * 1000) {
|
||||||
|
return cached.track
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const API_URL = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=yusdacra&api_key=da1911d405b5b37383e200b8f36ee9ec&format=json&limit=1"
|
||||||
|
var resp = await (await fetch(API_URL)).json()
|
||||||
|
var track = resp.recenttracks.track[0] ?? null
|
||||||
|
if (!(track['@attr'].nowplaying ?? null)) {
|
||||||
|
throw "no nowplaying track found"
|
||||||
|
}
|
||||||
|
var data = {
|
||||||
|
name: track.name,
|
||||||
|
artist: track.artist['#text'],
|
||||||
|
image: track.image[2]['#text'] ?? null,
|
||||||
|
link: track.url,
|
||||||
|
}
|
||||||
|
cachedLastTrack.set({track: data, since: Date.now()})
|
||||||
|
return data
|
||||||
|
} catch(why) {
|
||||||
|
console.log("could not fetch last fm: ", why)
|
||||||
|
cachedLastTrack.set({track: null, since: Date.now()})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const steamgriddbClient = new SGDB(env.STEAMGRIDDB_API_KEY);
|
||||||
|
const cachedLastGame = writable<{game: LastGame | null, since: number}>({game: null, since: 0})
|
||||||
|
export type LastGame = {name: string, link: string, icon: string, pfp: string}
|
||||||
|
export const steamGetNowPlaying: () => Promise<LastGame | null> = async () => {
|
||||||
|
var cached = get(cachedLastGame)
|
||||||
|
if (Date.now() - cached.since < 10 * 1000) {
|
||||||
|
return cached.game
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const API_URL = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${env.STEAM_API_KEY}&steamids=76561198106829949&format=json`
|
||||||
|
var profile = (await (await fetch(API_URL)).json()).response.players[0]
|
||||||
|
if (!profile.gameid) {
|
||||||
|
throw "no game is being played"
|
||||||
|
}
|
||||||
|
var icons = await steamgriddbClient.getIconsBySteamAppId(profile.gameid, ['official'])
|
||||||
|
console.log(icons)
|
||||||
|
var game = {
|
||||||
|
name: profile.gameextrainfo,
|
||||||
|
link: `https://store.steampowered.com/app/${profile.gameid}`,
|
||||||
|
icon: icons[0].thumb.toString(),
|
||||||
|
pfp: profile.avatarmedium,
|
||||||
|
}
|
||||||
|
cachedLastGame.set({game, since: Date.now()})
|
||||||
|
return game
|
||||||
|
} catch(why) {
|
||||||
|
console.log("could not fetch steam: ", why)
|
||||||
|
cachedLastGame.set({game: null, since: Date.now()})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
7
src/routes/+page.server.ts
Normal file
7
src/routes/+page.server.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { lastFmGetNowPlaying, steamGetNowPlaying } from "$lib"
|
||||||
|
|
||||||
|
export const load = async ({}) => {
|
||||||
|
const lastTrack = await lastFmGetNowPlaying()
|
||||||
|
const lastGame = await steamGetNowPlaying()
|
||||||
|
return {lastTrack, lastGame}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { PUBLIC_BASE_URL } from '$env/static/public';
|
import { PUBLIC_BASE_URL } from '$env/static/public';
|
||||||
import Window from '../components/window.svelte';
|
import Window from '../components/window.svelte';
|
||||||
|
|
||||||
|
export let data;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row gap-y-2 lg:gap-y-0 md:h-full h-card">
|
<div class="flex flex-col md:flex-row gap-y-2 lg:gap-y-0 md:h-full h-card">
|
||||||
@ -61,10 +63,8 @@
|
|||||||
<Window title="latest stuff" style="mt-auto">
|
<Window title="latest stuff" style="mt-auto">
|
||||||
<div class="prose prose-ralsei prose-img:m-0 leading-6">
|
<div class="prose prose-ralsei prose-img:m-0 leading-6">
|
||||||
<p>
|
<p>
|
||||||
new game prototype thingy <a href="https://yusdacra.itch.io/lightfelt"
|
new game prototype thingy <a href="https://yusdacra.itch.io/lightfelt">at itch.io page</a
|
||||||
>at itch.io page</a
|
>! spent a lot of time learning and designing the environment and scene stuff :3
|
||||||
>!
|
|
||||||
spent a lot of time learning and designing the environment and scene stuff :3
|
|
||||||
trenchbroom and func_godot were used mainly!
|
trenchbroom and func_godot were used mainly!
|
||||||
</p>
|
</p>
|
||||||
<img
|
<img
|
||||||
@ -122,13 +122,77 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</Window>
|
</Window>
|
||||||
<Window title="current" iconUri="/icons/entry.png" style="mt-auto">
|
<Window title="now happening" style="mt-auto" removePadding>
|
||||||
<div class="prose prose-ralsei leading-6">
|
{#if data.lastTrack}
|
||||||
<ul>
|
<div class="flex flex-row m-2 border-4 border-double">
|
||||||
<li>playing wynncraft, helldivers 2, warframe</li>
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
<li>idk bother me to do stuff</li>
|
{#if data.lastTrack.image}
|
||||||
</ul>
|
<img
|
||||||
</div>
|
class="border-4 w-16 h-16"
|
||||||
|
style="border-style: none double none none;"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
src={data.lastTrack.image}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<img
|
||||||
|
class="border-4 w-16 h-16 p-2"
|
||||||
|
style="border-style: none double none none; image-rendering: pixelated;"
|
||||||
|
src="/icons/cd_audio.png"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
<div class="flex flex-col max-w-[40ch] p-2 overflow-hidden">
|
||||||
|
<p
|
||||||
|
class="text-shadow-green text-ralsei-green-light text-ellipsis text-nowrap overflow-hidden max-w-[30ch]"
|
||||||
|
>
|
||||||
|
<span class="text-sm text-shadow-white text-ralsei-white">listening to</span>
|
||||||
|
<a
|
||||||
|
title={data.lastTrack.name}
|
||||||
|
href="https://www.last.fm/user/yusdacra"
|
||||||
|
class="hover:underline">{data.lastTrack.name}</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="text-shadow-pink text-ralsei-pink-regular text-sm text-ellipsis text-nowrap overflow-hidden max-w-[30ch]"
|
||||||
|
>
|
||||||
|
<span class="text-shadow-white text-ralsei-white">by</span>
|
||||||
|
<span title={data.lastTrack.artist}>{data.lastTrack.artist}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if data.lastGame}
|
||||||
|
<div class="flex flex-row m-2 border-4 border-double">
|
||||||
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
|
<img
|
||||||
|
class="border-4 w-16 h-16"
|
||||||
|
style="border-style: none double none none;"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
src={data.lastGame.icon}
|
||||||
|
/>
|
||||||
|
<div class="flex flex-col max-w-[40ch] p-2 gap-1 overflow-hidden">
|
||||||
|
<p
|
||||||
|
class="text-shadow-green text-ralsei-green-light text-ellipsis text-nowrap overflow-hidden max-w-[30ch]"
|
||||||
|
>
|
||||||
|
<span class="text-sm text-shadow-white text-ralsei-white">playing</span>
|
||||||
|
<a title={data.lastGame.name} class="hover:underline" href={data.lastGame.link}
|
||||||
|
>{data.lastGame.name}</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
|
<a
|
||||||
|
href="https://steamcommunity.com/id/yusdacra"
|
||||||
|
class="text-xs hover:underline text-shadow-green text-ralsei-green-light"
|
||||||
|
><img class="inline w-4" src={data.lastGame.pfp} />
|
||||||
|
<span class="align-middle">steam profile</span></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if !data.lastGame && !data.lastTrack}
|
||||||
|
<p class="text-xl m-2">nothing, apparently.</p>
|
||||||
|
{/if}
|
||||||
</Window>
|
</Window>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
BIN
static/icons/cd_audio.png
Normal file
BIN
static/icons/cd_audio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 631 B |
Loading…
Reference in New Issue
Block a user