aboutsummaryrefslogtreecommitdiffstats
path: root/src/queue.rs
diff options
context:
space:
mode:
authorsalmon <salmonik@tuta.io>2026-08-12 02:17:02 +0200
committersalmon <salmonik@tuta.io>2026-08-12 02:17:02 +0200
commit3c054ed1ec22b1cf9f1dea5d0a2403e6407fbdfa (patch)
tree0bed861fa5f903a3644cda2e7c3293690fbf7bbe /src/queue.rs
parentrc service: create state dir and log before daemon(8) starts (diff)
downloadrsplayer-3c054ed1ec22b1cf9f1dea5d0a2403e6407fbdfa.tar.gz
rsplayer-3c054ed1ec22b1cf9f1dea5d0a2403e6407fbdfa.zip
queue logic fixes
Diffstat (limited to '')
-rw-r--r--src/queue.rs53
1 files changed, 24 insertions, 29 deletions
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 {
202 position: usize, 202 position: usize,
203 shuffle: ShuffleMode, 203 shuffle: ShuffleMode,
204 shuffled_indices: Vec<usize>, 204 shuffled_indices: Vec<usize>,
205 original_tracks: Vec<Track>,
206} 205}
207 206
208impl Default for Queue { 207impl Default for Queue {
@@ -218,7 +217,6 @@ impl Queue {
218 position: 0, 217 position: 0,
219 shuffle: ShuffleMode::None, 218 shuffle: ShuffleMode::None,
220 shuffled_indices: Vec::new(), 219 shuffled_indices: Vec::new(),
221 original_tracks: Vec::new(),
222 } 220 }
223 } 221 }
224 222
@@ -248,62 +246,59 @@ impl Queue {
248 } 246 }
249 247
250 pub fn set_shuffle(&mut self, mode: ShuffleMode) { 248 pub fn set_shuffle(&mut self, mode: ShuffleMode) {
251 match mode { 249 self.shuffle = mode;
250 match self.shuffle {
252 ShuffleMode::None => { 251 ShuffleMode::None => {
253 self.shuffle = ShuffleMode::None;
254 self.restore_from_original(); 252 self.restore_from_original();
255 } 253 }
256 ShuffleMode::All => { 254 ShuffleMode::All => {
257 self.original_tracks = self.tracks.clone();
258 self.shuffle = ShuffleMode::All;
259 self.update_shuffle_indices(); 255 self.update_shuffle_indices();
260 } 256 }
261 ShuffleMode::Album => { 257 ShuffleMode::Album => {
262 self.original_tracks = self.tracks.clone();
263 self.shuffle = ShuffleMode::Album;
264 self.update_shuffle_indices_album(); 258 self.update_shuffle_indices_album();
265 } 259 }
266 ShuffleMode::Albums => { 260 ShuffleMode::Albums => {
267 self.original_tracks = self.tracks.clone();
268 self.shuffle = ShuffleMode::Albums;
269 self.update_shuffle_indices_albums(); 261 self.update_shuffle_indices_albums();
270 } 262 }
271 } 263 }
272 } 264 }
273 265
274 fn restore_from_original(&mut self) { 266 fn restore_from_original(&mut self) {
275 if self.original_tracks.is_empty() { 267 // Restore linear (unshuffled) order. `tracks` is never reordered by
268 // shuffle — only `shuffled_indices` is a permutation — so the live
269 // list already carries the original insertion order. Keep the played
270 // segment (positions 0..=current in shuffled order) in the order it
271 // was played, then append the unplayed entries in original order.
272 // Entries are tracked by identity, so duplicate paths are preserved
273 // and entries added during shuffle survive.
274 if self.tracks.is_empty() {
275 self.position = 0;
276 self.shuffled_indices.clear(); 276 self.shuffled_indices.clear();
277 return; 277 return;
278 } 278 }
279 279
280 let current_pos = self.position; 280 let current_pos = self.position.min(self.tracks.len().saturating_sub(1));
281 281
282 // Find which tracks have been played (positions 0..=current_pos in shuffled order) 282 // Played entries, in played order (positions 0..=current_pos in shuffled order).
283 let mut played_track_paths: Vec<std::path::PathBuf> = Vec::new(); 283 let mut played: Vec<Track> = Vec::new();
284 let mut played_idx: Vec<usize> = Vec::new();
284 for i in 0..=current_pos { 285 for i in 0..=current_pos {
285 if let Some(&idx) = self.shuffled_indices.get(i) 286 if let Some(&idx) = self.shuffled_indices.get(i) {
286 && let Some(track) = self.tracks.get(idx) 287 if let Some(track) = self.tracks.get(idx) {
287 { 288 played.push(track.clone());
288 played_track_paths.push(track.path.clone()); 289 played_idx.push(idx);
290 }
289 } 291 }
290 } 292 }
291 293
292 // Keep the played tracks in their current order 294 // Unplayed entries keep their original (insertion) order.
293 let mut new_tracks: Vec<Track> = Vec::new(); 295 let mut new_tracks = played;
294 for path in &played_track_paths { 296 for (idx, track) in self.tracks.iter().enumerate() {
295 if let Some(track) = self.tracks.iter().find(|t| &t.path == path) { 297 if !played_idx.contains(&idx) {
296 new_tracks.push(track.clone()); 298 new_tracks.push(track.clone());
297 } 299 }
298 } 300 }
299 301
300 // Add remaining tracks from original in original order
301 for orig_track in &self.original_tracks {
302 let is_played = played_track_paths.iter().any(|p| p == &orig_track.path);
303 if !is_played {
304 new_tracks.push(orig_track.clone());
305 }
306 }
307 self.tracks = new_tracks; 302 self.tracks = new_tracks;
308 self.position = current_pos; 303 self.position = current_pos;
309 self.shuffled_indices.clear(); 304 self.shuffled_indices.clear();