|
@@ -41,6 +41,7 @@ pub struct SpircTask {
|
|
|
shutdown: bool,
|
|
|
session: Session,
|
|
|
context_fut: Box<Future<Item = serde_json::Value, Error = MercuryError>>,
|
|
|
+ autoplay_fut: Box<Future<Item = String, Error = MercuryError>>,
|
|
|
context: Option<StationContext>,
|
|
|
}
|
|
|
|
|
@@ -268,6 +269,7 @@ impl Spirc {
|
|
|
session: session.clone(),
|
|
|
|
|
|
context_fut: Box::new(future::empty()),
|
|
|
+ autoplay_fut: Box::new(future::empty()),
|
|
|
context: None,
|
|
|
};
|
|
|
|
|
@@ -345,7 +347,7 @@ impl Future for SpircTask {
|
|
|
Ok(Async::NotReady) => (),
|
|
|
Err(oneshot::Canceled) => self.end_of_track = Box::new(future::empty()),
|
|
|
}
|
|
|
-
|
|
|
+ // TODO: Refactor
|
|
|
match self.context_fut.poll() {
|
|
|
Ok(Async::Ready(value)) => {
|
|
|
let r_context = serde_json::from_value::<StationContext>(value.clone());
|
|
@@ -378,6 +380,20 @@ impl Future for SpircTask {
|
|
|
error!("ContextError: {:?}", err)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ match self.autoplay_fut.poll() {
|
|
|
+ Ok(Async::Ready(autoplay_station_uri)) => {
|
|
|
+ info!("Autoplay resolved to <{:?}>", autoplay_station_uri);
|
|
|
+ self.context_fut = self.resolve_station(&autoplay_station_uri);
|
|
|
+ progress = true;
|
|
|
+ self.autoplay_fut = Box::new(future::empty());
|
|
|
+ }
|
|
|
+ Ok(Async::NotReady) => (),
|
|
|
+ Err(err) => {
|
|
|
+ self.autoplay_fut = Box::new(future::empty());
|
|
|
+ error!("AutoplayError: {:?}", err)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
let poll_sender = self.sender.poll_complete().unwrap();
|
|
@@ -657,12 +673,13 @@ impl SpircTask {
|
|
|
fn handle_next(&mut self) {
|
|
|
let mut new_index = self.consume_queued_track() as u32;
|
|
|
let mut continue_playing = true;
|
|
|
+ let tracks_len = self.state.get_track().len() as u32;
|
|
|
debug!(
|
|
|
"At track {:?} of {:?} <{:?}> update [{}]",
|
|
|
new_index,
|
|
|
self.state.get_track().len(),
|
|
|
self.state.get_context_uri(),
|
|
|
- self.state.get_track().len() as u32 - new_index < CONTEXT_FETCH_THRESHOLD
|
|
|
+ tracks_len - new_index < CONTEXT_FETCH_THRESHOLD
|
|
|
);
|
|
|
let context_uri = self.state.get_context_uri().to_owned();
|
|
|
if (context_uri.starts_with("spotify:station:") || context_uri.starts_with("spotify:dailymix:"))
|
|
@@ -671,8 +688,14 @@ impl SpircTask {
|
|
|
self.context_fut = self.resolve_station(&context_uri);
|
|
|
self.update_tracks_from_context();
|
|
|
}
|
|
|
-
|
|
|
- if new_index >= self.state.get_track().len() as u32 {
|
|
|
+ if new_index == tracks_len - 1 {
|
|
|
+ // Extend the playlist
|
|
|
+ // Note: This doesn't seem to reflect in the UI
|
|
|
+ // the additional tracks in the frame don't show up as with stations
|
|
|
+ info!("Extending playlist <{}>", context_uri);
|
|
|
+ self.update_tracks_from_context();
|
|
|
+ }
|
|
|
+ if new_index >= tracks_len {
|
|
|
new_index = 0; // Loop around back to start
|
|
|
continue_playing = self.state.get_repeat();
|
|
|
}
|
|
@@ -761,6 +784,17 @@ impl SpircTask {
|
|
|
self.resolve_uri(&radio_uri)
|
|
|
}
|
|
|
|
|
|
+ fn resolve_autoplay_uri(&self, uri: &str) -> Box<Future<Item = String, Error = MercuryError>> {
|
|
|
+ let query_uri = format!("hm://autoplay-enabled/query?uri={}", uri);
|
|
|
+ let request = self.session.mercury().get(query_uri);
|
|
|
+ Box::new(request.and_then(move |response| {
|
|
|
+ let data = response.payload.first().expect("Empty autoplay uri").to_vec();
|
|
|
+ let autoplay_uri = String::from_utf8(data).unwrap();
|
|
|
+
|
|
|
+ Ok(autoplay_uri)
|
|
|
+ }))
|
|
|
+ }
|
|
|
+
|
|
|
fn resolve_uri(&self, uri: &str) -> Box<Future<Item = serde_json::Value, Error = MercuryError>> {
|
|
|
let request = self.session.mercury().get(uri);
|
|
|
|
|
@@ -793,6 +827,8 @@ impl SpircTask {
|
|
|
{
|
|
|
self.state.set_playing_track_index(new_index);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ warn!("No context to update from!");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -804,6 +840,9 @@ impl SpircTask {
|
|
|
debug!("Frame has {:?} tracks", tracks.len());
|
|
|
if context_uri.starts_with("spotify:station:") || context_uri.starts_with("spotify:dailymix:") {
|
|
|
self.context_fut = self.resolve_station(&context_uri);
|
|
|
+ } else {
|
|
|
+ // Get autoplay_station_uri for regular playlists
|
|
|
+ self.autoplay_fut = self.resolve_autoplay_uri(&context_uri);
|
|
|
}
|
|
|
|
|
|
self.state.set_playing_track_index(index);
|