fix(qconnect): route shuffle and repeat through runtime

cx
This commit is contained in:
vicrodh committed 2026-03-13 20:28:11 -06:00
1 parent 2efa1b0809
commit 09c6d8f1f8
7 files changed
+284 -3

No files matched your search

+95
View File
@@ -590,6 +590,47 @@ impl QueueManager {
}
}
/// Set shuffle mode using an authoritative order produced elsewhere.
/// Used by QConnect so the local queue follows the remote session order
/// instead of generating a second independent shuffle.
pub fn set_shuffle_with_order(&self, enabled: bool, shuffle_order: Option<Vec<usize>>) {
let mut state = self.state.lock().unwrap();
state.shuffle = enabled;
if !enabled {
state.shuffle_order.clear();
state.shuffle_position = 0;
return;
}
if let Some(order) =
shuffle_order.filter(|order| Self::is_valid_shuffle_order(order, state.tracks.len()))
{
state.shuffle_order = order;
if let Some(curr_idx) = state.current_index {
if let Some(pos) = state.shuffle_order.iter().position(|&idx| idx == curr_idx) {
state.shuffle_position = pos;
} else {
state.shuffle_position = 0;
}
} else {
state.shuffle_position = 0;
}
return;
}
Self::regenerate_shuffle_order_internal(&mut state);
if let Some(curr_idx) = state.current_index {
if let Some(pos) = state.shuffle_order.iter().position(|&idx| idx == curr_idx) {
if pos != 0 {
state.shuffle_order.swap(0, pos);
}
state.shuffle_position = 0;
}
}
}
/// Get shuffle status
pub fn is_shuffle(&self) -> bool {
self.state.lock().unwrap().shuffle
@@ -752,6 +793,22 @@ impl QueueManager {
state.shuffle_position = 0;
}
}
fn is_valid_shuffle_order(order: &[usize], track_count: usize) -> bool {
if order.len() != track_count {
return false;
}
let mut seen = vec![false; track_count];
for &idx in order {
if idx >= track_count || seen[idx] {
return false;
}
seen[idx] = true;
}
true
}
}
#[cfg(test)]
@@ -1001,4 +1058,42 @@ mod tests {
assert_eq!(state.total_tracks, 11);
assert_eq!(state.upcoming.len(), 10);
}
#[test]
fn test_set_shuffle_with_order_uses_authoritative_order() {
let queue = QueueManager::new();
for i in 1..=5 {
queue.add_track(create_test_track(i));
}
queue.play_index(2);
queue.set_shuffle_with_order(true, Some(vec![2, 4, 1, 3, 0]));
let state = queue.get_state();
assert!(state.shuffle);
assert_eq!(
state
.upcoming
.iter()
.map(|track| track.id)
.collect::<Vec<_>>(),
vec![5, 2, 4, 1]
);
}
#[test]
fn test_set_shuffle_with_order_falls_back_when_order_is_invalid() {
let queue = QueueManager::new();
for i in 1..=4 {
queue.add_track(create_test_track(i));
}
queue.play_index(1);
queue.set_shuffle_with_order(true, Some(vec![1, 1, 2, 3]));
let state = queue.state.lock().unwrap();
assert!(state.shuffle);
assert_eq!(state.shuffle_order.len(), 4);
assert_eq!(state.shuffle_order[0], 1);
}
}