diff --git a/index.html b/index.html
index 9fd29ac..e8976ab 100644
--- a/index.html
+++ b/index.html
@@ -32,7 +32,10 @@
diff --git a/js/events.js b/js/events.js
index 6206fc6..9f0c5a5 100644
--- a/js/events.js
+++ b/js/events.js
@@ -250,9 +250,14 @@ function initializeSmoothSliders(audioPlayer, player) {
progressBar.addEventListener('click', e => {
if (!isSeeking) {
seek(progressBar, e, position => {
- if (!isNaN(audioPlayer.duration)) {
+ if (!isNaN(audioPlayer.duration) && audioPlayer.duration > 0 && audioPlayer.duration !== Infinity) {
audioPlayer.currentTime = position * audioPlayer.duration;
player.updateMediaSessionPositionState();
+ } else if (player.currentTrack && player.currentTrack.duration) {
+ const targetTime = position * player.currentTrack.duration;
+ const progressFill = document.querySelector('.progress-fill');
+ if (progressFill) progressFill.style.width = `${position * 100}%`;
+ player.playTrackFromQueue(targetTime);
}
});
}
@@ -310,7 +315,7 @@ export async function handleTrackAction(action, item, player, api, lyricsManager
// Update all instances of this item's like button on the page
const id = type === 'playlist' ? item.uuid : item.id;
const selector = type === 'track'
- ? `.track-item[data-track-id="${id}"] .like-btn`
+ ? `[data-track-id="${id}"] .like-btn`
: `.card[data-${type}-id="${id}"] .like-btn, .card[data-playlist-id="${id}"] .like-btn`;
// Also check header buttons
diff --git a/js/player.js b/js/player.js
index 932947b..7d41efe 100644
--- a/js/player.js
+++ b/js/player.js
@@ -52,6 +52,8 @@ export class Player {
if (coverEl) coverEl.src = this.api.getCoverUrl(track.album?.cover, '1280');
if (titleEl) titleEl.textContent = trackTitle;
if (artistEl) artistEl.textContent = trackArtists;
+ const totalDurationEl = document.getElementById('total-duration');
+ if (totalDurationEl) totalDurationEl.textContent = formatTime(track.duration);
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
this.updatePlayingTrackIndicator();
@@ -154,7 +156,7 @@ export class Player {
}
}
- async playTrackFromQueue() {
+ async playTrackFromQueue(startTime = 0) {
const currentQueue = this.shuffleActive ? this.shuffledQueue : this.queue;
if (this.currentQueueIndex < 0 || this.currentQueueIndex >= currentQueue.length) {
return;
@@ -193,6 +195,9 @@ export class Player {
}
this.audio.src = streamUrl;
+ if (startTime > 0) {
+ this.audio.currentTime = startTime;
+ }
await this.audio.play();
this.updateMediaSessionPlaybackState();
diff --git a/js/ui-interactions.js b/js/ui-interactions.js
index 82df0f5..fcc95fb 100644
--- a/js/ui-interactions.js
+++ b/js/ui-interactions.js
@@ -1,5 +1,5 @@
//js/ui-interactions.js
-import { SVG_CLOSE, formatTime, trackDataStore, getTrackTitle, getTrackArtists } from './utils.js';
+import { SVG_CLOSE, SVG_BIN, formatTime, trackDataStore, getTrackTitle, getTrackArtists } from './utils.js';
export function initializeUIInteractions(player, api) {
const sidebar = document.querySelector('.sidebar');
@@ -8,6 +8,7 @@ export function initializeUIInteractions(player, api) {
const queueBtn = document.getElementById('queue-btn');
const queueModalOverlay = document.getElementById('queue-modal-overlay');
const closeQueueBtn = document.getElementById('close-queue-btn');
+ const clearQueueBtn = document.getElementById('clear-queue-btn');
const queueList = document.getElementById('queue-list');
let draggedQueueIndex = null;
@@ -40,6 +41,13 @@ export function initializeUIInteractions(player, api) {
closeQueueBtn.addEventListener('click', () => {
queueModalOverlay.style.display = 'none';
});
+
+ if (clearQueueBtn) {
+ clearQueueBtn.addEventListener('click', () => {
+ player.clearQueue();
+ renderQueue();
+ });
+ }
queueModalOverlay.addEventListener('click', e => {
if (e.target === queueModalOverlay) {
@@ -50,6 +58,10 @@ export function initializeUIInteractions(player, api) {
function renderQueue() {
const currentQueue = player.getCurrentQueue();
+ if (clearQueueBtn) {
+ clearQueueBtn.style.display = currentQueue.length > 0 ? 'block' : 'none';
+ }
+
if (currentQueue.length === 0) {
queueList.innerHTML = 'Queue is empty.
';
return;
@@ -78,7 +90,7 @@ export function initializeUIInteractions(player, api) {
${formatTime(track.duration)}
`;
diff --git a/js/utils.js b/js/utils.js
index dbd77cc..b225985 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -34,6 +34,7 @@ export const SVG_DOWNLOAD = '