From e5a80242e9fcfba60709a5e3f4a15add3a0899b0 Mon Sep 17 00:00:00 2001 From: Honey Date: Tue, 28 Apr 2026 00:31:48 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20split=20multi-artists=20by=20=E2=80=A2?= =?UTF-8?q?=20and=20/,=20clickable=20artist/album=20in=20playlists=20and?= =?UTF-8?q?=20album=20detail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- src/components.js | 2 +- src/views.js | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components.js b/src/components.js index 3f35e2e..37edd8f 100644 --- a/src/components.js +++ b/src/components.js @@ -32,7 +32,7 @@ export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink = if(s.starred && !s._starred) s._starred = true; el.className = 'song-item' + (S.queue[S.qIdx]?.id === s.id ? ' playing' : ''); const cv = coverUrl(s.coverArt, 60); - const artistParts = (s.artist || '').split(' / ').filter(Boolean); + const artistParts = (s.artist || '').split(/\s*(?:\/|•)\s*/).filter(Boolean); const artistHtml = artistParts.length ? artistParts.map((name, i) => { const aid = i === 0 ? (s.artistId || '') : ''; diff --git a/src/views.js b/src/views.js index 9191eb6..75d2955 100644 --- a/src/views.js +++ b/src/views.js @@ -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 `${esc(name)}`; + }).join(' / ') || ''; const cw = document.getElementById('album-cover-wrap'); const cv = coverUrl(album.coverArt, 300); cw.innerHTML = cv ? `` : '
💿
'; @@ -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 = `

${e.message}

`; } } @@ -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 = `

${e.message}

`; } }