Repository: aome510/spotify-player (language: rust)

Issue:
Add album to queue
**Is your feature already implemented in the latest `master`?**
No

**Is your feature request related to a problem? Please describe.**
I like adding albums to queue on the official Spotify GUI but this feature is missing.

**Describe the solution you'd like**
Ability to add an album to queue with either `Z` or the `ShowActionsOnSelectedItem` menu on an album.


Discussion / hints:

Fix patch:
diff --git a/spotify_player/src/client/mod.rs b/spotify_player/src/client/mod.rs
index fa209d41..baf32e09 100644
--- a/spotify_player/src/client/mod.rs
+++ b/spotify_player/src/client/mod.rs
@@ -416,6 +416,16 @@ impl Client {
                 self.add_track_to_playlist(state, playlist_id, track_id)
                     .await?;
             }
+            ClientRequest::AddAlbumToQueue(album_id) => {
+                let album_context = self.album_context(album_id).await?;
+
+                if let Context::Album { album: _, tracks } = album_context {
+                    for track in tracks {
+                        self.add_item_to_queue(PlayableId::Track(track.id), None)
+                            .await?;
+                    }
+                }
+            }
             ClientRequest::DeleteTrackFromPlaylist(playlist_id, track_id) => {
                 self.delete_track_from_playlist(state, playlist_id, track_id)
                     .await?;
diff --git a/spotify_player/src/client/request.rs b/spotify_player/src/client/request.rs
index ca9061b0..8991a301 100644
--- a/spotify_player/src/client/request.rs
+++ b/spotify_player/src/client/request.rs
@@ -38,6 +38,7 @@ pub enum ClientRequest {
     },
     Search(String),
     AddTrackToQueue(TrackId<'static>),
+    AddAlbumToQueue(AlbumId<'static>),
     AddTrackToPlaylist(PlaylistId<'static>, TrackId<'static>),
     DeleteTrackFromPlaylist(PlaylistId<'static>, TrackId<'static>),
     ReorderPlaylistItems {
diff --git a/spotify_player/src/command.rs b/spotify_player/src/command.rs
index 33b59295..72f167d8 100644
--- a/spotify_player/src/command.rs
+++ b/spotify_player/src/command.rs
@@ -101,6 +101,7 @@ pub enum AlbumAction {
     AddToLibrary,
     DeleteFromLibrary,
     CopyAlbumLink,
+    AddToQueue,
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -149,6 +150,7 @@ pub fn construct_album_actions(album: &Album, data: &DataReadGuard) -> Vec<Album
         AlbumAction::GoToAlbumRadio,
         AlbumAction::ShowActionsOnArtist,
         AlbumAction::CopyAlbumLink,
+        AlbumAction::AddToQueue,
     ];
     if data.user_data.saved_albums.iter().any(|a| a.id == album.id) {
         actions.push(AlbumAction::DeleteFromLibrary);
diff --git a/spotify_player/src/event/page.rs b/spotify_player/src/event/page.rs
index 17aaaf83..ff443007 100644
--- a/spotify_player/src/event/page.rs
+++ b/spotify_player/src/event/page.rs
@@ -25,7 +25,7 @@ pub fn handle_key_sequence_for_page(
 
     match page_type {
         PageType::Search => anyhow::bail!("page search type should already be handled!"),
-        PageType::Library => handle_command_for_library_page(command, ui, state),
+        PageType::Library => handle_command_for_library_page(command, client_pub, ui, state),
         PageType::Context => handle_command_for_context_page(command, client_pub, ui, state),
         PageType::Browse => handle_command_for_browse_page(command, client_pub, ui, state),
         #[cfg(feature = "lyric-finder")]
@@ -37,6 +37,7 @@ pub fn handle_key_sequence_for_page(
 
 fn handle_command_for_library_page(
     command: Command,
+    client_pub: &flume::Sender<ClientRequest>,
     ui: &mut UIStateGuard,
     state: &SharedState,
 ) -> Result<bool> {
@@ -63,6 +64,7 @@ fn handle_command_for_library_page(
                     ui.search_filtered_items(&data.user_data.saved_albums),
                     &data,
                     ui,
+                    client_pub,
                 ),
                 LibraryFocusState::FollowedArtists => {
                     window::handle_command_for_artist_list_window(
@@ -140,7 +142,7 @@ fn handle_key_sequence_for_search_page(
             let albums = search_results
                 .map(|s| s.albums.iter().collect())
                 .unwrap_or_default();
-            window::handle_command_for_album_list_window(command, albums, &data, ui)
+            window::handle_command_for_album_list_window(command, albums, &data, ui, client_pub)
         }
         SearchFocusState::Playlists => {
             let playlists = search_results
diff --git a/spotify_player/src/event/popup.rs b/spotify_player/src/event/popup.rs
index ec2714eb..f578c831 100644
--- a/spotify_player/src/event/popup.rs
+++ b/spotify_player/src/event/popup.rs
@@ -587,6 +587,10 @@ fn handle_item_action(
                 client_pub.send(ClientRequest::DeleteFromLibrary(ItemId::Album(album.id)))?;
                 ui.popup = None;
             }
+            AlbumAction::AddToQueue => {
+                client_pub.send(ClientRequest::AddAlbumToQueue(album.id))?;
+                ui.popup = None;
+            }
         },
         ActionListItem::Artist(artist, actions) => match actions[n] {
             ArtistAction::Follow => {
diff --git a/spotify_player/src/event/window.rs b/spotify_player/src/event/window.rs
index a0a12746..fb681e0d 100644
--- a/spotify_player/src/event/window.rs
+++ b/spotify_player/src/event/window.rs
@@ -79,6 +79,7 @@ pub fn handle_command_for_focused_context_window(
                         ui.search_filtered_items(albums),
                         &data,
                         ui,
+                        client_pub,
                     ),
                     ArtistFocusState::RelatedArtists => handle_command_for_artist_list_window(
                         command,
@@ -327,6 +328,7 @@ pub fn handle_command_for_album_list_window(
     albums: Vec<&Album>,
     data: &DataReadGuard,
     ui: &mut UIStateGuard,
+    client_pub: &flume::Sender<ClientRequest>,
 ) -> Result<bool> {
     let id = ui.current_page_mut().selected().unwrap_or_default();
     if id >= albums.len() {
@@ -352,6 +354,9 @@ pub fn handle_command_for_album_list_window(
                 new_list_state(),
             ));
         }
+        Command::AddSelectedItemToQueue => {
+            client_pub.send(ClientRequest::AddAlbumToQueue(albums[id].id.clone()))?;
+        }
         _ => return Ok(false),
     }
     Ok(true)


Test patch: