a simple web player for subsonic tinysub.devins.page
subsonic navidrome javascript
11
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: scrobbling and playback handling fixes

intergrav a8f3cf58 f431fbc0

+26 -12
+2 -3
src/js/auth.js
··· 9 9 await loadLibrary(); 10 10 await loadPlaylists(); 11 11 await loadFavorites(); 12 - // restore song display and pause playback on startup 12 + // restore song display on startup 13 13 if (hasValidTrack()) { 14 - playTrack(state.queue[state.queueIndex]); 15 - ui.player.pause(); 14 + playTrack(state.queue[state.queueIndex], false); 16 15 } 17 16 } 18 17
+15 -1
src/js/events.js
··· 181 181 setupDragAndDrop(); 182 182 setupQueueContextMenu(); 183 183 initVirtualScroller(); 184 - selectionManager.virtualScroller = virtualScroller; 185 184 setupKeyboardShortcuts(); 186 185 setupMediaSessionHandlers(); 186 + 187 + // setup now playing scrobble listener 188 + let lastScrobbledSongId = null; 189 + ui.player.addEventListener("play", () => { 190 + if ( 191 + state.settings.scrobbling && 192 + isValidQueueIndex(state.queueIndex, state.queue.length) 193 + ) { 194 + const songId = state.queue[state.queueIndex]?.id; 195 + if (songId && songId !== lastScrobbledSongId) { 196 + lastScrobbledSongId = songId; 197 + state.api.nowPlaying(songId).catch(() => {}); 198 + } 199 + } 200 + }); 187 201 });
+6 -5
src/js/player.js
··· 21 21 } 22 22 23 23 // load and play a song 24 - function playTrack(song) { 24 + function playTrack(song, autoplay = true) { 25 25 if (!song) { 26 26 resetPlayerUI(); 27 27 return; ··· 43 43 ui.coverArt.srcset = ""; 44 44 } 45 45 ui.player.src = state.api.getStreamUrl(song.id); 46 - ui.player.play(); 47 - if (state.settings.scrobbling) { 48 - state.api.nowPlaying(song.id).catch(() => {}); 46 + if (autoplay) { 47 + ui.player.play(); 49 48 } 50 49 loadLyricsForSong(song); 51 50 highlightCurrentTrack(); 52 51 updateMediaSession(song); 53 - withMediaSession((ms) => (ms.playbackState = "playing")); 52 + withMediaSession( 53 + (ms) => (ms.playbackState = autoplay ? "playing" : "paused"), 54 + ); 54 55 } 55 56 56 57 // update play button icon based on playback state
+3 -3
src/js/queue.js
··· 271 271 }, 272 272 }, 273 273 ); 274 + selectionManager.virtualScroller = virtualScroller; 274 275 } 275 276 276 277 // update queue display using virtual scroller ··· 337 338 return isCurrentTrack; 338 339 } 339 340 340 - // handle UI update when current track is deleted 341 + // handle current track is deleted 341 342 function handleCurrentTrackDeleted() { 342 343 if (state.queue.length > 0) { 343 344 const wasPlaying = !ui.player.paused; 344 - playTrack(state.queue[state.queueIndex]); 345 - if (!wasPlaying) ui.player.pause(); 345 + playTrack(state.queue[state.queueIndex], wasPlaying); 346 346 } else { 347 347 resetPlayerUI(); 348 348 }