Skip to content

Commit

Permalink
Spotify status update
Browse files Browse the repository at this point in the history
  • Loading branch information
Posandu committed Nov 7, 2024
1 parent cf01c99 commit e4ab0dc
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 77 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"daisyui": "^4.12.2",
"firebase": "^9.23.0",
"minimasonry": "^1.3.2",
"querystring": "^0.2.1",
"svelte-masonry": "^0.1.1",
"svelte-ripple-action": "^1.0.6",
"svelte-seo": "^1.6.1",
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 17 additions & 13 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
import { onDestroy, onMount } from 'svelte';
import TypingComponent from './TypingComponent.svelte';
import { ripple } from 'svelte-ripple-action';
import { getSpotifyData, type UserData } from './spotify';
import { getSpotifyData, type NowPlaying } from './spotify';
import Work from './Work.svelte';
import Skills from './Skills.svelte';
import SvelteSeo from 'svelte-seo';
let spotifyData: UserData['data'] | null = $state(null);
let spotifyData: NowPlaying | false = $state(false);
let refreshInterval: NodeJS.Timeout;
onDestroy(() => {
clearInterval(refreshInterval);
});
onMount(async () => {
spotifyData = (await getSpotifyData()).data;
spotifyData = await getSpotifyData();
refreshInterval = setInterval(async () => {
spotifyData = (await getSpotifyData()).data;
spotifyData = await getSpotifyData();
}, 10000); //10 seconds - less than 1kb of data per request so it's fine ig
});
</script>
Expand All @@ -29,7 +29,9 @@
<div class="flex-1 flex flex-col justify-center md:items-start items-center">
<h2 class="text-3xl opacity-60 font-light">Hi, I'm</h2>

<h1 class="text-6xl my-4 font-medium text-white md:ml-0 ml-4 md:max-w-none max-w-[260px] md:text-left text-center">
<h1
class="text-6xl my-4 font-medium text-white md:ml-0 ml-4 md:max-w-none max-w-[260px] md:text-left text-center"
>
<TypingComponent text="Posandu Mapa" />
</h1>

Expand Down Expand Up @@ -57,17 +59,15 @@
>
<span class="text-base-content/40 text-2xl mb-4 block font-medium">Spotify</span>

{#if spotifyData?.listening_to_spotify}
{#if spotifyData && spotifyData?.isPlaying === true}
<p class="text-lg font-bold">
Listening to
<a href="https://open.spotify.com/track/{spotifyData?.spotify?.track_id}"
>{spotifyData?.spotify?.song}</a
>
<a href={spotifyData?.songUrl}>{spotifyData?.title}</a>
by
{spotifyData?.spotify?.artist}
{spotifyData?.artist}
</p>
<img
src={spotifyData?.spotify?.album_art_url}
src={spotifyData?.albumImageUrl}
alt="Album art"
class="rounded-lg size-12 inline-block absolute right-4 top-4"
/>
Expand All @@ -94,8 +94,12 @@
class="md:col-span-2 col-span-1 leading-8 bg-base-300 px-5 py-4 rounded-xl text-lg relative z-10"
>
<p>
I am a student @ <a target="_blank" href="https://nsbm.ac.lk" class="font-semibold text-blue-400">NSBM</a> by
day, developer by night who is passionate about everything related to
I am a student @ <a
target="_blank"
href="https://nsbm.ac.lk"
class="font-semibold text-blue-400">NSBM</a
>
by day, developer by night who is passionate about everything related to
<span class="font-semibold text-blue-400">computers</span>. I also explore
<span class="font-semibold text-green-400">software development</span>,
<span class="font-semibold text-indigo-400">machine learning (ML)</span>, and
Expand Down
70 changes: 70 additions & 0 deletions src/routes/api/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN } from '$env/static/private';
import { json } from '@sveltejs/kit';

import querystring from 'querystring';
const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`;
const NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`;

const client_id = CLIENT_ID;
const client_secret = CLIENT_SECRET;
const refresh_token = REFRESH_TOKEN;

const getAccessToken = async () => {
const basic = Buffer.from(`${client_id}:${client_secret}`).toString('base64');
const response = await fetch(TOKEN_ENDPOINT, {
method: 'POST',
headers: {
Authorization: `Basic ${basic}`,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: querystring.stringify({
grant_type: 'refresh_token',
refresh_token
})
});

return response.json();
};

const getNowPlaying = async () => {
const { access_token } = await getAccessToken();
return fetch(NOW_PLAYING_ENDPOINT, {
headers: {
Authorization: `Bearer ${access_token}`
}
});
};

async function getNowPlayingItem() {
const response = await getNowPlaying();
if (response.status === 204 || response.status > 400) {
return false;
}
const song = await response.json();
const albumImageUrl = song.item.album.images[0].url;
const artist = song.item.artists
.map(
(
//@ts-ignore
_artist
) => _artist.name
)
.join(', ');
const isPlaying = song.is_playing;
const songUrl = song.item.external_urls.spotify;
const title = song.item.name;

return {
albumImageUrl,
artist,
isPlaying,
songUrl,
title
};
}

export const GET = async () => {
const nowPlaying = await getNowPlayingItem();

return json(nowPlaying);
};
78 changes: 14 additions & 64 deletions src/routes/spotify.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,21 @@
interface Timestamps {
start: number;
end: number;
}

interface SpotifyData {
track_id: string;
timestamps: Timestamps;
album: string;
album_art_url: string;
artist: string;
song: string;
}

interface DiscordUser {
id: string;
username: string;
avatar: string;
discriminator: string;
bot: boolean;
global_name: string;
avatar_decoration_data: null | any; // Replace 'any' with the actual type if known
display_name: string;
public_flags: number;
}
export type NowPlaying =
| false
| {
albumImageUrl: string;
artist: string;
isPlaying: boolean;
songUrl: string;
title: string;
};

interface Activity {
flags: number;
id: string;
name: string;
type: number;
state: string;
session_id: string;
details: string;
timestamps: Timestamps;
assets: {
large_image: string;
large_text: string;
};
sync_id: string;
created_at: number;
party: {
id: string;
};
}
export async function getSpotifyData() {
if (typeof window === 'undefined') return false;

export interface UserData {
data: {
kv: Record<string, any>; // Replace 'any' with the actual type if known
spotify?: SpotifyData;
discord_user: DiscordUser;
activities: Activity[];
discord_status: string;
active_on_discord_web: boolean;
active_on_discord_desktop: boolean;
active_on_discord_mobile: boolean;
listening_to_spotify: boolean;
};
success: boolean;
}
const response = await fetch('/api/');

const API_URL = 'https://api.lanyard.rest/v1/users/961161387101536296';
const data: NowPlaying = await response.json();

export async function getSpotifyData() {
//@ts-ignore
if (typeof window === 'undefined') return { data: null };
const response = await fetch(API_URL + '?__cacheIgnore=' + Math.random());
const data: UserData = await response.json();
if (!data) return false;

return data;
}

0 comments on commit e4ab0dc

Please sign in to comment.