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

Issue:
Incorrent selection during search
**Describe the bug**
When im selecting a song while in search, it doesn't select it rather it selects the original playlist with the same index

**To Reproduce**
Go to Liked Tracks.
Search for a term. Go down and select one.
It doesn't play the selected one rather it starts playing the song which is the same index as the selected term in the liked tracks

**Expected behaviour**
It should play the select track


**Environment**

- OS: NixOS 24.05
- Application version: 0.18.1
- Application features: streaming, rodio,media-control,sixel,notify,lyrics
**Additional context**
Downgrading to 0.17.2 works as expected. I have not tested 0.18 but i'll assume the bug is introduced in that tag due to the UI changes



Discussion / hints:

Fix patch:
diff --git a/spotify_player/src/client/mod.rs b/spotify_player/src/client/mod.rs
index 402faf1a..fa1ba1d5 100644
--- a/spotify_player/src/client/mod.rs
+++ b/spotify_player/src/client/mod.rs
@@ -112,14 +112,32 @@ impl Client {
     pub async fn handle_player_request(
         &self,
         request: PlayerRequest,
-        playback: Option<PlaybackMetadata>,
+        mut playback: Option<PlaybackMetadata>,
     ) -> Result<Option<PlaybackMetadata>> {
-        // `TransferPlayback` needs to be handled separately from other player requests
-        // because `TransferPlayback` doesn't require an active playback
-        if let PlayerRequest::TransferPlayback(device_id, force_play) = request {
-            self.transfer_playback(&device_id, Some(force_play)).await?;
-            tracing::info!("Transferred playback to device with id={}", device_id);
-            return Ok(playback);
+        // handle requests that don't require an active playback
+        match request {
+            PlayerRequest::TransferPlayback(device_id, force_play) => {
+                // `TransferPlayback` needs to be handled separately from other player requests
+                // because `TransferPlayback` doesn't require an active playback
+                self.transfer_playback(&device_id, Some(force_play)).await?;
+                tracing::info!("Transferred playback to device with id={}", device_id);
+                return Ok(playback);
+            }
+            PlayerRequest::StartPlayback(p, shuffle) => {
+                // Set the playback's shuffle state if specified in the request
+                if let (Some(shuffle), Some(playback)) = (shuffle, playback.as_mut()) {
+                    playback.shuffle_state = shuffle;
+                }
+                let device_id = playback.as_ref().and_then(|p| p.device_id.as_deref());
+                self.start_playback(p, device_id).await?;
+                // For some reasons, when starting a new playback, the integrated `spotify_player`
+                // client doesn't respect the initial shuffle state, so we need to manually update the state
+                if let Some(ref playback) = playback {
+                    self.shuffle(playback.shuffle_state, device_id).await?;
+                }
+                return Ok(playback);
+            }
+            _ => {}
         }
 
         let mut playback = playback.context("no playback found")?;
@@ -188,14 +206,8 @@ impl Client {
 
                 playback.mute_state = new_mute_state;
             }
-            PlayerRequest::StartPlayback(p, shuffle) => {
-                if let Some(shuffle) = shuffle {
-                    playback.shuffle_state = shuffle;
-                }
-                self.start_playback(p, device_id).await?;
-                // for some reasons, when starting a new playback, the integrated `spotify_player`
-                // client doesn't respect the initial shuffle state, so we need to manually update the state
-                self.shuffle(playback.shuffle_state, device_id).await?;
+            PlayerRequest::StartPlayback(..) => {
+                anyhow::bail!("`StartPlayback` should be handled earlier")
             }
             PlayerRequest::TransferPlayback(..) => {
                 anyhow::bail!("`TransferPlayback` should be handled earlier")
diff --git a/spotify_player/src/event/window.rs b/spotify_player/src/event/window.rs
index fb681e0d..85a5bcd2 100644
--- a/spotify_player/src/event/window.rs
+++ b/spotify_player/src/event/window.rs
@@ -209,10 +209,12 @@ fn handle_command_for_track_table_window(
 
     match command {
         Command::PlayRandom | Command::ChooseSelected => {
-            let id = if command == Command::PlayRandom {
-                rand::thread_rng().gen_range(0..tracks.len())
+            let uri = if command == Command::PlayRandom {
+                tracks[rand::thread_rng().gen_range(0..tracks.len())]
+                    .id
+                    .uri()
             } else {
-                id
+                filtered_tracks[id].id.uri()
             };
 
             let base_playback = if let Some(context_id) = context_id {
@@ -222,10 +224,8 @@ fn handle_command_for_track_table_window(
             };
 
             client_pub.send(ClientRequest::Player(PlayerRequest::StartPlayback(
-                base_playback.uri_offset(
-                    tracks[id].id.uri(),
-                    config::get_config().app_config.tracks_playback_limit,
-                ),
+                base_playback
+                    .uri_offset(uri, config::get_config().app_config.tracks_playback_limit),
                 None,
             )))?;
         }


Test patch: