cargo fmt
This commit is contained in:
@@ -20,7 +20,7 @@ pub struct Album {
|
|||||||
pub cover_url: Option<String>,
|
pub cover_url: Option<String>,
|
||||||
pub url: String,
|
pub url: String,
|
||||||
pub tracks: Option<Vec<Track>>,
|
pub tracks: Option<Vec<Track>>,
|
||||||
pub added_at: Option<DateTime<Utc>>
|
pub added_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Album {
|
impl Album {
|
||||||
|
|||||||
112
src/library.rs
112
src/library.rs
@@ -53,25 +53,30 @@ impl Library {
|
|||||||
let t_tracks = {
|
let t_tracks = {
|
||||||
let library = library.clone();
|
let library = library.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
library.load_cache(config::cache_path(CACHE_TRACKS), library.tracks.clone());
|
library
|
||||||
|
.load_cache(config::cache_path(CACHE_TRACKS), library.tracks.clone());
|
||||||
library.fetch_tracks();
|
library.fetch_tracks();
|
||||||
library.save_cache(config::cache_path(CACHE_TRACKS), library.tracks.clone());
|
library
|
||||||
|
.save_cache(config::cache_path(CACHE_TRACKS), library.tracks.clone());
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let t_albums = {
|
let t_albums = {
|
||||||
let library = library.clone();
|
let library = library.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
library.load_cache(config::cache_path(CACHE_ALBUMS), library.albums.clone());
|
library
|
||||||
|
.load_cache(config::cache_path(CACHE_ALBUMS), library.albums.clone());
|
||||||
library.fetch_albums();
|
library.fetch_albums();
|
||||||
library.save_cache(config::cache_path(CACHE_ALBUMS), library.albums.clone());
|
library
|
||||||
|
.save_cache(config::cache_path(CACHE_ALBUMS), library.albums.clone());
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let t_artists = {
|
let t_artists = {
|
||||||
let library = library.clone();
|
let library = library.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
library.load_cache(config::cache_path(CACHE_ARTISTS), library.artists.clone());
|
library
|
||||||
|
.load_cache(config::cache_path(CACHE_ARTISTS), library.artists.clone());
|
||||||
library.fetch_artists();
|
library.fetch_artists();
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -79,9 +84,15 @@ impl Library {
|
|||||||
let t_playlists = {
|
let t_playlists = {
|
||||||
let library = library.clone();
|
let library = library.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
library.load_cache(config::cache_path(CACHE_PLAYLISTS), library.playlists.clone());
|
library.load_cache(
|
||||||
|
config::cache_path(CACHE_PLAYLISTS),
|
||||||
|
library.playlists.clone(),
|
||||||
|
);
|
||||||
library.fetch_playlists();
|
library.fetch_playlists();
|
||||||
library.save_cache(config::cache_path(CACHE_PLAYLISTS), library.playlists.clone());
|
library.save_cache(
|
||||||
|
config::cache_path(CACHE_PLAYLISTS),
|
||||||
|
library.playlists.clone(),
|
||||||
|
);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,7 +125,11 @@ impl Library {
|
|||||||
let parsed: Result<Vec<T>, _> = serde_json::from_str(&contents);
|
let parsed: Result<Vec<T>, _> = serde_json::from_str(&contents);
|
||||||
match parsed {
|
match parsed {
|
||||||
Ok(cache) => {
|
Ok(cache) => {
|
||||||
debug!("cache from {} loaded ({} lists)", cache_path.display(), cache.len());
|
debug!(
|
||||||
|
"cache from {} loaded ({} lists)",
|
||||||
|
cache_path.display(),
|
||||||
|
cache.len()
|
||||||
|
);
|
||||||
let mut store = store.write().expect("can't writelock store");
|
let mut store = store.write().expect("can't writelock store");
|
||||||
store.clear();
|
store.clear();
|
||||||
store.extend(cache);
|
store.extend(cache);
|
||||||
@@ -196,7 +211,12 @@ impl Library {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn needs_download(&self, remote: &SimplifiedPlaylist) -> bool {
|
fn needs_download(&self, remote: &SimplifiedPlaylist) -> bool {
|
||||||
for local in self.playlists.read().expect("can't readlock playlists").iter() {
|
for local in self
|
||||||
|
.playlists
|
||||||
|
.read()
|
||||||
|
.expect("can't readlock playlists")
|
||||||
|
.iter()
|
||||||
|
{
|
||||||
if local.id == remote.id {
|
if local.id == remote.id {
|
||||||
return local.snapshot_id != remote.snapshot_id;
|
return local.snapshot_id != remote.snapshot_id;
|
||||||
}
|
}
|
||||||
@@ -382,8 +402,9 @@ impl Library {
|
|||||||
|
|
||||||
let store = self.albums.read().unwrap();
|
let store = self.albums.read().unwrap();
|
||||||
|
|
||||||
if page.total as usize == store.len() &&
|
if page.total as usize == store.len()
|
||||||
!page.items
|
&& !page
|
||||||
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.any(|(i, a)| &a.album.id != &store[i].id)
|
.any(|(i, a)| &a.album.id != &store[i].id)
|
||||||
@@ -425,8 +446,9 @@ impl Library {
|
|||||||
|
|
||||||
let store = self.tracks.read().unwrap();
|
let store = self.tracks.read().unwrap();
|
||||||
|
|
||||||
if page.total as usize == store.len() &&
|
if page.total as usize == store.len()
|
||||||
!page.items
|
&& !page
|
||||||
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.any(|(i, t)| &t.track.id != &store[i].id)
|
.any(|(i, t)| &t.track.id != &store[i].id)
|
||||||
@@ -449,11 +471,7 @@ impl Library {
|
|||||||
// Remove old unfollowed artists
|
// Remove old unfollowed artists
|
||||||
{
|
{
|
||||||
let mut artists = self.artists.write().unwrap();
|
let mut artists = self.artists.write().unwrap();
|
||||||
*artists = artists
|
*artists = artists.iter().filter(|a| a.is_followed).cloned().collect();
|
||||||
.iter()
|
|
||||||
.filter(|a| a.is_followed)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add artists that aren't followed but have saved tracks
|
// Add artists that aren't followed but have saved tracks
|
||||||
@@ -527,12 +545,11 @@ impl Library {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if api {
|
if api {
|
||||||
if self.spotify.current_user_saved_tracks_add(
|
if self
|
||||||
tracks
|
.spotify
|
||||||
.iter()
|
.current_user_saved_tracks_add(tracks.iter().map(|t| t.id.clone()).collect())
|
||||||
.map(|t| t.id.clone())
|
.is_none()
|
||||||
.collect()
|
{
|
||||||
).is_none() {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,12 +579,11 @@ impl Library {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if api {
|
if api {
|
||||||
if self.spotify.current_user_saved_tracks_delete(
|
if self
|
||||||
tracks
|
.spotify
|
||||||
.iter()
|
.current_user_saved_tracks_delete(tracks.iter().map(|t| t.id.clone()).collect())
|
||||||
.map(|t| t.id.clone())
|
.is_none()
|
||||||
.collect()
|
{
|
||||||
).is_none() {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,7 +617,11 @@ impl Library {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.spotify.current_user_saved_albums_add(vec![album.id.clone()]).is_none() {
|
if self
|
||||||
|
.spotify
|
||||||
|
.current_user_saved_albums_add(vec![album.id.clone()])
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +646,11 @@ impl Library {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.spotify.current_user_saved_albums_delete(vec![album.id.clone()]).is_none() {
|
if self
|
||||||
|
.spotify
|
||||||
|
.current_user_saved_albums_delete(vec![album.id.clone()])
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,11 +658,7 @@ impl Library {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut store = self.albums.write().unwrap();
|
let mut store = self.albums.write().unwrap();
|
||||||
*store = store
|
*store = store.iter().filter(|a| a.id != album.id).cloned().collect();
|
||||||
.iter()
|
|
||||||
.filter(|a| a.id != album.id)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tracks) = album.tracks.as_ref() {
|
if let Some(tracks) = album.tracks.as_ref() {
|
||||||
@@ -662,7 +682,11 @@ impl Library {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.spotify.user_follow_artists(vec![artist.id.clone()]).is_none() {
|
if self
|
||||||
|
.spotify
|
||||||
|
.user_follow_artists(vec![artist.id.clone()])
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +711,11 @@ impl Library {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.spotify.user_unfollow_artists(vec![artist.id.clone()]).is_none() {
|
if self
|
||||||
|
.spotify
|
||||||
|
.user_unfollow_artists(vec![artist.id.clone()])
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,7 +745,11 @@ impl Library {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.spotify.user_playlist_follow_playlist(playlist.owner_id.clone(), playlist.id.clone()).is_none() {
|
if self
|
||||||
|
.spotify
|
||||||
|
.user_playlist_follow_playlist(playlist.owner_id.clone(), playlist.id.clone())
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,11 @@ fn main() {
|
|||||||
#[cfg(feature = "mpris")]
|
#[cfg(feature = "mpris")]
|
||||||
let mpris_manager = Arc::new(mpris::MprisManager::new(spotify.clone(), queue.clone()));
|
let mpris_manager = Arc::new(mpris::MprisManager::new(spotify.clone(), queue.clone()));
|
||||||
|
|
||||||
let library = Arc::new(Library::new(&event_manager, spotify.clone(), cfg.use_nerdfont.unwrap_or(false)));
|
let library = Arc::new(Library::new(
|
||||||
|
&event_manager,
|
||||||
|
spotify.clone(),
|
||||||
|
cfg.use_nerdfont.unwrap_or(false),
|
||||||
|
));
|
||||||
|
|
||||||
let mut cmd_manager = CommandManager::new();
|
let mut cmd_manager = CommandManager::new();
|
||||||
cmd_manager.register_all(spotify.clone(), queue.clone(), library.clone());
|
cmd_manager.register_all(spotify.clone(), queue.clone(), library.clone());
|
||||||
@@ -172,7 +176,7 @@ fn main() {
|
|||||||
event_manager.clone(),
|
event_manager.clone(),
|
||||||
spotify.clone(),
|
spotify.clone(),
|
||||||
queue.clone(),
|
queue.clone(),
|
||||||
library.clone()
|
library.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let libraryview = ui::library::LibraryView::new(queue.clone(), library.clone());
|
let libraryview = ui::library::LibraryView::new(queue.clone(), library.clone());
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use queue::Queue;
|
|
||||||
use library::Library;
|
use library::Library;
|
||||||
|
use queue::Queue;
|
||||||
use track::Track;
|
use track::Track;
|
||||||
use traits::ListItem;
|
use traits::ListItem;
|
||||||
|
|
||||||
|
|||||||
@@ -527,7 +527,10 @@ impl Spotify {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_user_followed_artists(&self, last: Option<String>) -> Option<CursorBasedPage<FullArtist>> {
|
pub fn current_user_followed_artists(
|
||||||
|
&self,
|
||||||
|
last: Option<String>,
|
||||||
|
) -> Option<CursorBasedPage<FullArtist>> {
|
||||||
self.api_with_retry(|api| api.current_user_followed_artists(50, last.clone()))
|
self.api_with_retry(|api| api.current_user_followed_artists(50, last.clone()))
|
||||||
.map(|cp| cp.artists)
|
.map(|cp| cp.artists)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pub struct Track {
|
|||||||
pub album_artists: Vec<String>,
|
pub album_artists: Vec<String>,
|
||||||
pub cover_url: String,
|
pub cover_url: String,
|
||||||
pub url: String,
|
pub url: String,
|
||||||
pub added_at: Option<DateTime<Utc>>
|
pub added_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Track {
|
impl Track {
|
||||||
|
|||||||
@@ -18,14 +18,28 @@ pub struct LibraryView {
|
|||||||
impl LibraryView {
|
impl LibraryView {
|
||||||
pub fn new(queue: Arc<Queue>, library: Arc<Library>) -> Self {
|
pub fn new(queue: Arc<Queue>, library: Arc<Library>) -> Self {
|
||||||
let tabs = TabView::new()
|
let tabs = TabView::new()
|
||||||
.tab("tracks", "Tracks", ListView::new(library.tracks.clone(), queue.clone(), library.clone()))
|
.tab(
|
||||||
.tab("albums", "Albums", ListView::new(library.albums.clone(), queue.clone(), library.clone()))
|
"tracks",
|
||||||
.tab("artists", "Artists", ListView::new(library.artists.clone(), queue.clone(), library.clone()))
|
"Tracks",
|
||||||
.tab("playlists", "Playlists", PlaylistsView::new(queue.clone(), library.clone()));
|
ListView::new(library.tracks.clone(), queue.clone(), library.clone()),
|
||||||
|
)
|
||||||
|
.tab(
|
||||||
|
"albums",
|
||||||
|
"Albums",
|
||||||
|
ListView::new(library.albums.clone(), queue.clone(), library.clone()),
|
||||||
|
)
|
||||||
|
.tab(
|
||||||
|
"artists",
|
||||||
|
"Artists",
|
||||||
|
ListView::new(library.artists.clone(), queue.clone(), library.clone()),
|
||||||
|
)
|
||||||
|
.tab(
|
||||||
|
"playlists",
|
||||||
|
"Playlists",
|
||||||
|
PlaylistsView::new(queue.clone(), library.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self { tabs }
|
||||||
tabs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl SearchView {
|
|||||||
events: EventManager,
|
events: EventManager,
|
||||||
spotify: Arc<Spotify>,
|
spotify: Arc<Spotify>,
|
||||||
queue: Arc<Queue>,
|
queue: Arc<Queue>,
|
||||||
library: Arc<Library>
|
library: Arc<Library>,
|
||||||
) -> SearchView {
|
) -> SearchView {
|
||||||
let results_tracks = Arc::new(RwLock::new(Vec::new()));
|
let results_tracks = Arc::new(RwLock::new(Vec::new()));
|
||||||
let results_albums = Arc::new(RwLock::new(Vec::new()));
|
let results_albums = Arc::new(RwLock::new(Vec::new()));
|
||||||
@@ -72,7 +72,8 @@ impl SearchView {
|
|||||||
let pagination_albums = list_albums.get_pagination().clone();
|
let pagination_albums = list_albums.get_pagination().clone();
|
||||||
let list_artists = ListView::new(results_artists.clone(), queue.clone(), library.clone());
|
let list_artists = ListView::new(results_artists.clone(), queue.clone(), library.clone());
|
||||||
let pagination_artists = list_artists.get_pagination().clone();
|
let pagination_artists = list_artists.get_pagination().clone();
|
||||||
let list_playlists = ListView::new(results_playlists.clone(), queue.clone(), library.clone());
|
let list_playlists =
|
||||||
|
ListView::new(results_playlists.clone(), queue.clone(), library.clone());
|
||||||
let pagination_playlists = list_playlists.get_pagination().clone();
|
let pagination_playlists = list_playlists.get_pagination().clone();
|
||||||
|
|
||||||
let tabs = TabView::new()
|
let tabs = TabView::new()
|
||||||
|
|||||||
Reference in New Issue
Block a user