Use new pagination interface for podcast episodes

This commit is contained in:
Henrik Friedrichsen
2021-04-08 16:49:19 +02:00
parent 53db188153
commit 0f8e4d0558
4 changed files with 52 additions and 37 deletions

View File

@@ -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();

View File

@@ -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()));

View File

@@ -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>> {

View File

@@ -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 }
}
}