queue diff estimates

This commit is contained in:
peterino2 2026-02-08 22:55:38 -08:00
parent 6901f75dfb
commit ce328acd03
6 changed files with 30 additions and 3 deletions

View File

@ -404,6 +404,9 @@
M.setTrackTitle(data.track.title); M.setTrackTitle(data.track.title);
M.loadingSegments.clear(); M.loadingSegments.clear();
// Auto-scroll queue to current track
setTimeout(() => M.scrollToCurrentTrack(), 100);
// Debug: log cache state for this track // Debug: log cache state for this track
const trackCache = M.trackCaches.get(trackId); const trackCache = M.trackCaches.get(trackId);
console.log("[Playback] Starting track:", data.track.title, { console.log("[Playback] Starting track:", data.track.title, {

1
public/controls.js vendored
View File

@ -64,6 +64,7 @@
M.localTimestamp = 0; M.localTimestamp = 0;
M.audio.play(); M.audio.play();
M.renderQueue(); M.renderQueue();
setTimeout(() => M.scrollToCurrentTrack(), 100);
} }
} }

View File

@ -133,7 +133,7 @@
</div> </div>
</div> </div>
<div id="queue-panel"> <div id="queue-panel">
<h3 id="queue-title">Queue</h3> <h3 id="queue-title">Queue <span id="queue-duration"></span></h3>
<div id="now-playing-bar" class="now-playing-bar hidden" title="Click to scroll to current track"></div> <div id="now-playing-bar" class="now-playing-bar hidden" title="Click to scroll to current track"></div>
<div id="queue"></div> <div id="queue"></div>
</div> </div>

View File

@ -231,8 +231,27 @@
if (queueContainer) { if (queueContainer) {
queueContainer.render(); queueContainer.render();
} }
updateQueueDuration();
}; };
function updateQueueDuration() {
const el = M.$("#queue-duration");
if (!el) return;
const totalSecs = M.queue.reduce((sum, t) => sum + (t.duration || 0), 0);
if (totalSecs === 0) {
el.textContent = "";
return;
}
const hours = Math.floor(totalSecs / 3600);
const mins = Math.floor((totalSecs % 3600) / 60);
const secs = Math.floor(totalSecs % 60);
let text = "";
if (hours > 0) text = `${hours}h ${mins}m`;
else if (mins > 0) text = `${mins}m ${secs}s`;
else text = `${secs}s`;
el.textContent = `(${M.queue.length} tracks · ${text})`;
}
M.renderLibrary = function() { M.renderLibrary = function() {
initContainers(); initContainers();
if (libraryContainer) { if (libraryContainer) {

View File

@ -129,6 +129,7 @@ h3 { font-size: 0.8rem; color: #666; margin-bottom: 0.3rem; text-transform: uppe
.upload-dropzone.hidden { display: none; } .upload-dropzone.hidden { display: none; }
.dropzone-content { color: #4e8; font-size: 1.2rem; font-weight: 600; } .dropzone-content { color: #4e8; font-size: 1.2rem; font-weight: 600; }
#queue-title { margin: 0 0 0.3rem 0; } #queue-title { margin: 0 0 0.3rem 0; }
#queue-duration { font-size: 0.75rem; color: #888; font-weight: normal; }
.now-playing-bar { font-size: 0.75rem; color: #4e8; padding: 0.3rem 0.5rem; background: #1a2a1a; border: 1px solid #2a4a3a; border-radius: 4px; margin-bottom: 0.3rem; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .now-playing-bar { font-size: 0.75rem; color: #4e8; padding: 0.3rem 0.5rem; background: #1a2a1a; border: 1px solid #2a4a3a; border-radius: 4px; margin-bottom: 0.3rem; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.now-playing-bar:hover { background: #2a3a2a; } .now-playing-bar:hover { background: #2a3a2a; }
.now-playing-bar.hidden { display: none; } .now-playing-bar.hidden { display: none; }

View File

@ -261,16 +261,19 @@
const trackId = track.id || track.filename; const trackId = track.id || track.filename;
const index = type === 'queue' ? originalIndex : filteredIndex; const index = type === 'queue' ? originalIndex : filteredIndex;
// Click - handle selection (Ctrl = toggle, Shift = range, plain = select only this) // Click/double-click handling - delay render to allow double-click detection
let clickTimeout = null;
div.onclick = (e) => { div.onclick = (e) => {
if (e.target.closest('.track-actions')) return; if (e.target.closest('.track-actions')) return;
toggleSelection(index, trackId, e.shiftKey, e.ctrlKey || e.metaKey); toggleSelection(index, trackId, e.shiftKey, e.ctrlKey || e.metaKey);
render(); clearTimeout(clickTimeout);
clickTimeout = setTimeout(() => render(), 200);
}; };
// Double-click - queue: jump to track, library/playlist: add to queue // Double-click - queue: jump to track, library/playlist: add to queue
div.ondblclick = (e) => { div.ondblclick = (e) => {
if (e.target.closest('.track-actions')) return; if (e.target.closest('.track-actions')) return;
clearTimeout(clickTimeout);
if (type === 'queue') { if (type === 'queue') {
M.jumpToTrack(originalIndex); M.jumpToTrack(originalIndex);
} else { } else {