mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Improved next/prev handling for queued tracks.
1) A queued track is removed once it has become the current track. Note that the track doesn't need to actually play i.e. it could have been immediately skipped over with 'next()'. This is implemented in 'consume_queue()'. 2) Queued tracks are always positioned immediately after the current track. 1) ensures this is true for 'next()' but 'prev()' requires all the queued tracks are actually moved for this to remain the case. Also fixed the case where 'prev()' on the first track would incorrectly wrap back around to the last track even when repeat was disabled. The correct behaviour is to remain on the first track and just seek to the start. For example, with the following tracks and repeat enabled: TrackA, TrackB, TrackC-Q, TrackD-Q, TrackE ^^^^^^ Here, the result of 'prev' changes the current track from TrackB to TrackA and the queued tracks (TrackC, TrackD) move to the position immediately after TrackA: TrackA, TrackC-Q, TrackD-Q, TrackB, TrackE ^^^^^^ Calling 'prev' again results in the current track wrapping back around to TrackE and the queued tracks moving after that same track: TrackA, TrackB, TrackE, TrackC-Q, TrackD-Q ^^^^^^
This commit is contained in:
parent
977a6db3ef
commit
b9b8e110df
1 changed files with 47 additions and 16 deletions
63
src/spirc.rs
63
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);
|
||||
|
|
Loading…
Reference in a new issue