diff --git a/src/library.rs b/src/library.rs index 8914faf..8915602 100644 --- a/src/library.rs +++ b/src/library.rs @@ -236,7 +236,8 @@ impl Library { if self.needs_download(remote) { info!("updating playlist {}", remote.name); - let playlist = Playlist::from_simplified_playlist(remote, &self.spotify); + let mut playlist: Playlist = remote.into(); + playlist.load_tracks(self.spotify.clone()); self.append_or_update(&playlist); // trigger redraw self.ev.trigger(); @@ -723,6 +724,9 @@ impl Library { return; } + let mut playlist = playlist.clone(); + playlist.load_tracks(self.spotify.clone()); + { let mut store = self.playlists.write().unwrap(); if !store.iter().any(|p| p.id == playlist.id) { diff --git a/src/playlist.rs b/src/playlist.rs index a0c75b7..52e2bb7 100644 --- a/src/playlist.rs +++ b/src/playlist.rs @@ -16,40 +16,19 @@ pub struct Playlist { pub name: String, pub owner_id: String, pub snapshot_id: String, - pub tracks: Vec, + pub num_tracks: usize, + pub tracks: Option>, } impl Playlist { - pub fn from_simplified_playlist(list: &SimplifiedPlaylist, spotify: &Spotify) -> Playlist { - Self::_process_playlist( - list.id.clone(), - list.name.clone(), - list.owner.id.clone(), - list.snapshot_id.clone(), - spotify, - ) - } + pub fn load_tracks(&mut self, spotify: Arc) { + if self.tracks.is_some() { + return; + } - pub fn from_full_playlist(list: &FullPlaylist, spotify: &Spotify) -> Playlist { - Self::_process_playlist( - list.id.clone(), - list.name.clone(), - list.owner.id.clone(), - list.snapshot_id.clone(), - spotify, - ) - } - - fn _process_playlist( - id: String, - name: String, - owner_id: String, - snapshot_id: String, - spotify: &Spotify, - ) -> Playlist { let mut collected_tracks = Vec::new(); - let mut tracks_result = spotify.user_playlist_tracks(&id, 100, 0); + let mut tracks_result = spotify.user_playlist_tracks(&self.id, 100, 0); while let Some(ref tracks) = tracks_result.clone() { for listtrack in &tracks.items { collected_tracks.push((&listtrack.track).into()); @@ -61,7 +40,7 @@ impl Playlist { Some(_) => { debug!("requesting tracks again.."); spotify.user_playlist_tracks( - &id, + &self.id, 100, tracks.offset + tracks.items.len() as u32, ) @@ -70,33 +49,62 @@ impl Playlist { } } + self.tracks = Some(collected_tracks); + } +} + +impl From<&SimplifiedPlaylist> for Playlist { + fn from(list: &SimplifiedPlaylist) -> Self { + let num_tracks = if let Some(number) = list.tracks.get("total") { + number.as_u64().unwrap() as usize + } else { + 0 + }; + Playlist { - id, - name, - owner_id, - snapshot_id, - tracks: collected_tracks, + id: list.id.clone(), + name: list.name.clone(), + owner_id: list.owner.id.clone(), + snapshot_id: list.snapshot_id.clone(), + num_tracks, + tracks: None, + } + } +} + +impl From<&FullPlaylist> for Playlist { + fn from(list: &FullPlaylist) -> Self { + Playlist { + id: list.id.clone(), + name: list.name.clone(), + owner_id: list.owner.id.clone(), + snapshot_id: list.snapshot_id.clone(), + num_tracks: list.tracks.total as usize, + tracks: None, } } } impl ListItem for Playlist { fn is_playing(&self, queue: Arc) -> bool { - let playing: Vec = queue - .queue - .read() - .unwrap() - .iter() - .filter(|t| t.id.is_some()) - .map(|t| t.id.clone().unwrap()) - .collect(); - let ids: Vec = self - .tracks - .iter() - .filter(|t| t.id.is_some()) - .map(|t| t.id.clone().unwrap()) - .collect(); - !ids.is_empty() && playing == ids + if let Some(tracks) = self.tracks.as_ref() { + let playing: Vec = queue + .queue + .read() + .unwrap() + .iter() + .filter(|t| t.id.is_some()) + .map(|t| t.id.clone().unwrap()) + .collect(); + let ids: Vec = tracks + .iter() + .filter(|t| t.id.is_some()) + .map(|t| t.id.clone().unwrap()) + .collect(); + !ids.is_empty() && playing == ids + } else { + false + } } fn display_left(&self) -> String { @@ -113,17 +121,28 @@ impl ListItem for Playlist { } else { "" }; - format!("{}{:>3} tracks", followed, self.tracks.len()) + + let num_tracks = self.tracks.as_ref().map(|t| t.len()).unwrap_or(self.num_tracks); + + format!("{}{:>4} tracks", followed, num_tracks) } fn play(&mut self, queue: Arc) { - let index = queue.append_next(self.tracks.iter().collect()); - queue.play(index, true); + self.load_tracks(queue.get_spotify()); + + if let Some(tracks) = self.tracks.as_ref() { + let index = queue.append_next(tracks.iter().collect()); + queue.play(index, true); + } } fn queue(&mut self, queue: Arc) { - for track in self.tracks.iter() { - queue.append(track); + self.load_tracks(queue.get_spotify()); + + if let Some(tracks) = self.tracks.as_ref() { + for track in tracks.iter() { + queue.append(track); + } } } diff --git a/src/ui/playlist.rs b/src/ui/playlist.rs index c266594..6d9dc3c 100644 --- a/src/ui/playlist.rs +++ b/src/ui/playlist.rs @@ -18,9 +18,18 @@ pub struct PlaylistView { impl PlaylistView { pub fn new(queue: Arc, library: Arc, playlist: &Playlist) -> Self { - let playlist = playlist.clone(); + let mut playlist = playlist.clone(); + + playlist.load_tracks(queue.get_spotify()); + + let tracks = if let Some(t) = playlist.tracks.as_ref() { + t.clone() + } else { + Vec::new() + }; + let list = ListView::new( - Arc::new(RwLock::new(playlist.tracks.clone())), + Arc::new(RwLock::new(tracks)), queue, library, ); diff --git a/src/ui/search.rs b/src/ui/search.rs index 713bdda..dc80bc1 100644 --- a/src/ui/search.rs +++ b/src/ui/search.rs @@ -224,8 +224,8 @@ impl SearchView { _offset: usize, _append: bool, ) -> u32 { - if let Some(results) = spotify.playlist(&query) { - let pls = vec![Playlist::from_full_playlist(&results, &&spotify)]; + if let Some(result) = spotify.playlist(&query).as_ref() { + let pls = vec![result.into()]; let mut r = playlists.write().unwrap(); *r = pls; return 1; @@ -245,7 +245,7 @@ impl SearchView { .playlists .items .iter() - .map(|sp| Playlist::from_simplified_playlist(sp, &&spotify)) + .map(|sp| sp.into()) .collect(); let mut r = playlists.write().unwrap();