fix: cover art caching, skip desync, notification tap opens now playing

- api.js: cache coverUrl() per id+size so WebView HTTP cache can work;
  previously each call generated a new random salt/token → unique URL →
  no cache hits → images re-fetched on every render

- player.js: replace _nsBridge('next')/'prev' with explicit seekToIndex
  in nextSong/prevSong so native always jumps to the exact same index JS
  computed; 'next'/'prev' relied on native's internal pointer being in sync
  which caused 'UI shows new song but audio plays old one' when they drifted

- MusicService: set setSessionActivity PendingIntent on MediaSession so
  tapping the playback notification opens the app

- MainActivity: handle open_now_playing extra in onCreate (cold start)
  and onNewIntent (app already running) to show the Now Playing screen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-18 22:12:29 +02:00
1 parent 66099c12f0
commit ba382aa6d9
4 files changed
+58 -5

No files matched your search

+17 -4
View File
@@ -496,13 +496,20 @@ export function prevSong() {
_clearPreload();
if (HAS_BRIDGE) {
_setSkipping();
if (_lastPositionMs > 3000) { _resetProgressUI(); _nsBridge('prev'); return; }
if (_lastPositionMs > 3000) {
// Restart current song explicitly — avoids relying on ExoPlayer's implicit prev-vs-restart logic.
_resetProgressUI();
_nsBridge('seekTo', 0);
return;
}
if (S.qIdx > 0) {
S.qIdx--;
const s = S.queue[S.qIdx];
if (s) { _resetProgressUI(); updatePlayerUI(s, true); onNpSongChange(s.id); renderQueue(); }
// Explicit index so native doesn't have to agree on what "previous" means.
_nsBridge('seekToIndex', S.qIdx, 0);
_nsBridge('play');
}
_nsBridge('prev');
return;
}
if(S.audio.currentTime > 3) { _resetProgressUI(); S.audio.currentTime = 0; return; }
@@ -518,8 +525,13 @@ export function nextSong() {
S.qIdx = ni;
const s = S.queue[S.qIdx];
if (s) { _resetProgressUI(); updatePlayerUI(s, true); onNpSongChange(s.id); renderQueue(); }
// Explicit index prevents desync when JS and native queue pointers diverge.
_nsBridge('seekToIndex', ni, 0);
_nsBridge('play');
} else {
// Shuffle mode: native picks the shuffled-next item; onTrackChanged will confirm the index.
_nsBridge('next');
}
_nsBridge('next');
if (S.radioMode && S.queue.length - S.qIdx < 5) fillRadioQueue();
return;
}
@@ -677,7 +689,8 @@ function _initBarScrub(bar, fill, onMove) {
_touchStartX = e.touches[0].clientX;
_touchMoved = false;
e.stopPropagation();
}, {passive:true});
e.preventDefault(); // block synthetic mousedown/click that would trigger scrub on plain tap
});
bar.addEventListener('touchmove', e => {
const dx = Math.abs(e.touches[0].clientX - _touchStartX);
if (!_touchMoved && dx >= 8) { _touchMoved = true; startScrub(getPos(e.touches[0].clientX)); }