mirror of
https://github.com/nuttylmao/nutty.gg.git
synced 2026-09-19 12:10:59 -04:00
269 lines
7.3 KiB
JavaScript
269 lines
7.3 KiB
JavaScript
///////////////
|
|
// PARAMETRS //
|
|
///////////////
|
|
|
|
const queryString = window.location.search;
|
|
const urlParams = new URLSearchParams(queryString);
|
|
|
|
const client_id = urlParams.get("client_id") || "";
|
|
const client_secret = urlParams.get("client_secret") || "";
|
|
let refresh_token = urlParams.get("refresh_token") || "";
|
|
let access_token = "";
|
|
|
|
const visibilityDuration = urlParams.get("duration") || 0;
|
|
const hideAlbumArt = urlParams.has("hideAlbumArt");
|
|
|
|
let currentState = false;
|
|
let currentSongUri = "";
|
|
|
|
|
|
|
|
/////////////////
|
|
// SPOTIFY API //
|
|
/////////////////
|
|
|
|
// Update the access token - this expires so needs to be refreshed with refresh_token
|
|
async function RefreshAccessToken() {
|
|
console.debug(`Client ID: ${client_id}`);
|
|
console.debug(`Client Secret: ${client_secret}`);
|
|
console.debug(`Refresh Token: ${refresh_token}`);
|
|
|
|
let body = "grant_type=refresh_token";
|
|
body += "&refresh_token=" + refresh_token;
|
|
body += "&client_id=" + client_id;
|
|
|
|
const response = await fetch("https://accounts.spotify.com/api/token", {
|
|
method: "POST",
|
|
headers: {
|
|
'Authorization': `Basic ${btoa(client_id + ":" + client_secret)}`,
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
},
|
|
body: body
|
|
});
|
|
|
|
// If we got a response, save the access token
|
|
if (response.ok)
|
|
{
|
|
const responseData = await response.json();
|
|
console.debug(responseData);
|
|
//refresh_token = responseData.refresh_token; // Unsure if we need to replace the refresh_token but do it just in case
|
|
access_token = responseData.access_token; // Save access token for all future API calls
|
|
}
|
|
else
|
|
{
|
|
console.error(`${response.status}`);
|
|
}
|
|
}
|
|
|
|
async function GetCurrentlyPlaying(refreshInterval) {
|
|
try {
|
|
// Get the current player information from Spotify
|
|
const response = await fetch("https://api.spotify.com/v1/me/player/currently-playing", {
|
|
method: "GET",
|
|
headers: {
|
|
'Authorization': `Bearer ${access_token}`,
|
|
'Content-Type': 'application/json'
|
|
}
|
|
})
|
|
|
|
// If we got a response, save the access token
|
|
if (response.ok)
|
|
{
|
|
const responseData = await response.json();
|
|
console.debug(responseData);
|
|
UpdatePlayer(responseData);
|
|
}
|
|
else
|
|
{
|
|
switch (response.status)
|
|
{
|
|
case 401:
|
|
console.debug(`${response.status}`)
|
|
RefreshAccessToken();
|
|
break;
|
|
default:
|
|
console.error(`${response.status}`)
|
|
}
|
|
}
|
|
// Refresh
|
|
setTimeout(() => {
|
|
GetCurrentlyPlaying()
|
|
}, 1000);
|
|
}
|
|
catch (error)
|
|
{
|
|
console.debug(error);
|
|
SetVisibility(false);
|
|
|
|
// Try again in 2 seconds
|
|
setTimeout(() => {
|
|
GetCurrentlyPlaying()
|
|
}, 2000);
|
|
}
|
|
}
|
|
|
|
function UpdatePlayer(data) {
|
|
const isPlaying = data.is_playing; // The play/pause state of the player
|
|
const songUri = data.item.uri;
|
|
const albumArt = data.item.album.images.length > 0 ?
|
|
`${data.item.album.images[0].url}`
|
|
: `images/placeholder-album-art.png`; // The album art URL
|
|
const artist = `${data.item.artists[0].name}`; // Name of the artist
|
|
const name = `${data.item.name}`; // Name of the song
|
|
const duration = `${data.item.duration_ms/1000}`; // The duration of the song in seconds
|
|
const progress = `${data.progress_ms/1000}`; // The current position in seconds
|
|
|
|
// Set the visibility of the player, but only if the state is different than the last time we checked
|
|
if (isPlaying != currentState) {
|
|
|
|
// Set player visibility
|
|
if (!isPlaying)
|
|
{
|
|
console.debug("Hiding player...");
|
|
SetVisibility(false);
|
|
}
|
|
else
|
|
{
|
|
console.debug("Showing player...");
|
|
setTimeout(() => {
|
|
SetVisibility(true);
|
|
|
|
if (visibilityDuration > 0) {
|
|
setTimeout(() => {
|
|
SetVisibility(false, false);
|
|
}, visibilityDuration * 1000);
|
|
}
|
|
}, 500);
|
|
}
|
|
}
|
|
|
|
if (songUri != currentSongUri) {
|
|
if (isPlaying) {
|
|
console.debug("Showing player...");
|
|
setTimeout(() => {
|
|
SetVisibility(true);
|
|
|
|
if (visibilityDuration > 0) {
|
|
setTimeout(() => {
|
|
SetVisibility(false, false);
|
|
}, visibilityDuration * 1000);
|
|
}
|
|
}, 500);
|
|
|
|
currentSongUri = songUri;
|
|
}
|
|
}
|
|
|
|
// Set thumbnail
|
|
UpdateAlbumArt(document.getElementById("albumArt"), albumArt);
|
|
UpdateAlbumArt(document.getElementById("backgroundImage"), albumArt);
|
|
|
|
// Set song info
|
|
UpdateTextLabel(document.getElementById("artistLabel"), artist);
|
|
UpdateTextLabel(document.getElementById("songLabel"), name);
|
|
|
|
// Set progressbar
|
|
const progressPerc = ((progress / duration) * 100); // Progress expressed as a percentage
|
|
const progressTime = ConvertSecondsToMinutesSoThatItLooksBetterOnTheOverlay(progress);
|
|
const timeRemaining = ConvertSecondsToMinutesSoThatItLooksBetterOnTheOverlay(duration - progress);
|
|
console.debug(`Progress: ${progressTime}`);
|
|
console.debug(`Time Remaining: ${timeRemaining}`);
|
|
document.getElementById("progressBar").style.width = `${progressPerc}%`;
|
|
document.getElementById("progressTime").innerHTML = progressTime;
|
|
document.getElementById("timeRemaining").innerHTML = `-${timeRemaining}`;
|
|
|
|
setTimeout(() => {
|
|
document.getElementById("albumArtBack").src = albumArt;
|
|
document.getElementById("backgroundImageBack").src = albumArt;
|
|
}, 1000);
|
|
}
|
|
|
|
function UpdateTextLabel(div, text) {
|
|
if (div.innerText != text) {
|
|
div.setAttribute("class", "text-fade");
|
|
setTimeout(() => {
|
|
div.innerText = text;
|
|
div.setAttribute("class", ".text-show");
|
|
}, 500);
|
|
}
|
|
}
|
|
|
|
function UpdateAlbumArt(div, imgsrc) {
|
|
if (div.src != imgsrc) {
|
|
div.setAttribute("class", "text-fade");
|
|
setTimeout(() => {
|
|
div.src = imgsrc;
|
|
div.setAttribute("class", "text-show");
|
|
}, 500);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//////////////////////
|
|
// HELPER FUNCTIONS //
|
|
//////////////////////
|
|
|
|
function ConvertSecondsToMinutesSoThatItLooksBetterOnTheOverlay(time) {
|
|
const minutes = Math.floor(time / 60);
|
|
const seconds = Math.trunc(time - minutes * 60);
|
|
|
|
return `${minutes}:${('0' + seconds).slice(-2)}`;
|
|
}
|
|
|
|
function SetVisibility(isVisible, updateCurrentState = true) {
|
|
widgetVisibility = isVisible;
|
|
|
|
const mainContainer = document.getElementById("mainContainer");
|
|
|
|
if (isVisible) {
|
|
mainContainer.style.opacity = 1;
|
|
mainContainer.style.bottom = "50%";
|
|
}
|
|
else {
|
|
mainContainer.style.opacity = 0;
|
|
mainContainer.style.bottom = "calc(50% - 20px)";
|
|
}
|
|
|
|
if (updateCurrentState)
|
|
currentState = isVisible;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// RESIZER THING BECAUSE I THINK I KNOW HOW RESPONSIVE DESIGN WORKS EVEN THOUGH I DON'T //
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
let outer = document.getElementById('mainContainer'),
|
|
maxWidth = outer.clientWidth+50,
|
|
maxHeight = outer.clientHeight;
|
|
|
|
window.addEventListener("resize", resize);
|
|
|
|
resize();
|
|
function resize() {
|
|
const scale = window.innerWidth / maxWidth;
|
|
outer.style.transform = 'translate(-50%, 50%) scale(' + scale + ')';
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// IF THE USER PUT IN THE HIDEALBUMART PARAMATER, THEN YOU SHOULD //
|
|
// HIDE THE ALBUM ART, BECAUSE THAT'S WHAT IT'S SUPPOSED TO DO //
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
if (hideAlbumArt) {
|
|
document.getElementById("albumArtBox").style.display = "none";
|
|
document.getElementById("songInfoBox").style.width = "calc(100% - 20px)";
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////
|
|
// KICK OFF THE WHOLE WIDGET //
|
|
////////////////////////////////
|
|
|
|
RefreshAccessToken();
|
|
GetCurrentlyPlaying(); // This is a recursive function, so just run it once
|