diff --git a/src/components.js b/src/components.js
index f97bded..0aafb19 100644
--- a/src/components.js
+++ b/src/components.js
@@ -2,7 +2,7 @@ import { S } from './state.js';
import { esc, formatDur } from './utils.js';
import { coverUrl } from './api.js';
// Circular imports — safe (only used inside event handlers after module init)
-import { playQueue, toggleStar, playPreview } from './player.js';
+import { playQueue, toggleStar, playPreview, parseArtists } from './player.js';
import { showCtxMenu, openDlModal } from './ui.js';
import { navigate, quickPlayAlbum, quickPlayArtist } from './views.js';
@@ -33,9 +33,7 @@ export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink =
el.className = 'song-item' + (S.queue[S.qIdx]?.id === s.id ? ' playing' : '');
el.dataset.songId = s.id;
const cv = coverUrl(s.coverArt, 128);
- const artistParts = Array.isArray(s.artists) && s.artists.length
- ? s.artists
- : s.artist ? [{ name: s.artist, id: s.artistId || '' }] : [];
+ const artistParts = parseArtists(s);
const artistHtml = artistParts.length
? artistParts.map(a => noArtistLink
? `${esc(a.name)}`
diff --git a/src/player.js b/src/player.js
index 7ac01a8..5739892 100644
--- a/src/player.js
+++ b/src/player.js
@@ -442,14 +442,20 @@ function _updatePlayingHighlights() {
});
}
+// Returns [{name, id}] using Navidrome's resolved artists when available,
+// otherwise splits the artist string on ';' only (safe for names like Au/Ra).
+export function parseArtists(s) {
+ if (Array.isArray(s.artists) && s.artists.length > 1) return s.artists;
+ return (s.artist || '').split(/\s*;\s*/).filter(Boolean)
+ .map((name, i) => ({ name, id: i === 0 ? (s.artistId || '') : '' }));
+}
+
export function updatePlayerUI(s, _skipMediaSession = false) {
document.getElementById('player-title').textContent = s.title;
- const artistParts = (s.artist || '').split(/\s*(?:\/|•|,)\s*/).filter(Boolean);
+ const artistParts = parseArtists(s);
document.getElementById('player-artist-name').innerHTML = artistParts.length
- ? artistParts.map((name, i) => {
- const aid = i === 0 ? (s.artistId || '') : '';
- return `${esc(name)}`;
- }).join(' • ')
+ ? artistParts.map(a => `${esc(a.name)}`)
+ .join(' • ')
: '—';
document.getElementById('player-album-name').textContent = s.album || '';
const art = document.getElementById('player-art');
@@ -515,12 +521,10 @@ export function _syncNpDirect(s) {
const t = document.getElementById('np-title'); if(t) t.textContent = s.title || '—';
const an = document.getElementById('np-artist-name');
if(an) {
- const parts = (s.artist || '').split(/\s*(?:\/|•|,)\s*/).filter(Boolean);
+ const parts = parseArtists(s);
an.innerHTML = parts.length
- ? parts.map((name, i) => {
- const aid = i === 0 ? (s.artistId || '') : '';
- return `${esc(name)}`;
- }).join(' • ')
+ ? parts.map(a => `${esc(a.name)}`)
+ .join(' • ')
: '—';
}
const aln = document.getElementById('np-album-name'); if(aln) aln.textContent = s.album || '';