From ed3404d28b4a421a1ec4d172e08e3f383bd65569 Mon Sep 17 00:00:00 2001 From: nick42d <133559267+nick42d@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:40:36 +0800 Subject: [PATCH] fix: Use a unique identifier to add albums instead of the album name. Closes #12. (#183) --- youtui/src/app/server/api.rs | 8 ++++--- youtui/src/app/structures.rs | 44 ++++++++++++++++-------------------- youtui/src/app/ui/browser.rs | 12 ++++++---- youtui/src/app/ui/footer.rs | 4 ++-- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/youtui/src/app/server/api.rs b/youtui/src/app/server/api.rs index 5699fe1d..0e496729 100644 --- a/youtui/src/app/server/api.rs +++ b/youtui/src/app/server/api.rs @@ -168,6 +168,7 @@ pub enum GetArtistSongsProgressUpdate { Songs { song_list: Vec, album: String, + album_id: AlbumID<'static>, year: String, artist: String, }, @@ -277,15 +278,15 @@ fn get_artist_songs( let api = api.clone(); async move { let query = GetAlbumQuery::new(&a_id); - query_api_with_retry(&api, query).await + (query_api_with_retry(&api, query).await, a_id) } }) .collect::>(); - while let Some(maybe_album) = stream.next().await { + while let Some((maybe_album, album_id)) = stream.next().await { let album = match maybe_album { Ok(album) => album, Err(e) => { - error!("Error <{e}> getting album"); + error!("Error <{e}> getting album {:?}", album_id); return; } }; @@ -302,6 +303,7 @@ fn get_artist_songs( GetArtistSongsProgressUpdate::Songs { song_list: tracks, album: title, + album_id, year, artist: artists .into_iter() diff --git a/youtui/src/app/structures.rs b/youtui/src/app/structures.rs index 4a089394..5bf56be4 100644 --- a/youtui/src/app/structures.rs +++ b/youtui/src/app/structures.rs @@ -4,6 +4,7 @@ use std::borrow::Cow; use std::rc::Rc; use std::sync::Arc; use std::time::Duration; +use ytmapi_rs::common::AlbumID; use ytmapi_rs::parse::AlbumSong; pub trait SongListComponent { @@ -31,9 +32,10 @@ pub struct ListSong { pub download_status: DownloadStatus, pub id: ListSongID, pub actual_duration: Option, - year: Rc, - artists: Vec>, - album: Rc, + pub year: Rc, + pub artists: Vec>, + pub album: Rc, + pub album_id: Rc>, } #[derive(Clone)] pub enum ListStatus { @@ -92,24 +94,6 @@ impl DownloadStatus { } impl ListSong { - fn _set_year(&mut self, year: Rc) { - self.year = year; - } - fn _set_album(&mut self, album: Rc) { - self.album = album; - } - pub fn get_year(&self) -> &String { - &self.year - } - fn _set_artists(&mut self, artists: Vec>) { - self.artists = artists; - } - pub fn get_artists(&self) -> &Vec> { - &self.artists - } - pub fn get_album(&self) -> &String { - &self.album - } pub fn get_track_no(&self) -> usize { self.raw.track_no } @@ -128,16 +112,16 @@ impl ListSong { }), self.get_track_no().to_string().into(), // TODO: Remove allocation - self.get_artists() + self.artists .first() .map(|a| a.to_string()) .unwrap_or_default() .into(), - self.get_album().into(), + self.album.as_ref().into(), (&self.raw.title).into(), // TODO: Remove allocation (&self.raw.duration).into(), - self.get_year().into(), + self.year.as_ref().into(), ] .into_iter(), ) @@ -185,6 +169,7 @@ impl AlbumSongsList { &mut self, raw_list: Vec, album: String, + album_id: AlbumID<'static>, year: String, artist: String, ) { @@ -192,16 +177,24 @@ impl AlbumSongsList { // So no need to clone/allocate for eache one. // Instead we'll share ownership via Rc. let album = Rc::new(album); + let album_id = Rc::new(album_id); let year = Rc::new(year); let artist = Rc::new(artist); for song in raw_list { - self.add_raw_song(song, album.clone(), year.clone(), artist.clone()); + self.add_raw_song( + song, + album.clone(), + album_id.clone(), + year.clone(), + artist.clone(), + ); } } pub fn add_raw_song( &mut self, song: AlbumSong, album: Rc, + album_id: Rc>, year: Rc, artist: Rc, ) -> ListSongID { @@ -213,6 +206,7 @@ impl AlbumSongsList { year, artists: vec![artist], album, + album_id, actual_duration: None, }); id diff --git a/youtui/src/app/ui/browser.rs b/youtui/src/app/ui/browser.rs index a7cff23e..b31d3949 100644 --- a/youtui/src/app/ui/browser.rs +++ b/youtui/src/app/ui/browser.rs @@ -27,7 +27,7 @@ use std::{borrow::Cow, mem, sync::Arc}; use tokio::sync::mpsc; use tracing::error; use ytmapi_rs::{ - common::SearchSuggestion, + common::{AlbumID, SearchSuggestion}, parse::{AlbumSong, SearchResultArtist}, }; @@ -361,7 +361,7 @@ impl Browser { .list // Even if list is filtered, still play the whole album. .get_list_iter() - .filter(|song| song.get_album() == cur_song.get_album()) + .filter(|song| song.album_id == cur_song.album_id) .cloned() .collect(); send_or_error( @@ -382,7 +382,7 @@ impl Browser { .list // Even if list is filtered, still play the whole album. .get_list_iter() - .filter(|song| song.get_album() == cur_song.get_album()) + .filter(|song| song.album_id == cur_song.album_id) // XXX: Could instead be inside an Rc. .cloned() .collect(); @@ -445,7 +445,8 @@ impl Browser { album, year, artist, - } => this.handle_append_song_list(song_list, album, year, artist), + album_id, + } => this.handle_append_song_list(song_list, album, album_id, year, artist), GetArtistSongsProgressUpdate::AllSongsSent => this.handle_song_list_loaded(), }; @@ -509,12 +510,13 @@ impl Browser { &mut self, song_list: Vec, album: String, + album_id: AlbumID<'static>, year: String, artist: String, ) { self.album_songs_list .list - .append_raw_songs(song_list, album, year, artist); + .append_raw_songs(song_list, album, album_id, year, artist); // If sort commands exist, sort the list. // Naive - can result in multiple calls to sort every time songs are appended. self.album_songs_list.apply_sort_commands(); diff --git a/youtui/src/app/ui/footer.rs b/youtui/src/app/ui/footer.rs index 37aee858..da216038 100644 --- a/youtui/src/app/ui/footer.rs +++ b/youtui/src/app/ui/footer.rs @@ -73,7 +73,7 @@ pub fn draw_footer(f: &mut Frame, w: &super::YoutuiWindow, chunk: Rect) { | PlayState::Buffering(id) => w .playlist .get_song_from_id(id) - .map(|s| s.get_album().to_owned()) + .map(|s| s.album.as_ref().to_owned()) .unwrap_or("".to_string()), PlayState::NotPlaying => "".to_string(), PlayState::Stopped => "".to_string(), @@ -88,7 +88,7 @@ pub fn draw_footer(f: &mut Frame, w: &super::YoutuiWindow, chunk: Rect) { // TODO: tidy this up as ListSong only contains one artist currently. // TODO: Remove allocation .map(|s| { - s.get_artists() + s.artists .clone() .first() .map(|a| a.to_string())