diff --git a/src/mpris.rs b/src/mpris.rs index 56e90a2..aecacc6 100644 --- a/src/mpris.rs +++ b/src/mpris.rs @@ -578,9 +578,9 @@ fn run_dbus_server( } Some(UriType::Show) => { if let Some(s) = spotify.get_show(&id) { - let mut show = Show::from(&s); + let mut show: Show = (&s).into(); let spotify = spotify.clone(); - show.load_episodes(spotify); + show.load_all_episodes(spotify); if let Some(e) = &show.episodes { queue.clear(); let mut ep = e.clone(); diff --git a/src/show.rs b/src/show.rs index c47201c..3bf434d 100644 --- a/src/show.rs +++ b/src/show.rs @@ -21,31 +21,18 @@ pub struct Show { } impl Show { - pub fn load_episodes(&mut self, spotify: Spotify) { + pub fn load_all_episodes(&mut self, spotify: Spotify) { if self.episodes.is_some() { return; } - let mut collected_episodes = Vec::new(); - - let mut episodes_result = spotify.show_episodes(&self.id, 0); - while let Some(ref episodes) = episodes_result.clone() { - for item in &episodes.items { - collected_episodes.push(item.into()) - } - debug!("got {} episodes", episodes.items.len()); - - // load next batch if necessary - episodes_result = match episodes.next { - Some(_) => { - debug!("requesting episodes again.."); - spotify.show_episodes(&self.id, episodes.offset + episodes.items.len() as u32) - } - None => None, - } + let episodes_result = spotify.show_episodes(&self.id); + while !episodes_result.at_end() { + episodes_result.next(); } - self.episodes = Some(collected_episodes); + let episodes = episodes_result.items.read().unwrap().clone(); + self.episodes = Some(episodes); } } @@ -106,7 +93,7 @@ impl ListItem for Show { } fn play(&mut self, queue: Arc) { - self.load_episodes(queue.get_spotify()); + self.load_all_episodes(queue.get_spotify()); let playables = self .episodes @@ -121,7 +108,7 @@ impl ListItem for Show { } fn play_next(&mut self, queue: Arc) { - self.load_episodes(queue.get_spotify()); + self.load_all_episodes(queue.get_spotify()); if let Some(episodes) = self.episodes.as_ref() { for ep in episodes.iter().rev() { @@ -131,7 +118,7 @@ impl ListItem for Show { } fn queue(&mut self, queue: Arc) { - self.load_episodes(queue.get_spotify()); + self.load_all_episodes(queue.get_spotify()); for ep in self.episodes.as_ref().unwrap_or(&Vec::new()) { queue.append(Playable::Episode(ep.clone())); diff --git a/src/spotify.rs b/src/spotify.rs index b100c53..e8ba477 100644 --- a/src/spotify.rs +++ b/src/spotify.rs @@ -50,10 +50,11 @@ use crate::spotify_worker::{Worker, WorkerCommand}; use crate::track::Track; use crate::album::Album; +use crate::episode::Episode; use crate::playlist::Playlist; use crate::ui::pagination::{ApiPage, ApiResult}; use rspotify::model::recommend::Recommendations; -use rspotify::model::show::{FullEpisode, FullShow, Show, SimplifiedEpisode}; +use rspotify::model::show::{FullEpisode, FullShow, Show}; pub const VOLUME_PERCENT: u16 = ((u16::max_value() as f64) * 1.0 / 100.0) as u16; @@ -641,10 +642,25 @@ impl Spotify { ApiResult::new(MAX_SIZE, Arc::new(fetch_page)) } - pub fn show_episodes(&self, show_id: &str, offset: u32) -> Option> { - self.api_with_retry(|api| { - api.get_shows_episodes(show_id.to_string(), 50, offset, self.country) - }) + pub fn show_episodes(&self, show_id: &str) -> ApiResult { + const MAX_SIZE: u32 = 50; + let spotify = self.clone(); + let show_id = show_id.to_string(); + let fetch_page = move |offset: u32| { + debug!("fetching show {} episodes, offset: {}", &show_id, offset); + spotify.api_with_retry(|api| { + match api.get_shows_episodes(show_id.clone(), MAX_SIZE, offset, spotify.country) { + Ok(page) => Ok(ApiPage { + offset: page.offset, + total: page.total, + items: page.items.iter().map(|se| se.into()).collect(), + }), + Err(e) => Err(e), + } + }) + }; + + ApiResult::new(MAX_SIZE, Arc::new(fetch_page)) } pub fn get_saved_shows(&self, offset: u32) -> Option> { diff --git a/src/ui/show.rs b/src/ui/show.rs index cc985bd..b5938d4 100644 --- a/src/ui/show.rs +++ b/src/ui/show.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use cursive::view::ViewWrapper; use cursive::Cursive; @@ -19,15 +19,27 @@ pub struct ShowView { impl ShowView { pub fn new(queue: Arc, library: Arc, show: &Show) -> Self { - let mut show = show.clone(); - show.load_episodes(queue.get_spotify()); + let spotify = queue.get_spotify(); + let show = show.clone(); - let episodes = show.episodes.clone().unwrap_or_default(); + let list = { + let results = spotify.show_episodes(&show.id); + let view = ListView::new(results.items.clone(), queue, library.clone()); + let pagination = view.get_pagination(); - Self { - list: ListView::new(Arc::new(RwLock::new(episodes)), queue, library), - show, - } + pagination.set( + results.total as usize, + Box::new(move |_| { + if results.next().is_some() { + library.trigger_redraw(); + } + }), + ); + + view + }; + + Self { list, show } } }