aboutsummaryrefslogtreecommitdiffstats
path: root/src/queue.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/queue.rs130
1 files changed, 107 insertions, 23 deletions
diff --git a/src/queue.rs b/src/queue.rs
index b0acf5f..9d09fec 100644
--- a/src/queue.rs
+++ b/src/queue.rs
@@ -6,6 +6,7 @@ pub enum ShuffleMode {
6 None, 6 None,
7 All, 7 All,
8 Album, 8 Album,
9 Albums,
9} 10}
10 11
11#[derive(Debug, Default, Clone)] 12#[derive(Debug, Default, Clone)]
@@ -46,28 +47,8 @@ pub fn extract_metadata(path: &Path) -> Option<AudioMetadata> {
46 }; 47 };
47 48
48 { 49 {
49 let meta = probed.metadata(); 50 let mut meta = probed.metadata();
50 if let Some(rev) = meta.current() { 51 if let Some(rev) = meta.skip_to_latest() {
51 for tag in &rev.media.tags {
52 match &tag.std {
53 Some(StandardTag::TrackTitle(value)) => {
54 metadata.title = Some(value.to_string());
55 }
56 Some(StandardTag::Artist(value)) => {
57 metadata.artist = Some(value.to_string());
58 }
59 Some(StandardTag::Album(value)) => {
60 metadata.album = Some(value.to_string());
61 }
62 _ => {}
63 }
64 }
65 }
66 }
67
68 if metadata.title.is_none() && metadata.artist.is_none() && metadata.album.is_none() {
69 let meta = probed.metadata();
70 if let Some(rev) = meta.current() {
71 for tag in &rev.media.tags { 52 for tag in &rev.media.tags {
72 match &tag.std { 53 match &tag.std {
73 Some(StandardTag::TrackTitle(value)) => { 54 Some(StandardTag::TrackTitle(value)) => {
@@ -183,6 +164,12 @@ impl Queue {
183 self.update_shuffle_indices(); 164 self.update_shuffle_indices();
184 } 165 }
185 166
167 #[allow(dead_code)]
168 pub fn push_track(&mut self, track: Track) {
169 self.tracks.push(track);
170 self.update_shuffle_indices();
171 }
172
186 pub fn insert_after_current(&mut self, path: PathBuf) { 173 pub fn insert_after_current(&mut self, path: PathBuf) {
187 if self.tracks.is_empty() { 174 if self.tracks.is_empty() {
188 self.tracks.push(Track::from_path(path)); 175 self.tracks.push(Track::from_path(path));
@@ -213,6 +200,11 @@ impl Queue {
213 self.shuffle = ShuffleMode::Album; 200 self.shuffle = ShuffleMode::Album;
214 self.update_shuffle_indices_album(); 201 self.update_shuffle_indices_album();
215 } 202 }
203 ShuffleMode::Albums => {
204 self.original_tracks = self.tracks.clone();
205 self.shuffle = ShuffleMode::Albums;
206 self.update_shuffle_indices_albums();
207 }
216 } 208 }
217 } 209 }
218 210
@@ -268,6 +260,9 @@ impl Queue {
268 ShuffleMode::Album => { 260 ShuffleMode::Album => {
269 self.update_shuffle_indices_album(); 261 self.update_shuffle_indices_album();
270 } 262 }
263 ShuffleMode::Albums => {
264 self.update_shuffle_indices_albums();
265 }
271 ShuffleMode::None => {} 266 ShuffleMode::None => {}
272 } 267 }
273 } 268 }
@@ -285,6 +280,62 @@ impl Queue {
285 } 280 }
286 } 281 }
287 282
283 fn update_shuffle_indices_albums(&mut self) {
284 let len = self.tracks.len();
285 self.shuffled_indices = (0..len).collect();
286
287 if len <= 1 {
288 return;
289 }
290
291 let pos = self.position.min(len.saturating_sub(1));
292 if pos + 1 >= len {
293 return;
294 }
295
296 let range_start = pos + 1;
297 let mut rng = rand::rng();
298
299 // Build album groups within the range, shuffling tracks within each group
300 let mut groups: Vec<Vec<usize>> = Vec::new();
301 let mut current_group: Vec<usize> = Vec::new();
302 let mut current_album: Option<&str> = None;
303
304 for i in range_start..len {
305 let album = self.tracks.get(i).and_then(|t| t.album.as_deref());
306
307 if current_group.is_empty() {
308 current_group.push(i);
309 current_album = album;
310 } else if album != current_album {
311 // Shuffle tracks within this album group before adding it
312 if current_group.len() > 1 {
313 current_group.shuffle(&mut rng);
314 }
315 groups.push(std::mem::take(&mut current_group));
316 current_group.push(i);
317 current_album = album;
318 } else {
319 current_group.push(i);
320 }
321 }
322 if !current_group.is_empty() {
323 if current_group.len() > 1 {
324 current_group.shuffle(&mut rng);
325 }
326 groups.push(current_group);
327 }
328
329 // Shuffle the album group order
330 groups.shuffle(&mut rng);
331
332 let mut new_indices: Vec<usize> = self.shuffled_indices[..=pos].to_vec();
333 for group in &groups {
334 new_indices.extend(group);
335 }
336 self.shuffled_indices = new_indices;
337 }
338
288 fn shuffle_album_range(&mut self, range: std::ops::Range<usize>, rng: &mut impl rand::Rng) { 339 fn shuffle_album_range(&mut self, range: std::ops::Range<usize>, rng: &mut impl rand::Rng) {
289 if range.start >= range.end { 340 if range.start >= range.end {
290 return; 341 return;
@@ -327,7 +378,7 @@ impl Queue {
327 self.shuffled_indices 378 self.shuffled_indices
328 .get(self.position) 379 .get(self.position)
329 .and_then(|&idx| self.tracks.get(idx)) 380 .and_then(|&idx| self.tracks.get(idx))
330 } else if self.shuffle == ShuffleMode::Album { 381 } else if self.shuffle == ShuffleMode::Album || self.shuffle == ShuffleMode::Albums {
331 self.shuffled_indices 382 self.shuffled_indices
332 .get(self.position) 383 .get(self.position)
333 .and_then(|&idx| self.tracks.get(idx)) 384 .and_then(|&idx| self.tracks.get(idx))
@@ -397,6 +448,39 @@ impl Queue {
397 ShuffleMode::Album => { 448 ShuffleMode::Album => {
398 self.shuffle_album_range(0..self.tracks.len(), &mut rng); 449 self.shuffle_album_range(0..self.tracks.len(), &mut rng);
399 } 450 }
451 ShuffleMode::Albums => {
452 let mut groups: Vec<Vec<usize>> = Vec::new();
453 let mut current_group: Vec<usize> = Vec::new();
454 let mut current_album: Option<&str> = None;
455
456 for i in 0..self.tracks.len() {
457 let album = self.tracks.get(i).and_then(|t| t.album.as_deref());
458
459 if current_group.is_empty() {
460 current_group.push(i);
461 current_album = album;
462 } else if album != current_album {
463 if current_group.len() > 1 {
464 current_group.shuffle(&mut rng);
465 }
466 groups.push(std::mem::take(&mut current_group));
467 current_group.push(i);
468 current_album = album;
469 } else {
470 current_group.push(i);
471 }
472 }
473 if !current_group.is_empty() {
474 if current_group.len() > 1 {
475 current_group.shuffle(&mut rng);
476 }
477 groups.push(current_group);
478 }
479
480 groups.shuffle(&mut rng);
481
482 self.shuffled_indices = groups.concat();
483 }
400 ShuffleMode::None => {} 484 ShuffleMode::None => {}
401 } 485 }
402 } 486 }