feat: Android Auto, radio mode, lyrics overhaul + web lyrics cleanup
Android: - fix: Android Auto credentials never set on MusicService → artwork/stream null - feat: Android Auto tabs reduced to Zuletzt gespielt, Favoriten, Playlists - feat: radio mode (getSimilarSongs2 → getRandomSongs fallback, <5 songs refill) - fix: lyrics now use Navidrome getLyricsBySongId plugin exclusively - fix: lyrics scroll rewritten with Column+ScrollState absolute animateScrollTo - fix: lyrics recomposition lag — extracted LyricsLineItem + key(idx) per line - chore: remove dead LrcLibClient (direct lrclib bypassed Navidrome plugin) Web: - fix: lyrics now use Navidrome getLyricsBySongId only, removed direct lrclib fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
8c8f03503b
commit
7e20062995
18 files changed
+700
-243
No files matched your search
+14
-42
@@ -147,61 +147,33 @@ async function _loadNpLyrics(songId) {
|
||||
content.innerHTML = '<div style="text-align:center;padding:60px 0;color:rgba(255,255,255,.3);font-size:14px">Lade Lyrics…</div>';
|
||||
|
||||
const token = ++_lyricsLoadToken;
|
||||
const s = S.queue[S.qIdx];
|
||||
const { getLyricsBySongId } = await import('../api.js');
|
||||
if(token !== _lyricsLoadToken) return;
|
||||
|
||||
// 1. Navidrome (plugin handles fetching + caching server-side)
|
||||
// Navidrome plugin (getLyricsBySongId) — plugin handles source lookup + caching
|
||||
const lyrics = await getLyricsBySongId(songId);
|
||||
if(token !== _lyricsLoadToken) return;
|
||||
const track = lyrics[0];
|
||||
if(track?.synced && track.line?.length) {
|
||||
content.innerHTML = '';
|
||||
_renderSyncedLines(content, track.line.map(l => ({ start: l.start, value: l.value || '' })).filter(l => l.value));
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Fallback: LRCLIB directly (synced LRC format)
|
||||
const firstArtist = (s?.artist||'').split(/[/,]/)[0].trim();
|
||||
let lrcText = null;
|
||||
let lrclibPlain = null;
|
||||
try {
|
||||
const attempts = [
|
||||
new URLSearchParams({ artist_name: firstArtist, track_name: s?.title||'', ...(s?.album ? { album_name: s.album } : {}) }),
|
||||
...(s?.album ? [new URLSearchParams({ artist_name: firstArtist, track_name: s?.title||'' })] : []),
|
||||
];
|
||||
for(const p of attempts) {
|
||||
if(token !== _lyricsLoadToken) return;
|
||||
const r = await fetch(`https://lrclib.net/api/get?${p}`, { signal: AbortSignal.timeout(6000) });
|
||||
if(r.ok) {
|
||||
const d = await r.json();
|
||||
lrcText = d.syncedLyrics || null;
|
||||
lrclibPlain = d.plainLyrics || null;
|
||||
if(lrcText || lrclibPlain) break;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
if(token !== _lyricsLoadToken) return;
|
||||
|
||||
content.innerHTML = '';
|
||||
if(lrcText) {
|
||||
const parsed = _parseLrc(lrcText);
|
||||
if(parsed.length) { _renderSyncedLines(content, parsed); return; }
|
||||
}
|
||||
const synced = lyrics.find(t => t.synced && t.line?.length);
|
||||
const plain = lyrics.find(t => t.line?.length);
|
||||
|
||||
const plain = lrclibPlain || (track?.line?.length ? track.line.map(l => l.value).join('\n') : null);
|
||||
if(synced) {
|
||||
_renderSyncedLines(content, synced.line.map(l => ({ start: l.start, value: l.value || '' })).filter(l => l.value));
|
||||
return;
|
||||
}
|
||||
if(plain) {
|
||||
const el = document.createElement('div');
|
||||
el.className = 'lyrics-plain';
|
||||
el.textContent = plain;
|
||||
content.appendChild(el);
|
||||
} else {
|
||||
const el = document.createElement('div');
|
||||
el.className = 'lyrics-none';
|
||||
el.style.cssText = 'text-align:center;padding:60px 0;color:rgba(255,255,255,.3);font-size:14px';
|
||||
el.textContent = 'Keine Lyrics verfügbar';
|
||||
el.textContent = plain.line.map(l => l.value).join('\n');
|
||||
content.appendChild(el);
|
||||
return;
|
||||
}
|
||||
const el = document.createElement('div');
|
||||
el.className = 'lyrics-none';
|
||||
el.style.cssText = 'text-align:center;padding:60px 0;color:rgba(255,255,255,.3);font-size:14px';
|
||||
el.textContent = 'Keine Lyrics verfügbar';
|
||||
content.appendChild(el);
|
||||
}
|
||||
|
||||
export function updateLyricsHighlight(currentMs) {
|
||||
|
||||
Reference in new issue
Block a user