diff --git a/static/v3/songs.js b/static/v3/songs.js index b3688c8..ed86acd 100644 --- a/static/v3/songs.js +++ b/static/v3/songs.js @@ -710,10 +710,6 @@ async function loadTree() { const host = document.getElementById('v3-songs-tree'); if (!host) return; - // Capture expanded groups BEFORE the "Loading…" wipe below, so a reload - // (e.g. toggling select mode) restores them instead of collapsing all. - const openArtists = new Set( - [...host.querySelectorAll('details[open]')].map((d) => d.getAttribute('data-artist'))); host.innerHTML = '

Loading…

'; // Page through ALL artists — the endpoint clamps size to 100, so a // single request would silently truncate libraries with >100 artists. @@ -730,33 +726,18 @@ if (!artists.length) { host.innerHTML = '

Nothing here.

'; return; } artists.forEach((a) => (a.albums || []).forEach((al) => (al.songs || []).forEach((s) => { state.songsById[cardKey(s)] = s; }))); host.innerHTML = artists.map((a) => - '
' + + '
' + '' + esc(a.name) + '' + esc(a.song_count) + '' + '
' + (a.albums || []).map((al) => '
' + esc(al.name || 'Unknown') + '
' + - (al.songs || []).map((s) => { - const k = cardKey(s); const fl = fmtLabel(s); const chips = arrChipsHtml(s); const sel = state.selected.has(k); - // Display-only checkbox (pointer-events-none); the row's - // capture-phase select handler (render()) owns the toggle. - const checkbox = state.selectMode - ? '' - : ''; - return ( - '
' + - checkbox + - '' + + (al.songs || []).map((s) => { const k = cardKey(s); const fl = fmtLabel(s); const chips = arrChipsHtml(s); return ( + '
' + + '' + '' + esc(s.title) + '' + - (chips ? '' + chips + '' : '') + + (chips ? '' : '') + (fl ? '' + fl + '' : '') + accuracyBadge(k, 'tree') + - // Same fav / save-for-later / overflow-menu cluster as the grid - // card. Always shown (like the arrangement chips), not hover- - // revealed. wireCards() binds all three for any [data-fn]. - '
' + - '' + - '' + - '' + - '
' + + '' + '
'); }).join('') + '
').join('') + '
').join(''); wireCards(host); } @@ -964,21 +945,6 @@ e.stopImmediatePropagation(); toggleSelect(card.getAttribute('data-fn'), card); }, true); - - // Same bulletproof guard for the list/tree view. Without it, clicking a - // song row (or its arrangement chip) in select mode falls through to the - // per-card play handler and starts playback instead of selecting. The - // group headers sit OUTSIDE any [data-fn], so closest() is null - // for them and their native expand/collapse is left untouched. - const treeEl = byId('v3-songs-tree'); - if (treeEl) treeEl.addEventListener('click', (e) => { - if (!state.selectMode) return; - const card = e.target.closest('[data-fn]'); - if (!card || !treeEl.contains(card)) return; - e.preventDefault(); - e.stopImmediatePropagation(); - toggleSelect(card.getAttribute('data-fn'), card); - }, true); const setView = (v) => { state.view = v; byId('v3-songs-grid-btn').className = 'px-3 py-2 text-sm ' + (v === 'grid' ? 'bg-fb-primary text-white' : 'text-fb-textDim'); @@ -1131,4 +1097,4 @@ if (active && active.id === 'v3-songs') applyScoreRefresh(); }); } -})(); \ No newline at end of file +})();