diff --git a/index.html b/index.html index dcc292a..86c5486 100644 --- a/index.html +++ b/index.html @@ -177,6 +177,31 @@
+ +
+ + +
+
+ + +
+ +
+
💿
+
+
iTunes
+
—
+
+
+
+ +
+
+
+
+
+
diff --git a/src/views.js b/src/views.js index 10b3df1..308d737 100644 --- a/src/views.js +++ b/src/views.js @@ -38,8 +38,10 @@ export function navigate(page, data=null) { if(page==='albums' && !document.getElementById('albums-grid').children.length) loadAlbums(); if(page==='starred') loadStarred(); if(page==='random') loadRandom(); - if(page==='artist-detail' && data) loadArtistDetail(data); - if(page==='album-detail' && data) loadAlbumDetail(data); + 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 = '
'; 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) {
${s.playCount?s.playCount.toLocaleString():''}
`; 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 ? `` : '
💿
'; + 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 = '
'; + 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 = '
Keine Tracks gefunden
'; return; } + tracks.forEach((t, i) => sl.appendChild(makeGlobalTrackItem(t, i, tracks))); + } catch(e) { sl.innerHTML = `

${e.message}

`; } +} + // ─── ALBUM DETAIL ─── export async function loadAlbumDetail(album) { document.getElementById('album-back-btn').onclick = () =>