(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 repeatBtn = document.getElementById('player-repeat'); const playerLikeBtn = document.getElementById('player-like'); const playerFavBtn = document.getElementById('player-favorite'); let repeatOn = false; function updatePlayerSocial(song) { if (!playerLikeBtn || !playerFavBtn) return; const active = !!song; playerLikeBtn.disabled = playerFavBtn.disabled = !active; playerLikeBtn.dataset.socialId = playerFavBtn.dataset.socialId = active ? song.id : ''; playerLikeBtn.classList.toggle('active', active && !!song.userLiked); playerLikeBtn.setAttribute('aria-pressed', String(active && !!song.userLiked)); playerFavBtn.classList.toggle('active', active && !!song.userFavorited); playerFavBtn.setAttribute('aria-pressed', String(active && !!song.userFavorited)); const lc = playerLikeBtn.querySelector('.social-count'); const fc = playerFavBtn.querySelector('.social-count'); if (lc) lc.textContent = active ? (song.likeCount ?? 0) : 0; if (fc) fc.textContent = active ? (song.favoriteCount ?? 0) : 0; } 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 = ''; updatePlayerSocial(null); 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}` : ''; updatePlayerSocial(cur); } function highlightNowPlaying(id) { document.querySelectorAll('.song-row').forEach(row => { row.classList.toggle('now-playing', String(row.dataset.songId) === String(id)); }); } function playCurrent() { const cur = state.queue[state.index]; if (!cur) return; window.briTunesNowPlaying = cur; audio.src = `/stream/${cur.id}`; audio.play() .then(() => window.dispatchEvent(new CustomEvent('briTunes:play', { detail: cur }))) .catch((err) => console.warn('play failed', err)); render(); highlightNowPlaying(cur.id); } 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; window.dispatchEvent(new CustomEvent('briTunes:queue', { detail: { queue: list.slice() } })); playCurrent(); } function next() { if (state.index + 1 < state.queue.length) { state.index += 1; playCurrent(); } else if (repeatOn && state.queue.length > 0) { state.index = 0; playCurrent(); } } audio.addEventListener('ended', next); nextBtn.addEventListener('click', next); repeatBtn.addEventListener('click', () => { repeatOn = !repeatOn; repeatBtn.classList.toggle('active', repeatOn); repeatBtn.setAttribute('aria-pressed', repeatOn); }); window.addEventListener('briTunes:navigate', () => { if (window.briTunesNowPlaying) highlightNowPlaying(window.briTunesNowPlaying.id); }); // 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); } return; } const shuffleBtn = e.target.closest('[data-shuffle-playlist]'); if (shuffleBtn) { try { const list = JSON.parse(shuffleBtn.getAttribute('data-shuffle-playlist')); for (let i = list.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [list[i], list[j]] = [list[j], list[i]]; } playList(list); } catch (err) { console.error(err); } } }); render(); })();