mirror of
https://github.com/bckelley/spotify-player.git
synced 2026-08-24 03:24:12 -05:00
89 lines
3.1 KiB
JavaScript
89 lines
3.1 KiB
JavaScript
import { loginWithSpotify, handleRedirect, getProfile, getCurrentTrack } from './spotify-api.js';
|
|
|
|
let isPremium = false;
|
|
|
|
const loginBtn = document.getElementById('login-btn');
|
|
const nowPlayingDiv = document.getElementById('now-playing');
|
|
const errorMsg = document.getElementById('error-msg');
|
|
const profilePic = document.getElementById('profile-pic');
|
|
|
|
loginBtn.onclick = loginWithSpotify;
|
|
|
|
async function main() {
|
|
const access_token = await handleRedirect() || localStorage.getItem('access_token');
|
|
if (!access_token) return;
|
|
|
|
loginBtn.style.display = 'none';
|
|
|
|
// Show user profile
|
|
const profile = await getProfile(access_token);
|
|
if (profile && profile.images && profile.images.length) {
|
|
profilePic.src = profile.images[0].url;
|
|
profilePic.style.display = '';
|
|
}
|
|
|
|
const isPremium = profile?.product === 'premium';
|
|
|
|
['play-btn', 'pause-btn', 'next-btn', 'prev-btn'].forEach(id => {
|
|
const btn = document.getElementById(id);
|
|
if (!isPremium) {
|
|
btn.disabled = true;
|
|
btn.title = 'Spotify Premium required for playback controls';
|
|
btn.classList.add('opacity-50', 'cursor-not-allowed');
|
|
}
|
|
});
|
|
|
|
const playBtn = document.getElementById('play-btn');
|
|
const pauseBtn = document.getElementById('pause-btn');
|
|
|
|
function showPause() {
|
|
playBtn.style.display = 'none';
|
|
pauseBtn.style.display = '';
|
|
}
|
|
function showPlay() {
|
|
playBtn.style.display = '';
|
|
pauseBtn.style.display = 'none';
|
|
}
|
|
|
|
function onPlaybackStateChanged(isPlaying) {
|
|
if (isPlaying) {
|
|
showPause();
|
|
} else {
|
|
showPlay();
|
|
}
|
|
}
|
|
|
|
// Show now playing
|
|
async function updateNowPlaying() {
|
|
const track = await getCurrentTrack(access_token);
|
|
if (!track || !track.item) {
|
|
nowPlayingDiv.style.display = 'none';
|
|
errorMsg.textContent = 'Nothing playing or no active device.';
|
|
return;
|
|
}
|
|
nowPlayingDiv.style.display = '';
|
|
errorMsg.textContent = '';
|
|
document.getElementById('album-art').src = track.item.album.images[0].url;
|
|
document.getElementById('track-title').textContent = track.item.name;
|
|
document.getElementById('track-artist').textContent = track.item.artists.map(a => a.name).join(', ');
|
|
document.getElementById('track-album').textContent = track.item.album.name;
|
|
// Progress bar
|
|
const progress = (track.progress_ms / track.item.duration_ms) * 100;
|
|
document.getElementById('progress-bar').style.width = `${progress}%`;
|
|
document.getElementById('progress-current').textContent = msToMinSec(track.progress_ms);
|
|
document.getElementById('progress-duration').textContent = msToMinSec(track.item.duration_ms);
|
|
|
|
onPlaybackStateChanged(track.is_playing);
|
|
|
|
}
|
|
setInterval(updateNowPlaying, 2000);
|
|
updateNowPlaying();
|
|
}
|
|
|
|
function msToMinSec(ms) {
|
|
const min = Math.floor(ms / 60000);
|
|
const sec = Math.floor((ms % 60000) / 1000);
|
|
return `${min}:${sec.toString().padStart(2, '0')}`;
|
|
}
|
|
|
|
main(); |