83 lines
2.3 KiB
JavaScript
83 lines
2.3 KiB
JavaScript
(function () {
|
|
const audio = document.getElementById('player-audio');
|
|
const titleEl = document.getElementById('player-title');
|
|
const artistEl = document.getElementById('player-artist');
|
|
const coverEl = document.getElementById('player-cover');
|
|
const queueInfoEl = document.getElementById('player-queue-info');
|
|
const nextBtn = document.getElementById('player-next');
|
|
|
|
const state = {
|
|
queue: [], // array of {id, title, artist, cover}
|
|
index: -1,
|
|
};
|
|
|
|
function render() {
|
|
const cur = state.queue[state.index];
|
|
if (!cur) {
|
|
titleEl.textContent = 'Nothing playing';
|
|
artistEl.textContent = '';
|
|
coverEl.src = '/static/vendor/cover-placeholder.svg';
|
|
queueInfoEl.textContent = '';
|
|
return;
|
|
}
|
|
titleEl.textContent = cur.title;
|
|
artistEl.textContent = cur.artist || '';
|
|
coverEl.src = cur.cover || '/static/vendor/cover-placeholder.svg';
|
|
queueInfoEl.textContent = state.queue.length > 1
|
|
? `${state.index + 1} / ${state.queue.length}`
|
|
: '';
|
|
}
|
|
|
|
function playCurrent() {
|
|
const cur = state.queue[state.index];
|
|
if (!cur) return;
|
|
audio.src = `/stream/${cur.id}`;
|
|
audio.play().catch((err) => console.warn('play failed', err));
|
|
render();
|
|
}
|
|
|
|
function playOne(song) {
|
|
state.queue = [song];
|
|
state.index = 0;
|
|
playCurrent();
|
|
}
|
|
|
|
function playList(list) {
|
|
if (!Array.isArray(list) || list.length === 0) return;
|
|
state.queue = list;
|
|
state.index = 0;
|
|
playCurrent();
|
|
}
|
|
|
|
function next() {
|
|
if (state.index + 1 < state.queue.length) {
|
|
state.index += 1;
|
|
playCurrent();
|
|
}
|
|
}
|
|
|
|
audio.addEventListener('ended', next);
|
|
nextBtn.addEventListener('click', next);
|
|
|
|
// Delegated click handler for any [data-play-song] / [data-play-playlist] button.
|
|
document.addEventListener('click', (e) => {
|
|
const songBtn = e.target.closest('[data-play-song]');
|
|
if (songBtn) {
|
|
try {
|
|
const song = JSON.parse(songBtn.getAttribute('data-play-song'));
|
|
playOne(song);
|
|
} catch (err) { console.error(err); }
|
|
return;
|
|
}
|
|
const listBtn = e.target.closest('[data-play-playlist]');
|
|
if (listBtn) {
|
|
try {
|
|
const list = JSON.parse(listBtn.getAttribute('data-play-playlist'));
|
|
playList(list);
|
|
} catch (err) { console.error(err); }
|
|
}
|
|
});
|
|
|
|
render();
|
|
})();
|