Unify pagination setup for ApiResult values

Also:
- Fix duplicate results
- Rename `album.load_tracks` to `album.load_all_tracks`
This commit is contained in:
Henrik Friedrichsen
2021-04-08 17:46:50 +02:00
parent 0f8e4d0558
commit 577e7ebd87
7 changed files with 26 additions and 34 deletions

View File

@@ -27,7 +27,7 @@ pub struct Album {
} }
impl Album { impl Album {
pub fn load_tracks(&mut self, spotify: Spotify) { pub fn load_all_tracks(&mut self, spotify: Spotify) {
if self.tracks.is_some() { if self.tracks.is_some() {
return; return;
} }
@@ -176,7 +176,7 @@ impl ListItem for Album {
} }
fn play(&mut self, queue: Arc<Queue>) { fn play(&mut self, queue: Arc<Queue>) {
self.load_tracks(queue.get_spotify()); self.load_all_tracks(queue.get_spotify());
if let Some(tracks) = self.tracks.as_ref() { if let Some(tracks) = self.tracks.as_ref() {
let tracks: Vec<Playable> = tracks let tracks: Vec<Playable> = tracks
@@ -189,7 +189,7 @@ impl ListItem for Album {
} }
fn play_next(&mut self, queue: Arc<Queue>) { fn play_next(&mut self, queue: Arc<Queue>) {
self.load_tracks(queue.get_spotify()); self.load_all_tracks(queue.get_spotify());
if let Some(tracks) = self.tracks.as_ref() { if let Some(tracks) = self.tracks.as_ref() {
for t in tracks.iter().rev() { for t in tracks.iter().rev() {
@@ -199,7 +199,7 @@ impl ListItem for Album {
} }
fn queue(&mut self, queue: Arc<Queue>) { fn queue(&mut self, queue: Arc<Queue>) {
self.load_tracks(queue.get_spotify()); self.load_all_tracks(queue.get_spotify());
if let Some(tracks) = self.tracks.as_ref() { if let Some(tracks) = self.tracks.as_ref() {
for t in tracks { for t in tracks {

View File

@@ -618,7 +618,7 @@ impl Library {
} }
} }
album.load_tracks(self.spotify.clone()); album.load_all_tracks(self.spotify.clone());
{ {
let mut store = self.albums.write().unwrap(); let mut store = self.albums.write().unwrap();
@@ -649,7 +649,7 @@ impl Library {
} }
} }
album.load_tracks(self.spotify.clone()); album.load_all_tracks(self.spotify.clone());
{ {
let mut store = self.albums.write().unwrap(); let mut store = self.albums.write().unwrap();

View File

@@ -22,7 +22,7 @@ impl AlbumView {
pub fn new(queue: Arc<Queue>, library: Arc<Library>, album: &Album) -> Self { pub fn new(queue: Arc<Queue>, library: Arc<Library>, album: &Album) -> Self {
let mut album = album.clone(); let mut album = album.clone();
album.load_tracks(queue.get_spotify()); album.load_all_tracks(queue.get_spotify());
let tracks = if let Some(t) = album.tracks.as_ref() { let tracks = if let Some(t) = album.tracks.as_ref() {
t.clone() t.clone()

View File

@@ -107,20 +107,9 @@ impl ArtistView {
if let Some(artist_id) = &artist.id { if let Some(artist_id) = &artist.id {
let spotify = queue.get_spotify(); let spotify = queue.get_spotify();
let albums_page = spotify.artist_albums(artist_id, Some(album_type)); let albums_page = spotify.artist_albums(artist_id, Some(album_type));
let view = ListView::new(albums_page.items.clone(), queue, library.clone()); let view = ListView::new(albums_page.items.clone(), queue, library);
let pagination = view.get_pagination().clone(); albums_page.apply_pagination(view.get_pagination());
pagination.set(
albums_page.total as usize,
Box::new(move |items| {
if let Some(next_page) = albums_page.next() {
let mut w = items.write().unwrap();
w.extend(next_page);
w.sort_by(|a, b| b.year.cmp(&a.year));
library.trigger_redraw();
}
}),
);
view view
} else { } else {
ListView::new(Arc::new(RwLock::new(Vec::new())), queue, library) ListView::new(Arc::new(RwLock::new(Vec::new())), queue, library)

View File

@@ -458,7 +458,7 @@ impl<I: ListItem + Clone> ViewExt for ListView<I> {
return Ok(CommandResult::Consumed(None)); return Ok(CommandResult::Consumed(None));
} }
MoveMode::Down if self.selected == last_idx && self.can_paginate() => { MoveMode::Down if self.selected == last_idx && self.can_paginate() => {
self.pagination.call(&self.content); self.pagination.call(&self.content, self.library.clone());
} }
_ => {} _ => {}
} }

View File

@@ -1,5 +1,6 @@
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use crate::library::Library;
use crate::traits::ListItem; use crate::traits::ListItem;
pub struct ApiPage<I> { pub struct ApiPage<I> {
@@ -16,7 +17,7 @@ pub struct ApiResult<I> {
fetch_page: Arc<FetchPageFn<I>>, fetch_page: Arc<FetchPageFn<I>>,
} }
impl<I: Clone> ApiResult<I> { impl<I: ListItem + Clone> ApiResult<I> {
pub fn new(limit: u32, fetch_page: Arc<FetchPageFn<I>>) -> ApiResult<I> { pub fn new(limit: u32, fetch_page: Arc<FetchPageFn<I>>) -> ApiResult<I> {
let items = Arc::new(RwLock::new(Vec::new())); let items = Arc::new(RwLock::new(Vec::new()));
if let Some(first_page) = fetch_page(0) { if let Some(first_page) = fetch_page(0) {
@@ -47,6 +48,16 @@ impl<I: Clone> ApiResult<I> {
(self.offset() + self.limit as u32) >= self.total (self.offset() + self.limit as u32) >= self.total
} }
pub fn apply_pagination(self, pagination: &Pagination<I>) {
let total = self.total as usize;
pagination.set(
total,
Box::new(move |_| {
self.next();
}),
)
}
pub fn next(&self) -> Option<Vec<I>> { pub fn next(&self) -> Option<Vec<I>> {
let offset = self.offset() + self.limit as u32; let offset = self.offset() + self.limit as u32;
debug!("fetching next page at offset {}", offset); debug!("fetching next page at offset {}", offset);
@@ -112,7 +123,7 @@ impl<I: ListItem> Pagination<I> {
*self.busy.read().unwrap() *self.busy.read().unwrap()
} }
pub fn call(&self, content: &Arc<RwLock<Vec<I>>>) { pub fn call(&self, content: &Arc<RwLock<Vec<I>>>, library: Arc<Library>) {
let pagination = self.clone(); let pagination = self.clone();
let content = content.clone(); let content = content.clone();
if !self.is_busy() { if !self.is_busy() {
@@ -123,6 +134,7 @@ impl<I: ListItem> Pagination<I> {
debug!("calling paginator!"); debug!("calling paginator!");
cb(content); cb(content);
*pagination.busy.write().unwrap() = false; *pagination.busy.write().unwrap() = false;
library.trigger_redraw();
} }
}); });
} }

View File

@@ -24,17 +24,8 @@ impl ShowView {
let list = { let list = {
let results = spotify.show_episodes(&show.id); let results = spotify.show_episodes(&show.id);
let view = ListView::new(results.items.clone(), queue, library.clone()); let view = ListView::new(results.items.clone(), queue, library);
let pagination = view.get_pagination(); results.apply_pagination(view.get_pagination());
pagination.set(
results.total as usize,
Box::new(move |_| {
if results.next().is_some() {
library.trigger_redraw();
}
}),
);
view view
}; };