Use new pagination interface for podcast episodes
This commit is contained in:
@@ -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();
|
||||
|
||||
31
src/show.rs
31
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<Queue>) {
|
||||
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<Queue>) {
|
||||
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<Queue>) {
|
||||
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()));
|
||||
|
||||
@@ -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<Page<SimplifiedEpisode>> {
|
||||
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<Episode> {
|
||||
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<Page<Show>> {
|
||||
|
||||
@@ -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<Queue>, library: Arc<Library>, 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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user