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.

fix: sync player when deleting current track

also rename queue_action to queue_play, it was named that way since i originally had one action (which was play)

intergrav 37ab96c7 aaf1c5fd

+42 -9
+1 -1
src/js/constants.js
··· 12 12 TREE_ITEM: "tree-item", 13 13 NESTED: "nested", 14 14 NESTED_SONGS: "nested-songs", 15 - QUEUE_ACTION: "queue-action", 15 + QUEUE_PLAY: "queue-play", 16 16 QUEUE_FAVORITE: "queue-favorite", 17 17 QUEUE_PLAY_NEXT: "queue-play-next", 18 18 QUEUE_MOVE_UP: "queue-move-up",
+8 -2
src/js/events.js
··· 35 35 // map button classes to handler functions 36 36 const QUEUE_BUTTON_HANDLERS = { 37 37 // play the selected track 38 - [CLASSES.QUEUE_ACTION]: (idx) => { 38 + [CLASSES.QUEUE_PLAY]: (idx) => { 39 39 playQueueTrack(idx); 40 40 updateQueue(); 41 41 }, ··· 58 58 }, 59 59 // clear from queue 60 60 [CLASSES.QUEUE_CLEAR]: (idx) => { 61 - state.queue.splice(idx, 1); 61 + const isCurrentTrack = removeFromQueue(idx); 62 + 63 + if (isCurrentTrack) { 64 + handleCurrentTrackDeleted(); 65 + highlightCurrentTrack(); 66 + } 67 + 62 68 updateQueue(); 63 69 }, 64 70 // toggle favorite status
+33 -6
src/js/queue.js
··· 143 143 state.queueIndex -= deletionsBefore; 144 144 } else if (wasCurrentTrackDeleted) { 145 145 state.queueIndex = Math.min(state.queueIndex, state.queue.length - 1); 146 - if (state.queueIndex >= 0) { 147 - playTrack(state.queue[state.queueIndex]); 148 - } else { 149 - resetPlayerUI(); 150 - } 146 + handleCurrentTrackDeleted(); 151 147 } 152 148 153 149 clearSelection(); ··· 172 168 updateQueue(); 173 169 } 174 170 171 + // remove a song by index, adjusting queue index if necessary 172 + function removeFromQueue(idx) { 173 + const isCurrentTrack = idx === state.queueIndex; 174 + 175 + state.queue.splice(idx, 1); 176 + 177 + if (isCurrentTrack) { 178 + if (state.queue.length > 0) { 179 + state.queueIndex = Math.min(idx, state.queue.length - 1); 180 + } else { 181 + state.queueIndex = -1; 182 + } 183 + } else if (idx < state.queueIndex) { 184 + state.queueIndex--; 185 + } 186 + 187 + saveQueue(); 188 + return isCurrentTrack; 189 + } 190 + 191 + // handle UI update when current track is deleted 192 + function handleCurrentTrackDeleted() { 193 + if (state.queue.length > 0) { 194 + const wasPlaying = !ui.player.paused; 195 + playTrack(state.queue[state.queueIndex]); 196 + if (!wasPlaying) ui.player.pause(); 197 + } else { 198 + resetPlayerUI(); 199 + } 200 + } 201 + 175 202 // remove all items from queue 176 203 function clearQueue() { 177 204 state.queue = []; ··· 184 211 // buttons for queue row actions 185 212 const ROW_BUTTON_CONFIG = [ 186 213 { 187 - className: CLASSES.QUEUE_ACTION, 214 + className: CLASSES.QUEUE_PLAY, 188 215 label: "play", 189 216 icon: ICONS.PLAY, 190 217 },