fix for queue list closing when modified
This commit is contained in:
parent
c33ef02dca
commit
698c6abd15
2 changed files with 110 additions and 93 deletions
|
|
@ -44,6 +44,19 @@ export class SidePanelManager {
|
||||||
return this.currentView === view && this.panel.classList.contains('active');
|
return this.currentView === view && this.panel.classList.contains('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refresh(view, renderControlsCallback, renderContentCallback) {
|
||||||
|
if (this.isActive(view)) {
|
||||||
|
if (renderControlsCallback) {
|
||||||
|
this.controlsElement.innerHTML = '';
|
||||||
|
renderControlsCallback(this.controlsElement);
|
||||||
|
}
|
||||||
|
if (renderContentCallback) {
|
||||||
|
this.contentElement.innerHTML = '';
|
||||||
|
renderContentCallback(this.contentElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateContent(view, renderContentCallback) {
|
updateContent(view, renderContentCallback) {
|
||||||
if (this.isActive(view)) {
|
if (this.isActive(view)) {
|
||||||
this.contentElement.innerHTML = '';
|
this.contentElement.innerHTML = '';
|
||||||
|
|
|
||||||
|
|
@ -30,111 +30,115 @@ export function initializeUIInteractions(player, api) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Queue panel
|
// Queue panel
|
||||||
const openQueuePanel = () => {
|
const renderQueueControls = (container) => {
|
||||||
const renderControls = (container) => {
|
const currentQueue = player.getCurrentQueue();
|
||||||
const currentQueue = player.getCurrentQueue();
|
const showClearBtn = currentQueue.length > 0;
|
||||||
const showClearBtn = currentQueue.length > 0;
|
|
||||||
|
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
<button id="clear-queue-btn" class="btn-icon" title="Clear Queue" style="display: ${showClearBtn ? 'flex' : 'none'}">
|
<button id="clear-queue-btn" class="btn-icon" title="Clear Queue" style="display: ${showClearBtn ? 'flex' : 'none'}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>
|
||||||
</button>
|
</button>
|
||||||
<button id="close-side-panel-btn" class="btn-icon" title="Close">
|
<button id="close-side-panel-btn" class="btn-icon" title="Close">
|
||||||
${SVG_CLOSE}
|
${SVG_CLOSE}
|
||||||
</button>
|
</button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
container.querySelector('#close-side-panel-btn').addEventListener('click', () => {
|
container.querySelector('#close-side-panel-btn').addEventListener('click', () => {
|
||||||
sidePanelManager.close();
|
sidePanelManager.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
const clearBtn = container.querySelector('#clear-queue-btn');
|
||||||
|
if (clearBtn) {
|
||||||
|
clearBtn.addEventListener('click', () => {
|
||||||
|
player.clearQueue();
|
||||||
|
refreshQueuePanel();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const clearBtn = container.querySelector('#clear-queue-btn');
|
const renderQueueContent = (container) => {
|
||||||
if (clearBtn) {
|
const currentQueue = player.getCurrentQueue();
|
||||||
clearBtn.addEventListener('click', () => {
|
|
||||||
player.clearQueue();
|
|
||||||
openQueuePanel(); // Re-render to update state
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderContent = (container) => {
|
if (currentQueue.length === 0) {
|
||||||
const currentQueue = player.getCurrentQueue();
|
container.innerHTML = '<div class="placeholder-text">Queue is empty.</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentQueue.length === 0) {
|
const html = currentQueue.map((track, index) => {
|
||||||
container.innerHTML = '<div class="placeholder-text">Queue is empty.</div>';
|
const isPlaying = index === player.currentQueueIndex;
|
||||||
return;
|
const trackTitle = getTrackTitle(track);
|
||||||
}
|
const trackArtists = getTrackArtists(track, { fallback: "Unknown" });
|
||||||
|
|
||||||
const html = currentQueue.map((track, index) => {
|
return `
|
||||||
const isPlaying = index === player.currentQueueIndex;
|
<div class="queue-track-item ${isPlaying ? 'playing' : ''}" data-queue-index="${index}" data-track-id="${track.id}" draggable="true">
|
||||||
const trackTitle = getTrackTitle(track);
|
<div class="drag-handle">
|
||||||
const trackArtists = getTrackArtists(track, { fallback: "Unknown" });
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<line x1="5" y1="8" x2="19" y2="8"></line>
|
||||||
return `
|
<line x1="5" y1="16" x2="19" y2="16"></line>
|
||||||
<div class="queue-track-item ${isPlaying ? 'playing' : ''}" data-queue-index="${index}" data-track-id="${track.id}" draggable="true">
|
</svg>
|
||||||
<div class="drag-handle">
|
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
||||||
<line x1="5" y1="8" x2="19" y2="8"></line>
|
|
||||||
<line x1="5" y1="16" x2="19" y2="16"></line>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="track-item-info">
|
|
||||||
<img src="${api.getCoverUrl(track.album?.cover, '80')}"
|
|
||||||
class="track-item-cover" loading="lazy">
|
|
||||||
<div class="track-item-details">
|
|
||||||
<div class="title">${trackTitle}</div>
|
|
||||||
<div class="artist">${trackArtists}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="track-item-duration">${formatTime(track.duration)}</div>
|
|
||||||
<button class="queue-remove-btn" data-track-index="${index}" title="Remove from queue">
|
|
||||||
${SVG_BIN}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
<div class="track-item-info">
|
||||||
}).join('');
|
<img src="${api.getCoverUrl(track.album?.cover, '80')}"
|
||||||
|
class="track-item-cover" loading="lazy">
|
||||||
|
<div class="track-item-details">
|
||||||
|
<div class="title">${trackTitle}</div>
|
||||||
|
<div class="artist">${trackArtists}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="track-item-duration">${formatTime(track.duration)}</div>
|
||||||
|
<button class="queue-remove-btn" data-track-index="${index}" title="Remove from queue">
|
||||||
|
${SVG_BIN}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
|
|
||||||
container.querySelectorAll('.queue-track-item').forEach((item) => {
|
container.querySelectorAll('.queue-track-item').forEach((item) => {
|
||||||
const index = parseInt(item.dataset.queueIndex);
|
const index = parseInt(item.dataset.queueIndex);
|
||||||
|
|
||||||
item.addEventListener('click', (e) => {
|
item.addEventListener('click', (e) => {
|
||||||
const removeBtn = e.target.closest('.queue-remove-btn');
|
const removeBtn = e.target.closest('.queue-remove-btn');
|
||||||
if (removeBtn) {
|
if (removeBtn) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
player.removeFromQueue(index);
|
player.removeFromQueue(index);
|
||||||
openQueuePanel(); // Re-render
|
refreshQueuePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.playAtIndex(index);
|
player.playAtIndex(index);
|
||||||
openQueuePanel(); // Re-render to update playing state
|
refreshQueuePanel();
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener('dragstart', (e) => {
|
|
||||||
draggedQueueIndex = index;
|
|
||||||
item.style.opacity = '0.5';
|
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener('dragend', () => {
|
|
||||||
item.style.opacity = '1';
|
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener('dragover', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener('drop', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (draggedQueueIndex !== null && draggedQueueIndex !== index) {
|
|
||||||
player.moveInQueue(draggedQueueIndex, index);
|
|
||||||
openQueuePanel(); // Re-render
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
sidePanelManager.open('queue', 'Queue', renderControls, renderContent);
|
item.addEventListener('dragstart', (e) => {
|
||||||
|
draggedQueueIndex = index;
|
||||||
|
item.style.opacity = '0.5';
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addEventListener('dragend', () => {
|
||||||
|
item.style.opacity = '1';
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addEventListener('dragover', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addEventListener('drop', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (draggedQueueIndex !== null && draggedQueueIndex !== index) {
|
||||||
|
player.moveInQueue(draggedQueueIndex, index);
|
||||||
|
refreshQueuePanel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshQueuePanel = () => {
|
||||||
|
sidePanelManager.refresh('queue', renderQueueControls, renderQueueContent);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openQueuePanel = () => {
|
||||||
|
sidePanelManager.open('queue', 'Queue', renderQueueControls, renderQueueContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
queueBtn.addEventListener('click', openQueuePanel);
|
queueBtn.addEventListener('click', openQueuePanel);
|
||||||
|
|
@ -142,7 +146,7 @@ export function initializeUIInteractions(player, api) {
|
||||||
// Expose renderQueue for external updates (e.g. shuffle, add to queue)
|
// Expose renderQueue for external updates (e.g. shuffle, add to queue)
|
||||||
window.renderQueueFunction = () => {
|
window.renderQueueFunction = () => {
|
||||||
if (sidePanelManager.isActive('queue')) {
|
if (sidePanelManager.isActive('queue')) {
|
||||||
openQueuePanel(); // Re-open acts as update if active
|
refreshQueuePanel();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue