feat: all-songs view as separate page, iTunes album detail page
- 'Alle X Songs' button now navigates to a dedicated page instead of expanding inline - Partial/not-downloaded albums now open an iTunes album detail page with track list, preview buttons and download option - Added page-artist-all-songs and page-itunes-album-detail to index.html - Replaced _expandArtistAllSongs with loadArtistAllSongs + loadItunesAlbumDetail Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
72f6087043
commit
976e80f86d
2 files changed
+61
-10
No files matched your search
+25
@@ -177,6 +177,31 @@
|
||||
<div id="artist-albums-section"></div>
|
||||
</div>
|
||||
|
||||
<!-- ARTIST ALL SONGS -->
|
||||
<div class="page" id="page-artist-all-songs">
|
||||
<button class="back-btn" id="artist-songs-back-btn"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>Zurück</button>
|
||||
<div class="page-header" style="margin-top:8px"><div class="page-title" id="artist-songs-title">Alle Songs</div></div>
|
||||
<div id="artist-songs-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- ITUNES ALBUM DETAIL -->
|
||||
<div class="page" id="page-itunes-album-detail">
|
||||
<button class="back-btn" id="itunes-album-back-btn"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>Zurück</button>
|
||||
<div class="album-header">
|
||||
<div class="album-cover" id="itunes-album-cover-wrap"><div class="no-art">💿</div></div>
|
||||
<div class="album-meta">
|
||||
<div class="album-type">iTunes</div>
|
||||
<div class="album-name" id="itunes-album-detail-name">—</div>
|
||||
<div class="album-artist-name" id="itunes-album-detail-artist"></div>
|
||||
<div class="album-stats" id="itunes-album-detail-stats"></div>
|
||||
<div class="album-actions">
|
||||
<button class="btn-outline" id="itunes-album-dl-btn"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>Album laden</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="itunes-album-songs"></div>
|
||||
</div>
|
||||
|
||||
<!-- ALBUMS -->
|
||||
<div class="page" id="page-albums">
|
||||
<div class="page-header"><div class="page-title">Alben</div></div>
|
||||
|
||||
+36
-10
@@ -39,7 +39,9 @@ export function navigate(page, data=null) {
|
||||
if(page==='starred') loadStarred();
|
||||
if(page==='random') loadRandom();
|
||||
if(page==='artist-detail' && data) loadArtistDetail(data);
|
||||
if(page==='artist-all-songs' && data) loadArtistAllSongs(data);
|
||||
if(page==='album-detail' && data) loadAlbumDetail(data);
|
||||
if(page==='itunes-album-detail'&& data) loadItunesAlbumDetail(data);
|
||||
if(page==='new-releases') loadNewReleases();
|
||||
if(page==='playlists') loadPlaylists();
|
||||
if(page==='playlist-detail' && data) loadPlaylistDetail(data);
|
||||
@@ -319,7 +321,7 @@ export async function loadArtistDetail(artist) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'btn-outline'; btn.style.cssText = 'font-size:12px;padding:7px 14px;margin-bottom:16px;margin-top:4px';
|
||||
btn.textContent = `Alle ${total} Songs in Library`;
|
||||
btn.onclick = () => _expandArtistAllSongs(btn, ndAlbums, artist);
|
||||
btn.onclick = () => navigate('artist-all-songs', { albums: ndAlbums, artist });
|
||||
tsEl.appendChild(btn);
|
||||
}
|
||||
}
|
||||
@@ -391,7 +393,7 @@ function _renderArtistAlbums(el, ndAlbums, iAlbums, artist) {
|
||||
const art = itunes?.artworkUrl100?.replace('100x100','300x300') || coverUrl(nd.coverArt, 300);
|
||||
const c = makeCard(nd.name, `${have} / ${total} Tracks`, art, '💿');
|
||||
c.querySelector('.play-btn').onclick = (e) => { e.stopPropagation(); quickPlayAlbum(nd); };
|
||||
c.onclick = () => navigate('album-detail', { ...nd, _fromArtist: artist });
|
||||
c.onclick = () => itunes ? navigate('itunes-album-detail', itunes) : navigate('album-detail', { ...nd, _fromArtist: artist });
|
||||
const artEl = c.querySelector('.card-art');
|
||||
const badge = document.createElement('div');
|
||||
badge.className = 'album-partial-badge'; badge.textContent = `${have}/${total}`;
|
||||
@@ -412,7 +414,7 @@ function _renderArtistAlbums(el, ndAlbums, iAlbums, artist) {
|
||||
notDl.forEach(ia => {
|
||||
const art = ia.artworkUrl100?.replace('100x100','300x300');
|
||||
const c = makeCard(ia.collectionName, ia.releaseDate?.slice(0,4)||'', art, '💿');
|
||||
c.onclick = () => loadItunesAlbum(ia);
|
||||
c.onclick = () => navigate('itunes-album-detail', ia);
|
||||
const artEl = c.querySelector('.card-art');
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'card-dl-btn'; btn.title = 'Album laden';
|
||||
@@ -430,11 +432,13 @@ function _renderArtistAlbums(el, ndAlbums, iAlbums, artist) {
|
||||
}
|
||||
}
|
||||
|
||||
async function _expandArtistAllSongs(btn, albums, artist) {
|
||||
btn.disabled = true; btn.textContent = 'Lädt…';
|
||||
export async function loadArtistAllSongs({ albums, artist }) {
|
||||
document.getElementById('artist-songs-title').textContent = `Alle Songs · ${artist.name}`;
|
||||
document.getElementById('artist-songs-back-btn').onclick = () => _navGoBack();
|
||||
const el = document.getElementById('artist-songs-list');
|
||||
el.innerHTML = '<div class="spinner"></div>';
|
||||
const results = await Promise.allSettled(albums.map(a => api('getAlbum', `&id=${a.id}`)));
|
||||
const container = document.createElement('div'); container.style.marginBottom = '16px';
|
||||
btn.replaceWith(container);
|
||||
el.innerHTML = '';
|
||||
const allSongs = results
|
||||
.filter(r => r.status === 'fulfilled')
|
||||
.flatMap(r => { const alb = r.value?.album; return (alb?.song || []).map(s => ({ ...s, _alb: alb })); })
|
||||
@@ -448,8 +452,9 @@ async function _expandArtistAllSongs(btn, albums, artist) {
|
||||
if(s._alb?.id !== curId) {
|
||||
curId = s._alb?.id || '';
|
||||
const h = document.createElement('div');
|
||||
h.style.cssText = 'font-size:12px;font-weight:700;color:var(--text2);padding:8px 0 2px;border-top:1px solid var(--border);margin-top:4px';
|
||||
h.textContent = s._alb?.name || ''; container.appendChild(h);
|
||||
h.style.cssText = 'font-size:12px;font-weight:700;color:var(--text2);padding:12px 0 4px;border-top:1px solid var(--border);margin-top:4px';
|
||||
h.textContent = s._alb?.name || '';
|
||||
el.appendChild(h);
|
||||
}
|
||||
const cv = coverUrl(s.coverArt, 60);
|
||||
const row = document.createElement('div'); row.className = 'topsong-item';
|
||||
@@ -459,10 +464,31 @@ async function _expandArtistAllSongs(btn, albums, artist) {
|
||||
<div class="topsong-plays">${s.playCount?s.playCount.toLocaleString():''}</div>`;
|
||||
row.onclick = () => playQueue(allSongs, i);
|
||||
row.addEventListener('contextmenu', e => { e.preventDefault(); showCtxMenu(e, s, allSongs, i); });
|
||||
container.appendChild(row);
|
||||
el.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadItunesAlbumDetail(album) {
|
||||
document.getElementById('itunes-album-back-btn').onclick = () => _navGoBack();
|
||||
document.getElementById('itunes-album-detail-name').textContent = album.collectionName || '—';
|
||||
document.getElementById('itunes-album-detail-artist').textContent = album.artistName || '';
|
||||
const cw = document.getElementById('itunes-album-cover-wrap');
|
||||
const art = (album.artworkUrl100 || '').replace('100x100bb','600x600bb').replace('100x100','600x600');
|
||||
cw.innerHTML = art ? `<img src="${art}" onerror="this.parentNode.innerHTML='<div class=\\'no-art\\'>💿</div>'">` : '<div class="no-art">💿</div>';
|
||||
const dlBtn = document.getElementById('itunes-album-dl-btn');
|
||||
dlBtn.onclick = () => openDlModal({ artistName: album.artistName, trackName: album.collectionName, collectionName: album.collectionName, artworkUrl100: album.artworkUrl100||'', isAlbum: true, itunesData: album, collectionId: album.collectionId });
|
||||
const sl = document.getElementById('itunes-album-songs');
|
||||
sl.innerHTML = '<div class="spinner"></div>';
|
||||
try {
|
||||
const tracks = await itunesLookupAlbum(album.collectionId);
|
||||
const year = album.releaseDate ? new Date(album.releaseDate).getFullYear() : '';
|
||||
document.getElementById('itunes-album-detail-stats').textContent = `${tracks.length} Titel${year ? ' · ' + year : ''}`;
|
||||
sl.innerHTML = '';
|
||||
if(!tracks.length) { sl.innerHTML = '<div style="padding:16px;color:var(--text3)">Keine Tracks gefunden</div>'; return; }
|
||||
tracks.forEach((t, i) => sl.appendChild(makeGlobalTrackItem(t, i, tracks)));
|
||||
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
|
||||
}
|
||||
|
||||
// ─── ALBUM DETAIL ───
|
||||
export async function loadAlbumDetail(album) {
|
||||
document.getElementById('album-back-btn').onclick = () =>
|
||||
|
||||
Reference in new issue
Block a user