feat: remove album from song subtitle; add Go to Album in context menu

Album name no longer shown inline next to the artist — navigate via
right-click > Zum Album instead, available everywhere.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-23 22:47:43 +02:00
1 parent 5093ce1f9d
commit c6990cfd7b
3 files changed
+7 -9

No files matched your search

+3 -6
View File
@@ -27,7 +27,7 @@ export function makeAlbumCard(a) {
} }
// ─── SONG LIST ITEM (library) ─── // ─── SONG LIST ITEM (library) ───
export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink = false } = {}) { export function makeSongItem(s, idx, list, { noArtistLink = false } = {}) {
const el = document.createElement('div'); const el = document.createElement('div');
if(s.starred && !s._starred) s._starred = true; if(s.starred && !s._starred) s._starred = true;
el.className = 'song-item' + (S.queue[S.qIdx]?.id === s.id ? ' playing' : ''); el.className = 'song-item' + (S.queue[S.qIdx]?.id === s.id ? ' playing' : '');
@@ -40,10 +40,7 @@ export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink =
: `<span class="song-link" onclick="event.stopPropagation();s_goArtist(event,'${esc(a.name)}','${a.id||''}')">${esc(a.name)}</span>` : `<span class="song-link" onclick="event.stopPropagation();s_goArtist(event,'${esc(a.name)}','${a.id||''}')">${esc(a.name)}</span>`
).join('<span style="color:var(--text3)"> • </span>') ).join('<span style="color:var(--text3)"> • </span>')
: ''; : '';
// Hide album in subtitle when it's identical to the track title (common for singles)
const albumHtml = !noAlbumLink && (s.albumId||s.album) && s.album !== s.title
? `<span style="color:var(--text3)"> · </span><span class="song-link" onclick="event.stopPropagation();s_goAlbum(event,'${s.albumId||''}','${esc(s.album||'')}','${esc(s.artist||'')}','${s.artistId||''}')">${esc(s.album||'')}</span>`
: '';
const playsHtml = S.cfg.showPlayCount const playsHtml = S.cfg.showPlayCount
? `<span class="song-plays">${s.playCount ? s.playCount.toLocaleString() + '<span class="song-plays-x">×</span>' : '—'}</span>` ? `<span class="song-plays">${s.playCount ? s.playCount.toLocaleString() + '<span class="song-plays-x">×</span>' : '—'}</span>`
: ''; : '';
@@ -51,7 +48,7 @@ export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink =
<div class="song-thumb">${cv ? `<img src="${cv}" loading="lazy" onerror="this.parentNode.innerHTML='<div class=\\'no-art\\'>♪</div>'">` : '<div class="no-art">♪</div>'}</div> <div class="song-thumb">${cv ? `<img src="${cv}" loading="lazy" onerror="this.parentNode.innerHTML='<div class=\\'no-art\\'>♪</div>'">` : '<div class="no-art">♪</div>'}</div>
<div class="song-info"> <div class="song-info">
<div class="song-title">${esc(s.title)}</div> <div class="song-title">${esc(s.title)}</div>
<div class="song-artist">${artistHtml}${albumHtml}</div> <div class="song-artist">${artistHtml}</div>
</div> </div>
<div class="song-meta"> <div class="song-meta">
<span class="song-dur">${formatDur(s.duration)}</span> <span class="song-dur">${formatDur(s.duration)}</span>
+1
View File
@@ -135,6 +135,7 @@ export function showCtxMenu(e, song, list, idx) {
.catch(err => toast('Fehler: ' + err.message)); .catch(err => toast('Fehler: ' + err.message));
}}, }},
{ sep: true }, { sep: true },
{ icon: '💿', label: 'Zum Album', fn: () => song.albumId && navigate('album-detail', { id: song.albumId, name: song.album||'', artist: song.artist||'', artistId: song.artistId||'', coverArt: song.coverArt||'' }) },
{ icon: 'ℹ', label: 'Song-Info', fn: () => showSongInfo(song) }, { icon: 'ℹ', label: 'Song-Info', fn: () => showSongInfo(song) },
{ icon: '⬇', label: 'Herunterladen', fn: () => dlSongLocal(song) }, { icon: '⬇', label: 'Herunterladen', fn: () => dlSongLocal(song) },
]; ];
+3 -3
View File
@@ -644,7 +644,7 @@ export async function loadAlbumDetail(album) {
toast(`⬇ ${songs.length} Titel Download gestartet`); toast(`⬇ ${songs.length} Titel Download gestartet`);
}; };
sl.innerHTML = ''; sl.innerHTML = '';
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noAlbumLink: true }))); songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs)));
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; } } catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
} }
@@ -711,7 +711,7 @@ export async function loadPlaylistDetail(pl) {
sl.innerHTML = ''; sl.innerHTML = '';
const plSearch = document.getElementById('playlist-search'); const plSearch = document.getElementById('playlist-search');
if (plSearch) plSearch.value = ''; if (plSearch) plSearch.value = '';
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true }))); songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true })));
_setupReorderMode(sl, songs, S._currentPlaylist); _setupReorderMode(sl, songs, S._currentPlaylist);
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; } } catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
} }
@@ -880,7 +880,7 @@ export async function loadStarred(sort = _starredSort) {
else if (sort === 'plays') songs.sort((a, b) => (b.playCount||0) - (a.playCount||0)); else if (sort === 'plays') songs.sort((a, b) => (b.playCount||0) - (a.playCount||0));
el.innerHTML = ''; el.innerHTML = '';
if(!songs.length) { el.innerHTML = '<div class="empty-state"><div class="icon">⭐</div><p>Noch keine Favoriten</p></div>'; return; } if(!songs.length) { el.innerHTML = '<div class="empty-state"><div class="icon">⭐</div><p>Noch keine Favoriten</p></div>'; return; }
songs.forEach((s,i) => el.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true }))); songs.forEach((s,i) => el.appendChild(makeSongItem(s, i, songs, { noArtistLink: true })));
} catch(e) { el.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; } } catch(e) { el.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
} }