Refactor pagination code into separate file
This commit is contained in:
@@ -27,72 +27,9 @@ use crate::traits::{IntoBoxedViewExt, ListItem, ViewExt};
|
|||||||
use crate::ui::album::AlbumView;
|
use crate::ui::album::AlbumView;
|
||||||
use crate::ui::artist::ArtistView;
|
use crate::ui::artist::ArtistView;
|
||||||
use crate::ui::contextmenu::ContextMenu;
|
use crate::ui::contextmenu::ContextMenu;
|
||||||
|
use crate::ui::pagination::Pagination;
|
||||||
use crate::{album::Album, spotify::URIType, spotify_url::SpotifyURL};
|
use crate::{album::Album, spotify::URIType, spotify_url::SpotifyURL};
|
||||||
|
|
||||||
pub type Paginator<I> = Box<dyn Fn(Arc<RwLock<Vec<I>>>) + Send + Sync>;
|
|
||||||
|
|
||||||
pub struct Pagination<I: ListItem> {
|
|
||||||
max_content: Arc<RwLock<Option<usize>>>,
|
|
||||||
callback: Arc<RwLock<Option<Paginator<I>>>>,
|
|
||||||
busy: Arc<RwLock<bool>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: ListItem> Default for Pagination<I> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Pagination {
|
|
||||||
max_content: Arc::new(RwLock::new(None)),
|
|
||||||
callback: Arc::new(RwLock::new(None)),
|
|
||||||
busy: Arc::new(RwLock::new(false)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: figure out why deriving Clone doesn't work
|
|
||||||
impl<I: ListItem> Clone for Pagination<I> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Pagination {
|
|
||||||
max_content: self.max_content.clone(),
|
|
||||||
callback: self.callback.clone(),
|
|
||||||
busy: self.busy.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: ListItem> Pagination<I> {
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
*self.max_content.write().unwrap() = None;
|
|
||||||
*self.callback.write().unwrap() = None;
|
|
||||||
}
|
|
||||||
pub fn set(&mut self, max_content: usize, callback: Paginator<I>) {
|
|
||||||
*self.max_content.write().unwrap() = Some(max_content);
|
|
||||||
*self.callback.write().unwrap() = Some(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn max_content(&self) -> Option<usize> {
|
|
||||||
*self.max_content.read().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_busy(&self) -> bool {
|
|
||||||
*self.busy.read().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&self, content: &Arc<RwLock<Vec<I>>>) {
|
|
||||||
let pagination = self.clone();
|
|
||||||
let content = content.clone();
|
|
||||||
if !self.is_busy() {
|
|
||||||
*self.busy.write().unwrap() = true;
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
let cb = pagination.callback.read().unwrap();
|
|
||||||
if let Some(ref cb) = *cb {
|
|
||||||
debug!("calling paginator!");
|
|
||||||
cb(content);
|
|
||||||
*pagination.busy.write().unwrap() = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ListView<I: ListItem> {
|
pub struct ListView<I: ListItem> {
|
||||||
content: Arc<RwLock<Vec<I>>>,
|
content: Arc<RwLock<Vec<I>>>,
|
||||||
last_content_len: usize,
|
last_content_len: usize,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ pub mod layout;
|
|||||||
pub mod library;
|
pub mod library;
|
||||||
pub mod listview;
|
pub mod listview;
|
||||||
pub mod modal;
|
pub mod modal;
|
||||||
|
pub mod pagination;
|
||||||
pub mod playlist;
|
pub mod playlist;
|
||||||
pub mod playlists;
|
pub mod playlists;
|
||||||
pub mod queue;
|
pub mod queue;
|
||||||
|
|||||||
67
src/ui/pagination.rs
Normal file
67
src/ui/pagination.rs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
|
use crate::traits::ListItem;
|
||||||
|
|
||||||
|
pub type Paginator<I> = Box<dyn Fn(Arc<RwLock<Vec<I>>>) + Send + Sync>;
|
||||||
|
|
||||||
|
pub struct Pagination<I: ListItem> {
|
||||||
|
max_content: Arc<RwLock<Option<usize>>>,
|
||||||
|
callback: Arc<RwLock<Option<Paginator<I>>>>,
|
||||||
|
busy: Arc<RwLock<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: ListItem> Default for Pagination<I> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Pagination {
|
||||||
|
max_content: Arc::new(RwLock::new(None)),
|
||||||
|
callback: Arc::new(RwLock::new(None)),
|
||||||
|
busy: Arc::new(RwLock::new(false)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: figure out why deriving Clone doesn't work
|
||||||
|
impl<I: ListItem> Clone for Pagination<I> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Pagination {
|
||||||
|
max_content: self.max_content.clone(),
|
||||||
|
callback: self.callback.clone(),
|
||||||
|
busy: self.busy.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: ListItem> Pagination<I> {
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
*self.max_content.write().unwrap() = None;
|
||||||
|
*self.callback.write().unwrap() = None;
|
||||||
|
}
|
||||||
|
pub fn set(&mut self, max_content: usize, callback: Paginator<I>) {
|
||||||
|
*self.max_content.write().unwrap() = Some(max_content);
|
||||||
|
*self.callback.write().unwrap() = Some(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_content(&self) -> Option<usize> {
|
||||||
|
*self.max_content.read().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_busy(&self) -> bool {
|
||||||
|
*self.busy.read().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(&self, content: &Arc<RwLock<Vec<I>>>) {
|
||||||
|
let pagination = self.clone();
|
||||||
|
let content = content.clone();
|
||||||
|
if !self.is_busy() {
|
||||||
|
*self.busy.write().unwrap() = true;
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let cb = pagination.callback.read().unwrap();
|
||||||
|
if let Some(ref cb) = *cb {
|
||||||
|
debug!("calling paginator!");
|
||||||
|
cb(content);
|
||||||
|
*pagination.busy.write().unwrap() = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,8 @@ use crate::spotify::{Spotify, URIType};
|
|||||||
use crate::track::Track;
|
use crate::track::Track;
|
||||||
use crate::traits::{ListItem, ViewExt};
|
use crate::traits::{ListItem, ViewExt};
|
||||||
use crate::ui::layout::Layout;
|
use crate::ui::layout::Layout;
|
||||||
use crate::ui::listview::{ListView, Pagination};
|
use crate::ui::listview::ListView;
|
||||||
|
use crate::ui::pagination::Pagination;
|
||||||
use crate::ui::search_results::SearchResultsView;
|
use crate::ui::search_results::SearchResultsView;
|
||||||
use crate::ui::tabview::TabView;
|
use crate::ui::tabview::TabView;
|
||||||
use rspotify::model::search::SearchResult;
|
use rspotify::model::search::SearchResult;
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ use crate::spotify::{Spotify, URIType};
|
|||||||
use crate::spotify_url::SpotifyURL;
|
use crate::spotify_url::SpotifyURL;
|
||||||
use crate::track::Track;
|
use crate::track::Track;
|
||||||
use crate::traits::{ListItem, ViewExt};
|
use crate::traits::{ListItem, ViewExt};
|
||||||
use crate::ui::listview::{ListView, Pagination};
|
use crate::ui::listview::ListView;
|
||||||
|
use crate::ui::pagination::Pagination;
|
||||||
use crate::ui::tabview::TabView;
|
use crate::ui::tabview::TabView;
|
||||||
use cursive::view::ViewWrapper;
|
use cursive::view::ViewWrapper;
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
|
|||||||
Reference in New Issue
Block a user