From 03f4585424d05dd50022759c7ad098fe06277f6e Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 7 May 2026 16:16:01 +0200 Subject: Fix queue bugs: play -i on empty queue, stale track replay after queue ends, shuffle preserving current position - insert_after_current: guard against panic on empty queue - play -i (now): skip position increment when queue was empty so track plays - directory last: use audio.is_playing() instead of q.current() to avoid replaying finished track - shuffle: only randomize tracks after current position --- src/daemon.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'src/daemon.rs') diff --git a/src/daemon.rs b/src/daemon.rs index 3379c7b..9e02e3f 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -150,8 +150,12 @@ impl Queue { } fn insert_after_current(&mut self, path: PathBuf) { - let insert_idx = self.position + 1; - self.tracks.insert(insert_idx, Track::from_path(path)); + if self.tracks.is_empty() { + self.tracks.push(Track::from_path(path)); + } else { + let insert_idx = self.position + 1; + self.tracks.insert(insert_idx, Track::from_path(path)); + } self.update_shuffle_indices(); } @@ -165,11 +169,15 @@ impl Queue { } fn update_shuffle_indices(&mut self) { - self.shuffled_indices = (0..self.tracks.len()).collect(); + let len = self.tracks.len(); + self.shuffled_indices = (0..len).collect(); if let ShuffleMode::All = self.shuffle { use rand::seq::SliceRandom; let mut rng = rand::rng(); - self.shuffled_indices.shuffle(&mut rng); + let pos = self.position.min(len.saturating_sub(1)); + if pos + 1 < len { + self.shuffled_indices[pos + 1..].shuffle(&mut rng); + } } } @@ -583,10 +591,13 @@ fn process_command( let path = std::path::PathBuf::from(path_str.clone()); if path.is_file() { if let Ok(mut q) = queue.lock() { + let was_empty = q.tracks.is_empty(); match position { "now" => { q.insert_after_current(path.clone()); - q.position += 1; + if !was_empty { + q.position += 1; + } if let Some(track) = q.track_at(q.position) { audio.play(track.path.clone()); } @@ -609,12 +620,15 @@ fn process_command( match find_audio_in_dir(&path) { Some(files) if !files.is_empty() => { if let Ok(mut q) = queue.lock() { + let was_empty = q.tracks.is_empty(); match position { "now" => { for file in &files { q.insert_after_current(file.clone()); } - q.position += 1; + if !was_empty { + q.position += 1; + } if let Some(track) = q.track_at(q.position) { audio.play(track.path.clone()); } @@ -638,8 +652,10 @@ fn process_command( for file in &files { q.add_track(file.clone()); } - if let Some(track) = q.current() { - audio.play(track.path.clone()); + if !audio.is_playing() { + if let Some(track) = files.first() { + audio.play(track.clone()); + } } format!("Queued {} tracks from: {}\n", files.len(), path_str) } -- cgit v1.2.3