discover: fold the remaining mixes into the "Your Mixes" shelf
Fresh Tape (release_radar), The Archives (discovery_weekly), and the Seasonal/Summer Mix (seasonal_playlist) move out of their old full-width compact-track-table sections into the unified shelf as mix cards (set the global in the controller renderItems, then _upsertMixCard + collapse the old section after load). Daily Mixes loader is converted the same way (each mix → a card) for if/when that HIDDEN feature is re-enabled. So every active mix now lives in one consistent shelf. 64 script-integrity tests green.
This commit is contained in:
parent
9d5e58c4b8
commit
9c832ab3c3
1 changed files with 41 additions and 58 deletions
|
|
@ -1788,11 +1788,7 @@ async function loadDiscoverReleaseRadar() {
|
|||
contentEl: '#release-radar-playlist',
|
||||
fetchUrl: '/api/discover/release-radar',
|
||||
extractItems: (data) => data.tracks || [],
|
||||
renderItems: (items) => {
|
||||
discoverReleaseRadarTracks = items;
|
||||
const rows = items.map((t, i) => _renderCompactTrackRow(t, i)).join('');
|
||||
return `<div class="discover-playlist-tracks-compact">${rows}</div>`;
|
||||
},
|
||||
renderItems: (items) => { discoverReleaseRadarTracks = items; return ''; },
|
||||
loadingMessage: 'Loading release radar...',
|
||||
emptyMessage: 'No new releases available',
|
||||
errorMessage: 'Failed to load release radar',
|
||||
|
|
@ -1800,7 +1796,16 @@ async function loadDiscoverReleaseRadar() {
|
|||
showErrorToast: true,
|
||||
});
|
||||
}
|
||||
return _releaseRadarCtrl.load();
|
||||
await _releaseRadarCtrl.load();
|
||||
const c = document.querySelector('#release-radar-playlist');
|
||||
if (c) _collapseOldMixSection(c);
|
||||
if (discoverReleaseRadarTracks && discoverReleaseRadarTracks.length) {
|
||||
_upsertMixCard({
|
||||
key: 'release_radar', title: 'Fresh Tape',
|
||||
subtitle: 'New releases from artists you follow',
|
||||
tracks: discoverReleaseRadarTracks, syncKey: 'release_radar',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let _weeklyCtrl = null;
|
||||
|
|
@ -1812,11 +1817,7 @@ async function loadDiscoverWeekly() {
|
|||
contentEl: '#discovery-weekly-playlist',
|
||||
fetchUrl: '/api/discover/weekly',
|
||||
extractItems: (data) => data.tracks || [],
|
||||
renderItems: (items) => {
|
||||
discoverWeeklyTracks = items;
|
||||
const rows = items.map((t, i) => _renderCompactTrackRow(t, i)).join('');
|
||||
return `<div class="discover-playlist-tracks-compact">${rows}</div>`;
|
||||
},
|
||||
renderItems: (items) => { discoverWeeklyTracks = items; return ''; },
|
||||
loadingMessage: 'Curating your discovery playlist...',
|
||||
emptyMessage: 'No tracks available yet',
|
||||
errorMessage: 'Failed to load discovery weekly',
|
||||
|
|
@ -1824,7 +1825,16 @@ async function loadDiscoverWeekly() {
|
|||
showErrorToast: true,
|
||||
});
|
||||
}
|
||||
return _weeklyCtrl.load();
|
||||
await _weeklyCtrl.load();
|
||||
const c = document.querySelector('#discovery-weekly-playlist');
|
||||
if (c) _collapseOldMixSection(c);
|
||||
if (discoverWeeklyTracks && discoverWeeklyTracks.length) {
|
||||
_upsertMixCard({
|
||||
key: 'discovery_weekly', title: 'The Archives',
|
||||
subtitle: 'A weekly dig through artists across your library',
|
||||
tracks: discoverWeeklyTracks, syncKey: 'discovery_weekly',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================
|
||||
|
|
@ -4050,23 +4060,6 @@ async function loadSeasonalPlaylist(seasonData) {
|
|||
const playlistContainer = document.getElementById('seasonal-playlist');
|
||||
if (!playlistContainer) return;
|
||||
|
||||
// Show seasonal playlist section
|
||||
const seasonalPlaylistSection = document.getElementById('seasonal-playlist-section');
|
||||
if (seasonalPlaylistSection) {
|
||||
seasonalPlaylistSection.style.display = 'block';
|
||||
}
|
||||
|
||||
// Update header
|
||||
const playlistTitle = document.getElementById('seasonal-playlist-title');
|
||||
const playlistSubtitle = document.getElementById('seasonal-playlist-subtitle');
|
||||
|
||||
if (playlistTitle) {
|
||||
playlistTitle.textContent = `${seasonData.icon} ${seasonData.name} Mix`;
|
||||
}
|
||||
if (playlistSubtitle) {
|
||||
playlistSubtitle.textContent = `Curated playlist for ${seasonData.name.toLowerCase()}`;
|
||||
}
|
||||
|
||||
// Re-create the controller when the season key changes so the
|
||||
// fetchUrl always points at the active season's endpoint.
|
||||
if (!_seasonalPlaylistCtrl || _seasonalPlaylistCtrlKey !== currentSeasonKey) {
|
||||
|
|
@ -4075,11 +4068,7 @@ async function loadSeasonalPlaylist(seasonData) {
|
|||
contentEl: '#seasonal-playlist',
|
||||
fetchUrl: `/api/discover/seasonal/${currentSeasonKey}/playlist`,
|
||||
extractItems: (data) => data.tracks || [],
|
||||
renderItems: (items) => {
|
||||
discoverSeasonalTracks = items;
|
||||
const rows = items.map((t, i) => _renderCompactTrackRow(t, i)).join('');
|
||||
return `<div class="discover-playlist-tracks-compact">${rows}</div>`;
|
||||
},
|
||||
renderItems: (items) => { discoverSeasonalTracks = items; return ''; },
|
||||
loadingMessage: 'Loading playlist...',
|
||||
emptyMessage: 'No tracks available yet',
|
||||
errorMessage: 'Failed to load playlist',
|
||||
|
|
@ -4088,7 +4077,16 @@ async function loadSeasonalPlaylist(seasonData) {
|
|||
});
|
||||
_seasonalPlaylistCtrlKey = currentSeasonKey;
|
||||
}
|
||||
return _seasonalPlaylistCtrl.load();
|
||||
await _seasonalPlaylistCtrl.load();
|
||||
_collapseOldMixSection(playlistContainer);
|
||||
if (discoverSeasonalTracks && discoverSeasonalTracks.length) {
|
||||
_upsertMixCard({
|
||||
key: 'seasonal_playlist',
|
||||
title: `${seasonData.icon} ${seasonData.name} Mix`,
|
||||
subtitle: `Curated playlist for ${seasonData.name.toLowerCase()}`,
|
||||
tracks: discoverSeasonalTracks, syncKey: 'seasonal_playlist',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function hideSeasonalSections() {
|
||||
|
|
@ -4364,31 +4362,16 @@ async function loadPersonalizedDailyMixes() {
|
|||
}
|
||||
|
||||
personalizedDailyMixes = data.mixes;
|
||||
|
||||
// Render Daily Mix cards
|
||||
let html = '';
|
||||
// Fold each daily mix into the unified "Your Mixes" shelf (#discover redesign).
|
||||
// (Their old open action was a no-op stub; opening to the track list is an upgrade.)
|
||||
data.mixes.forEach((mix, index) => {
|
||||
const coverUrl = mix.tracks && mix.tracks.length > 0 ?
|
||||
(mix.tracks[0].album_cover_url || '/static/placeholder-album.png') :
|
||||
'/static/placeholder-album.png';
|
||||
|
||||
html += `
|
||||
<div class="discover-playlist-card" onclick="openDailyMix(${index})">
|
||||
<div class="discover-playlist-cover">
|
||||
<img src="${coverUrl}" alt="${mix.name}" loading="lazy">
|
||||
<div class="playlist-play-overlay">▶</div>
|
||||
</div>
|
||||
<div class="discover-playlist-info">
|
||||
<h4 class="discover-playlist-name">${mix.name}</h4>
|
||||
<p class="discover-playlist-description">${mix.description}</p>
|
||||
<p class="discover-playlist-count">${mix.track_count} tracks</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
_upsertMixCard({
|
||||
key: `daily_mix_${index}`, title: mix.name,
|
||||
subtitle: mix.description || 'Daily Mix',
|
||||
tracks: mix.tracks || [],
|
||||
});
|
||||
});
|
||||
|
||||
container.innerHTML = html;
|
||||
container.closest('.discover-section').style.display = 'block';
|
||||
_collapseOldMixSection(container);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading daily mixes:', error);
|
||||
|
|
|
|||
Loading…
Reference in a new issue