This commit is contained in:
parent
9ea97c4ac6
commit
5f0ac7efdb
7 changed files with 154 additions and 64 deletions
104
website/scripts/lastfm.ts
Normal file
104
website/scripts/lastfm.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import { timeAgo } from "./util";
|
||||
|
||||
interface GetRecentTracksType {
|
||||
recenttracks: {
|
||||
track: Array<{
|
||||
artist: {
|
||||
mbid: string;
|
||||
"#text": string;
|
||||
};
|
||||
streamable: string;
|
||||
image: Array<{
|
||||
size: string;
|
||||
"#text": string;
|
||||
}>;
|
||||
mbid: string;
|
||||
album: {
|
||||
mbid: string;
|
||||
"#text": string;
|
||||
};
|
||||
name: string;
|
||||
"@attr"?: {
|
||||
nowplaying: string;
|
||||
};
|
||||
url: string;
|
||||
date?: {
|
||||
uts: string;
|
||||
"#text": string;
|
||||
};
|
||||
}>;
|
||||
"@attr": {
|
||||
user: string;
|
||||
totalPages: string;
|
||||
page: string;
|
||||
perPage: string;
|
||||
total: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
//https://ws.audioscrobbler.com/2.0/
|
||||
//?api_key=816cfe50ddeeb73c9987b85de5c19e71
|
||||
//&method=User.getrecenttracks
|
||||
//&user=yourfriendoss
|
||||
//&format=json
|
||||
//&limit=1
|
||||
|
||||
const lastFM = {
|
||||
apiKey: "816cfe50ddeeb73c9987b85de5c19e71",
|
||||
constructUrl: (method: string, parameters: Record<string, any>) => {
|
||||
const defaultParams = {
|
||||
format: "json",
|
||||
api_key: lastFM.apiKey,
|
||||
method
|
||||
}
|
||||
|
||||
Object.assign(parameters, defaultParams);
|
||||
|
||||
return "https://ws.audioscrobbler.com/2.0/?" + new URLSearchParams(parameters).toString()
|
||||
},
|
||||
getRecentTracks: async (user: string): Promise<GetRecentTracksType> => {
|
||||
const request = await fetch(lastFM.constructUrl("User.getrecenttracks", {user, limit: 1}));
|
||||
return await request.json();
|
||||
},
|
||||
};
|
||||
|
||||
(async () => {
|
||||
const recentTracks = await lastFM.getRecentTracks("yourfriendoss");
|
||||
const track = recentTracks.recenttracks.track[0];
|
||||
if(!track) return;
|
||||
const lastFMElement = document.getElementById("lastfm")!
|
||||
lastFMElement.innerHTML = "";
|
||||
const img = document.createElement("img");
|
||||
img.width = 150
|
||||
img.height = 150
|
||||
img.src = track.image.at(-1)?.["#text"]!;
|
||||
lastFMElement?.appendChild(img);
|
||||
|
||||
const div = document.createElement("div");
|
||||
const h1 = document.createElement("h1");
|
||||
const spanArtist = document.createElement("span");
|
||||
const spanTitle = document.createElement("span");
|
||||
|
||||
h1.innerText = track["@attr"]?.nowplaying ? "listening to Now" : "listened to " + timeAgo((+track.date?.uts!)*1000)
|
||||
h1.style.margin = "0";
|
||||
|
||||
spanArtist.style.fontSize = "xx-large";
|
||||
spanTitle.style.fontSize = "x-large";
|
||||
|
||||
spanArtist.innerText = track.artist["#text"];
|
||||
spanTitle.innerText = track.name;
|
||||
|
||||
div.appendChild(h1)
|
||||
div.appendChild(spanArtist)
|
||||
div.appendChild(spanTitle)
|
||||
lastFMElement?.appendChild(div);
|
||||
|
||||
|
||||
/* <img src="https://lastfm.freetls.fastly.net/i/u/300x300/400560416eb0c37bbc407cd4279c7899.jpg" width="150" height="150">
|
||||
<div>
|
||||
<h1>listening to now</h1>
|
||||
<span style="font-size:x-large">Bladee</span>
|
||||
<span style="font-size:x-large">Open your Eyes (hymn)</span>
|
||||
</div>*/
|
||||
|
||||
})();
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { timeAgo } from "./util";
|
||||
|
||||
interface LatestStatus {
|
||||
username: string;
|
||||
status: string;
|
||||
|
|
@ -7,28 +9,6 @@ interface LatestStatus {
|
|||
}
|
||||
|
||||
(async () => {
|
||||
function timeAgo(input: number | Date) {
|
||||
const date = input instanceof Date ? input : new Date(input);
|
||||
const formatter = new Intl.RelativeTimeFormat("en");
|
||||
const ranges = [
|
||||
["years", 3600 * 24 * 365],
|
||||
["months", 3600 * 24 * 30],
|
||||
["weeks", 3600 * 24 * 7],
|
||||
["days", 3600 * 24],
|
||||
["hours", 3600],
|
||||
["minutes", 60],
|
||||
["seconds", 1],
|
||||
] as const;
|
||||
const secondsElapsed = (date.getTime() - Date.now()) / 1000;
|
||||
|
||||
for (const [rangeType, rangeVal] of ranges) {
|
||||
if (rangeVal < Math.abs(secondsElapsed)) {
|
||||
const delta = secondsElapsed / rangeVal;
|
||||
return formatter.format(Math.round(delta), rangeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const req = await fetch("https://status.cafe/users/sophie.atom");
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(await req.text(), "text/xml");
|
||||
|
|
|
|||
21
website/scripts/util.ts
Normal file
21
website/scripts/util.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
export function timeAgo(input: number | Date) {
|
||||
const date = input instanceof Date ? input : new Date(input);
|
||||
const formatter = new Intl.RelativeTimeFormat("en");
|
||||
const ranges = [
|
||||
["years", 3600 * 24 * 365],
|
||||
["months", 3600 * 24 * 30],
|
||||
["weeks", 3600 * 24 * 7],
|
||||
["days", 3600 * 24],
|
||||
["hours", 3600],
|
||||
["minutes", 60],
|
||||
["seconds", 1],
|
||||
] as const;
|
||||
const secondsElapsed = (date.getTime() - Date.now()) / 1000;
|
||||
|
||||
for (const [rangeType, rangeVal] of ranges) {
|
||||
if (rangeVal < Math.abs(secondsElapsed)) {
|
||||
const delta = secondsElapsed / rangeVal;
|
||||
return formatter.format(Math.round(delta), rangeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue