diff --git a/src/spirc.rs b/src/spirc.rs index f8bd53a8..beb678f2 100644 --- a/src/spirc.rs +++ b/src/spirc.rs @@ -514,35 +514,66 @@ impl SpircTask { } } + fn consume_queue(&mut self) -> bool { + let current_index = self.state.get_playing_track_index() as usize; + if self.state.get_track()[current_index].get_queued() { + self.state.mut_track().remove(current_index); + return true + } + false + } + fn handle_next(&mut self) { let current_index = self.state.get_playing_track_index(); - let num_tracks = self.state.get_track().len() as u32; - let new_index = (current_index + 1) % num_tracks; - - let mut was_last_track = (current_index + 1) >= num_tracks; - if self.state.get_repeat() { - was_last_track = false; + let mut new_index = if self.consume_queue() { + current_index + } else { + current_index + 1 + }; + let mut continue_playing = true; + if new_index >= self.state.get_track().len() as u32 { + new_index = 0; // Loop around back to start + continue_playing = self.state.get_repeat(); } - self.state.set_playing_track_index(new_index); self.state.set_position_ms(0); self.state.set_position_measured_at(now_ms() as u64); - self.load_track(!was_last_track); + self.load_track(continue_playing); } fn handle_prev(&mut self) { // Previous behaves differently based on the position - // Under 3s it goes to the previous song - // Over 3s it seeks to zero + // Under 3s it goes to the previous song (starts playing) + // Over 3s it seeks to zero (retains previous play status) if self.position() < 3000 { - let current_index = self.state.get_playing_track_index(); - - let new_index = if current_index == 0 { - self.state.get_track().len() as u32 - 1 - } else { + let current_index = self.state.get_playing_track_index() as usize; + let mut q_tracks = Vec::new(); + { + // Extract any queued tracks. + let q_index = if self.consume_queue() { + current_index + } else { + current_index + 1 + }; + let tracks = self.state.mut_track(); + while q_index < tracks.len() && tracks[q_index].get_queued() { + q_tracks.push(tracks.remove(q_index)); + } + } + let new_index = if current_index > 0 { current_index - 1 - }; + } else if self.state.get_repeat() { + self.state.get_track().len() - 1 + } else { + 0 + } as u32; + // Reposition queued tracks to be next. + let mut pos = (new_index + 1) as usize; + for track in q_tracks.into_iter() { + self.state.mut_track().insert(pos, track); + pos += 1; + } self.state.set_playing_track_index(new_index); self.state.set_position_ms(0);