Show playlists instead of the branding hero on the empty home

This commit is contained in:
Jonathan Sykes
2026-08-15 07:19:46 +00:00
parent b2154bd9c4
commit fa9ef000b9
3 changed files with 119 additions and 0 deletions

View File

@@ -1936,6 +1936,52 @@ function renderSidebar() {
});
updateQueueBadge();
updateDownloadBadge();
renderHomePlaylists();
}
// The empty player pane (nothing playing yet) shows the branding hero. Once
// this device has playlists, they take that space instead — the hero stays as
// the fallback so a first-time visitor still gets the landing.
// Driven from renderSidebar() so every playlist mutation refreshes both.
function renderHomePlaylists() {
const wrap = document.getElementById('homePlaylists');
const hero = document.querySelector('#playerPlaceholder .hero');
const grid = document.getElementById('homePlGrid');
if (!wrap || !hero || !grid) return;
const lists = data.playlists || [];
wrap.classList.toggle('hidden', !lists.length);
hero.classList.toggle('hidden', !!lists.length);
// The hero is centered art; the grid wants the full box, so the placeholder
// switches from centering to stretching (and tightens its padding).
if (els.placeholder) els.placeholder.classList.toggle('showing-playlists', !!lists.length);
if (!lists.length) { grid.innerHTML = ''; return; }
grid.innerHTML = '';
for (const pl of lists) {
const count = pl.videos.length;
const thumb = (pl.videos.find((v) => v && v.thumbnail) || {}).thumbnail || '';
const card = document.createElement('button');
card.className = 'home-pl-card';
card.type = 'button';
card.innerHTML = `
<span class="home-pl-thumb">
${thumb ? `<img src="${escapeHtml(thumb)}" alt="" loading="lazy" />`
: '<span class="home-pl-thumb-fallback">🎵</span>'}
<span class="home-pl-play" title="Play all">▶</span>
</span>
<span class="home-pl-name"></span>
<span class="home-pl-count">${count} video${count === 1 ? '' : 's'}</span>`;
card.querySelector('.home-pl-name').textContent = pl.name;
card.title = pl.name;
card.addEventListener('click', () => { view = { type: 'playlist', id: pl.id }; render(); });
card.querySelector('.home-pl-play').addEventListener('click', (e) => {
e.stopPropagation(); // the ▶ badge plays; the rest of the card opens the list
if (count) playFromList(pl.videos, 0, 'playlist:' + pl.id);
else toast('That playlist is empty');
});
grid.appendChild(card);
}
}
function currentList() {
@@ -3263,6 +3309,9 @@ function wireUI() {
$('sidebarProfileCopy').addEventListener('click', copyProfileLink);
$('sidebarProfileShare').addEventListener('click', shareProfileLink);
// ---- Empty-home playlist grid ----
$('homePlNewBtn').addEventListener('click', () => newPlaylist(null));
els.searchForm.addEventListener('submit', async (e) => {
e.preventDefault();
const q = els.searchInput.value.trim();