From 3c054ed1ec22b1cf9f1dea5d0a2403e6407fbdfa Mon Sep 17 00:00:00 2001 From: salmon Date: Wed, 12 Aug 2026 02:17:02 +0200 Subject: queue logic fixes --- src/queue.rs | 53 ++++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/queue.rs b/src/queue.rs index 1f2f0fc..c3f8dbe 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -202,7 +202,6 @@ pub struct Queue { position: usize, shuffle: ShuffleMode, shuffled_indices: Vec, - original_tracks: Vec, } impl Default for Queue { @@ -218,7 +217,6 @@ impl Queue { position: 0, shuffle: ShuffleMode::None, shuffled_indices: Vec::new(), - original_tracks: Vec::new(), } } @@ -248,62 +246,59 @@ impl Queue { } pub fn set_shuffle(&mut self, mode: ShuffleMode) { - match mode { + self.shuffle = mode; + match self.shuffle { ShuffleMode::None => { - self.shuffle = ShuffleMode::None; self.restore_from_original(); } ShuffleMode::All => { - self.original_tracks = self.tracks.clone(); - self.shuffle = ShuffleMode::All; self.update_shuffle_indices(); } ShuffleMode::Album => { - self.original_tracks = self.tracks.clone(); - self.shuffle = ShuffleMode::Album; self.update_shuffle_indices_album(); } ShuffleMode::Albums => { - self.original_tracks = self.tracks.clone(); - self.shuffle = ShuffleMode::Albums; self.update_shuffle_indices_albums(); } } } fn restore_from_original(&mut self) { - if self.original_tracks.is_empty() { + // Restore linear (unshuffled) order. `tracks` is never reordered by + // shuffle — only `shuffled_indices` is a permutation — so the live + // list already carries the original insertion order. Keep the played + // segment (positions 0..=current in shuffled order) in the order it + // was played, then append the unplayed entries in original order. + // Entries are tracked by identity, so duplicate paths are preserved + // and entries added during shuffle survive. + if self.tracks.is_empty() { + self.position = 0; self.shuffled_indices.clear(); return; } - let current_pos = self.position; + let current_pos = self.position.min(self.tracks.len().saturating_sub(1)); - // Find which tracks have been played (positions 0..=current_pos in shuffled order) - let mut played_track_paths: Vec = Vec::new(); + // Played entries, in played order (positions 0..=current_pos in shuffled order). + let mut played: Vec = Vec::new(); + let mut played_idx: Vec = Vec::new(); for i in 0..=current_pos { - if let Some(&idx) = self.shuffled_indices.get(i) - && let Some(track) = self.tracks.get(idx) - { - played_track_paths.push(track.path.clone()); + if let Some(&idx) = self.shuffled_indices.get(i) { + if let Some(track) = self.tracks.get(idx) { + played.push(track.clone()); + played_idx.push(idx); + } } } - // Keep the played tracks in their current order - let mut new_tracks: Vec = Vec::new(); - for path in &played_track_paths { - if let Some(track) = self.tracks.iter().find(|t| &t.path == path) { + // Unplayed entries keep their original (insertion) order. + let mut new_tracks = played; + for (idx, track) in self.tracks.iter().enumerate() { + if !played_idx.contains(&idx) { new_tracks.push(track.clone()); } } - // Add remaining tracks from original in original order - for orig_track in &self.original_tracks { - let is_played = played_track_paths.iter().any(|p| p == &orig_track.path); - if !is_played { - new_tracks.push(orig_track.clone()); - } - } self.tracks = new_tracks; self.position = current_pos; self.shuffled_indices.clear(); -- cgit v1.2.3