fix: split multi-artists by • and /, clickable artist/album in playlists and album detail

- components.js: expand artist split regex to handle both ' / ' and '•' separators
- views.js: enable artist+album links in playlist song items (were noArtistLink:true)
- views.js: enable artist links in album detail song items
- views.js: album header artist is now split and renders as clickable links

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-04-28 00:31:48 +02:00
1 parent 51babd9e41
commit e5a80242e9
2 files changed
+8 -5

No files matched your search

+7 -4
View File
@@ -422,8 +422,11 @@ export async function loadAlbumDetail(album) {
album._fromArtist ? navigate('artist-detail', album._fromArtist) : navigate('albums');
document.getElementById('album-detail-name').textContent = album.name;
const artistEl = document.getElementById('album-detail-artist');
artistEl.textContent = album.artist || '';
artistEl.onclick = () => { if(album.artistId) navigate('artist-detail', {id:album.artistId, name:album.artist}); };
const albumArtistParts = (album.artist || '').split(/\s*(?:\/|•)\s*/).filter(Boolean);
artistEl.innerHTML = albumArtistParts.map((name, i) => {
const aid = i === 0 ? (album.artistId || '') : '';
return `<span class="song-link" onclick="s_goArtist(event,${JSON.stringify(name)},${JSON.stringify(aid)})">${esc(name)}</span>`;
}).join('<span style="color:var(--text3)"> / </span>') || '';
const cw = document.getElementById('album-cover-wrap');
const cv = coverUrl(album.coverArt, 300);
cw.innerHTML = cv ? `<img src="${cv}" onerror="this.parentNode.innerHTML='<div class=\\'no-art\\'>💿</div>'">` : '<div class="no-art">💿</div>';
@@ -440,7 +443,7 @@ export async function loadAlbumDetail(album) {
toast(`⬇ ${songs.length} Titel Download gestartet`);
};
sl.innerHTML = '';
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true })));
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noAlbumLink: true })));
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
}
@@ -492,7 +495,7 @@ export async function loadPlaylistDetail(pl) {
playQueue(shuffled, 0);
};
sl.innerHTML = '';
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true })));
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs)));
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
}