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: many things

fixes #35, #36, and a few other little issues i noticed

+33 -13
+2
src/lib/NowPlaying.svelte
··· 34 34 35 35 async function load() { 36 36 if (!player.track) return ((lyrics.full = ""), (lyrics.sync = [])); 37 + lyrics.full = ""; 38 + lyrics.sync = []; 37 39 try { 38 40 const response = await api.lyricsById(player.track.id); 39 41 const structuredLyrics = response.lyricsList?.structuredLyrics?.[0];
-1
src/lib/Queue.svelte
··· 334 334 } 335 335 .col-num { 336 336 inline-size: 4rem; 337 - opacity: 0.5; 338 337 text-align: end; 339 338 } 340 339 .col-fav {
+1
src/lib/SettingsModal.svelte
··· 100 100 h3 { 101 101 border-block-end: 1px solid var(--border-subtle); 102 102 padding-block-end: 0.25rem; 103 + margin-block: 0 0.5rem; 103 104 } 104 105 .settings { 105 106 display: flex;
+5 -4
src/lib/ShortcutsModal.svelte
··· 62 62 </Modal> 63 63 64 64 <style> 65 + h3 { 66 + border-block-end: 1px solid var(--border-subtle); 67 + padding-block-end: 0.25rem; 68 + margin-block: 0 0.5rem; 69 + } 65 70 .grid { 66 71 display: grid; 67 72 grid-template-columns: 1fr 1fr; 68 73 gap: 1rem; 69 - } 70 - h3 { 71 - border-block-end: 1px solid var(--border-subtle); 72 - padding-block-end: 0.25rem; 73 74 } 74 75 .items { 75 76 display: flex;
+19 -1
src/lib/player.svelte.ts
··· 27 27 next(); 28 28 }; 29 29 player.audio.ontimeupdate = () => (player.time = player.audio.currentTime); 30 + let pendingRestoreTime = 0; 31 + 30 32 player.audio.onloadedmetadata = () => { 31 33 player.dur = player.audio.duration; 34 + if (pendingRestoreTime > 0) { 35 + player.audio.currentTime = pendingRestoreTime; 36 + player.time = pendingRestoreTime; 37 + pendingRestoreTime = 0; 38 + } 32 39 if ( 33 40 navigator.mediaSession && 34 41 "setPositionState" in navigator.mediaSession && ··· 37 44 navigator.mediaSession.setPositionState({ 38 45 duration: player.dur, 39 46 playbackRate: player.audio.playbackRate, 40 - position: 0, 47 + position: player.audio.currentTime, 41 48 }); 42 49 } 43 50 }; 44 51 52 + export const restoreTrack = (song: Song, position: number) => { 53 + player.track = song; 54 + player.dur = song.duration || 0; 55 + pendingRestoreTime = position; 56 + player.time = position; 57 + player.audio.src = api.stream(song.id); 58 + }; 59 + 45 60 export const play = (song: Song) => { 46 61 if (player.track?.id === song.id) { 47 62 seek(0); ··· 50 65 return; 51 66 } 52 67 player.track = song; 68 + player.dur = song.duration || 0; 69 + pendingRestoreTime = 0; 70 + player.time = 0; 53 71 player.audio.src = api.stream(song.id); 54 72 player.audio.play(); 55 73 player.paused = false;
+6 -7
src/lib/queue.svelte.ts
··· 1 1 import { api, type Song, asArray, internSong } from "./client.svelte.js"; 2 - import { player, play, stop } from "./player.svelte.js"; 2 + import { player, play, stop, restoreTrack } from "./player.svelte.js"; 3 3 import { nav, ui } from "./ui.svelte.js"; 4 4 import { auth } from "./auth.svelte.js"; 5 5 import { t } from "./lang.svelte.js"; ··· 101 101 if (index >= 0 && index < queue.tracks.length) { 102 102 queue.pos = index; 103 103 play(queue.tracks[index]); 104 - clearSel(); 105 104 queue.version++; 106 105 } else if (player.loop && queue.tracks.length) goto(0); 107 106 else stop(); ··· 320 319 const idx = queue.tracks.findIndex((t) => t.id === saved.current); 321 320 if (idx !== -1) { 322 321 queue.pos = idx; 323 - player.track = queue.tracks[idx]; 324 - player.audio.src = api.stream(player.track.id); 325 - if (saved.position) { 326 - player.time = saved.position / 1000; 327 - player.audio.currentTime = player.time; 322 + if (saved.position) 323 + restoreTrack(queue.tracks[idx], saved.position / 1000); 324 + else { 325 + player.track = queue.tracks[idx]; 326 + player.audio.src = api.stream(player.track.id); 328 327 } 329 328 } 330 329 }