Compare commits

...
3 Commits
+29 -7
View File
@@ -98,9 +98,17 @@ window.NSPlayer = {
onPlaybackStateChanged(stateJson) { onPlaybackStateChanged(stateJson) {
try { try {
const state = JSON.parse(stateJson); const state = JSON.parse(stateJson);
if (state.isPlaying) { _skipping = false; clearTimeout(_skipTimer); } if (_skipping) {
// Suppress the transient isPlaying:false emitted by the native player during track transitions. if (state.isPlaying) {
if (!state.isPlaying && _skipping) return; // isPlaying:true during skip/seek — restart grace period instead of clearing immediately,
// so a follow-up buffering false event is also suppressed.
clearTimeout(_skipTimer);
_skipTimer = setTimeout(() => { _skipping = false; }, 600);
} else {
// Suppress transient isPlaying:false during track transitions / seeks.
return;
}
}
const prev = _nativePlaying; const prev = _nativePlaying;
_nativePlaying = state.isPlaying; _nativePlaying = state.isPlaying;
if (state.isPlaying !== prev) { if (state.isPlaying !== prev) {
@@ -275,6 +283,7 @@ export function playCurrent() {
if (HAS_BRIDGE) { if (HAS_BRIDGE) {
// Update DOM immediately for snappy feedback; onTrackChanged will confirm. // Update DOM immediately for snappy feedback; onTrackChanged will confirm.
S._trackChanging = true; S._trackChanging = true;
_resetProgressUI();
updatePlayerUI(s, true); updatePlayerUI(s, true);
onNpSongChange(s.id); onNpSongChange(s.id);
renderQueue(); renderQueue();
@@ -285,6 +294,7 @@ export function playCurrent() {
const gen = ++_playGen; const gen = ++_playGen;
S._trackChanging = true; S._trackChanging = true;
_resetProgressUI();
if(navigator.mediaSession) navigator.mediaSession.playbackState = 'playing'; if(navigator.mediaSession) navigator.mediaSession.playbackState = 'playing';
updatePlayerUI(s, true); updatePlayerUI(s, true);
onNpSongChange(s.id); onNpSongChange(s.id);
@@ -463,20 +473,32 @@ function _setSkipping() {
_skipTimer = setTimeout(() => { _skipping = false; }, 2000); _skipTimer = setTimeout(() => { _skipping = false; }, 2000);
} }
function _resetProgressUI() {
if (HAS_BRIDGE) _nativePos = 0;
document.getElementById('progress-fill').style.width = '0%';
document.getElementById('time-cur').textContent = formatDur(0);
if (S.npOpen) {
const fill = document.getElementById('np-fill');
const cur = document.getElementById('np-cur');
if (fill) fill.style.width = '0%';
if (cur) cur.textContent = formatDur(0);
}
}
export function prevSong() { export function prevSong() {
_clearPreload(); _clearPreload();
if (HAS_BRIDGE) { if (HAS_BRIDGE) {
_setSkipping(); _setSkipping();
if (_lastPositionMs > 3000) { _nsBridge('prev'); return; } if (_lastPositionMs > 3000) { _resetProgressUI(); _nsBridge('prev'); return; }
if (S.qIdx > 0) { if (S.qIdx > 0) {
S.qIdx--; S.qIdx--;
const s = S.queue[S.qIdx]; const s = S.queue[S.qIdx];
if (s) { updatePlayerUI(s, true); onNpSongChange(s.id); renderQueue(); } if (s) { _resetProgressUI(); updatePlayerUI(s, true); onNpSongChange(s.id); renderQueue(); }
} }
_nsBridge('prev'); _nsBridge('prev');
return; return;
} }
if(S.audio.currentTime > 3) { S.audio.currentTime = 0; return; } if(S.audio.currentTime > 3) { _resetProgressUI(); S.audio.currentTime = 0; return; }
if(S.qIdx > 0) { S.qIdx--; playCurrent(); } if(S.qIdx > 0) { S.qIdx--; playCurrent(); }
} }
@@ -488,7 +510,7 @@ export function nextSong() {
if (ni >= 0 && ni < S.queue.length) { if (ni >= 0 && ni < S.queue.length) {
S.qIdx = ni; S.qIdx = ni;
const s = S.queue[S.qIdx]; const s = S.queue[S.qIdx];
if (s) { updatePlayerUI(s, true); onNpSongChange(s.id); renderQueue(); } if (s) { _resetProgressUI(); updatePlayerUI(s, true); onNpSongChange(s.id); renderQueue(); }
} }
_nsBridge('next'); _nsBridge('next');
if (S.radioMode && S.queue.length - S.qIdx < 5) fillRadioQueue(); if (S.radioMode && S.queue.length - S.qIdx < 5) fillRadioQueue();