Progressive track list rendering for large playlists

main
Broque Thomas 2 days ago
parent ed184f9bb8
commit 2c56b23c27

@ -5601,6 +5601,65 @@ let currentModalPlaylistId = null;
// PHASE 2: Local cancelled track management (GUI PARITY)
let cancelledTracks = new Set(); // Track cancelled track indices like GUI's cancelled_tracks
const TRACK_RENDER_BATCH_SIZE = 100;
function applyProgressiveTrackRendering(playlistId, totalTrackCount) {
if (totalTrackCount <= TRACK_RENDER_BATCH_SIZE) return;
const modal = document.getElementById(`download-missing-modal-${playlistId}`);
if (!modal) return;
const tbody = document.getElementById(`download-tracks-tbody-${playlistId}`);
if (!tbody) return;
const rows = tbody.querySelectorAll('tr[data-track-index]');
if (rows.length <= TRACK_RENDER_BATCH_SIZE) return;
// Hide rows beyond first batch
for (let i = TRACK_RENDER_BATCH_SIZE; i < rows.length; i++) {
rows[i].classList.add('hidden');
}
let revealedCount = TRACK_RENDER_BATCH_SIZE;
// Append indicator into .download-tracks-title
const titleEl = modal.querySelector('.download-tracks-title');
if (titleEl) {
const indicator = document.createElement('span');
indicator.className = 'track-render-indicator';
indicator.id = `track-render-indicator-${playlistId}`;
indicator.textContent = `Showing ${revealedCount} of ${totalTrackCount} tracks`;
titleEl.appendChild(indicator);
}
// Scroll listener on table container
const container = modal.querySelector('.download-tracks-table-container');
if (!container) return;
container.addEventListener('scroll', function onScroll() {
const scrollBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
if (scrollBottom > 200) return;
if (revealedCount >= rows.length) return;
const nextEnd = Math.min(revealedCount + TRACK_RENDER_BATCH_SIZE, rows.length);
for (let i = revealedCount; i < nextEnd; i++) {
rows[i].classList.remove('hidden');
}
revealedCount = nextEnd;
const indicator = document.getElementById(`track-render-indicator-${playlistId}`);
if (indicator) {
indicator.textContent = revealedCount >= rows.length
? `Showing all ${totalTrackCount} tracks`
: `Showing ${revealedCount} of ${totalTrackCount} tracks`;
}
if (revealedCount >= rows.length) {
container.removeEventListener('scroll', onScroll);
}
});
}
async function openDownloadMissingModal(playlistId) {
showLoadingOverlay('Loading playlist...');
@ -5765,6 +5824,7 @@ async function openDownloadMissingModal(playlistId) {
</div>
`;
applyProgressiveTrackRendering(playlistId, tracks.length);
modal.style.display = 'flex';
hideLoadingOverlay();
}
@ -6123,6 +6183,7 @@ async function openDownloadMissingModalForYouTube(virtualPlaylistId, playlistNam
</div>
`;
applyProgressiveTrackRendering(virtualPlaylistId, spotifyTracks.length);
modal.style.display = 'flex';
hideLoadingOverlay();
}
@ -7326,6 +7387,7 @@ async function openDownloadMissingWishlistModal(category = null) {
</div>
`;
applyProgressiveTrackRendering(playlistId, tracks.length);
modal.style.display = 'flex';
hideLoadingOverlay();
WishlistModalState.setVisible(); // Track that new wishlist modal is now visible
@ -14989,6 +15051,7 @@ async function openDownloadMissingModalForTidal(virtualPlaylistId, playlistName,
</div>
`;
applyProgressiveTrackRendering(virtualPlaylistId, spotifyTracks.length);
modal.style.display = 'flex';
hideLoadingOverlay();
}
@ -22079,6 +22142,7 @@ async function openDownloadMissingModalForArtistAlbum(virtualPlaylistId, playlis
</div>
`;
applyProgressiveTrackRendering(virtualPlaylistId, spotifyTracks.length);
modal.style.display = 'flex';
hideLoadingOverlay();

@ -10326,6 +10326,14 @@ body {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.track-render-indicator {
font-size: 11px;
font-weight: 400;
color: #888888;
margin-left: auto;
white-space: nowrap;
}
.download-tracks-table-container {
flex: 1;
overflow-y: auto;

Loading…
Cancel
Save