diff --git a/connect/src/context_resolver.rs b/connect/src/context_resolver.rs index 2d599e3a..1bc0c163 100644 --- a/connect/src/context_resolver.rs +++ b/connect/src/context_resolver.rs @@ -319,7 +319,7 @@ impl ContextResolver { let res = if let Some(transfer_state) = transfer_state.take() { state.finish_transfer(transfer_state) } else if state.shuffling_context() && next.update == ContextType::Default { - state.shuffle(None) + state.shuffle_new() } else if matches!(active_ctx, Ok(ctx) if ctx.index.track == 0) { // has context, and context is not touched // when the index is not zero, the next index was already evaluated elsewhere diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 6bb9685b..087384e9 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -1287,7 +1287,7 @@ impl SpircTask { if self.context_resolver.has_next() { self.connect_state.update_queue_revision() } else { - self.connect_state.shuffle(None)?; + self.connect_state.shuffle_new()?; self.add_autoplay_resolving_when_required(); } } else { diff --git a/connect/src/state/handle.rs b/connect/src/state/handle.rs index 54a7a913..e031410a 100644 --- a/connect/src/state/handle.rs +++ b/connect/src/state/handle.rs @@ -13,7 +13,7 @@ impl ConnectState { self.set_shuffle(shuffle); if shuffle { - return self.shuffle(None); + return self.shuffle_new(); } self.reset_context(ResetContext::DefaultIndex); diff --git a/connect/src/state/options.rs b/connect/src/state/options.rs index 76970275..efb83764 100644 --- a/connect/src/state/options.rs +++ b/connect/src/state/options.rs @@ -50,7 +50,7 @@ impl ConnectState { self.set_repeat_context(false); } - pub fn shuffle(&mut self, shuffle_state: Option) -> Result<(), Error> { + fn validate_shuffle_allowed(&self) -> Result<(), Error> { if let Some(reason) = self .player() .restrictions @@ -61,39 +61,39 @@ impl ConnectState { action: "shuffle", reason: reason.clone(), })? + } else { + Ok(()) } + } + pub fn shuffle_restore(&mut self, shuffle_state: ShuffleState) -> Result<(), Error> { + self.validate_shuffle_allowed()?; + + self.shuffle(shuffle_state.seed, &shuffle_state.initial_track) + } + + pub fn shuffle_new(&mut self) -> Result<(), Error> { + self.validate_shuffle_allowed()?; + + let new_seed = rand::rng().random_range(100_000_000_000..1_000_000_000_000); + let current_track = self.current_track(|t| t.uri.clone()); + + self.shuffle(new_seed, ¤t_track) + } + + fn shuffle(&mut self, seed: u64, initial_track: &str) -> Result<(), Error> { self.clear_prev_track(); self.clear_next_tracks(); - let (seed, initial_track) = match shuffle_state { - Some(state) => (state.seed, Some(state.initial_track)), - None => ( - rand::rng().random_range(100_000_000_000..1_000_000_000_000), - None, - ), - }; - - let current_track = self.current_track(|t| t.uri.clone()); - let first_track = initial_track.as_ref().unwrap_or(¤t_track); - self.reset_context(ResetContext::DefaultIndex); let ctx = self.get_context_mut(ContextType::Default)?; ctx.tracks - .shuffle_with_seed(seed, |f| f.uri == *first_track); - ctx.set_initial_track(first_track); + .shuffle_with_seed(seed, |f| f.uri == initial_track); + + ctx.set_initial_track(initial_track); ctx.set_shuffle_seed(seed); - let start_at = - initial_track.and_then(|initial| ctx.tracks.iter().position(|t| t.uri == initial)); - - let start_at = start_at.unwrap_or_default(); - self.update_current_index(|i| i.track = start_at as u32); - self.update_context_index(ContextType::Default, start_at + 1)?; - - self.set_active_context(ContextType::Default); - self.fill_up_context = ContextType::Default; self.fill_up_next_tracks()?; Ok(()) diff --git a/connect/src/state/transfer.rs b/connect/src/state/transfer.rs index e05897e7..8fdb21fa 100644 --- a/connect/src/state/transfer.rs +++ b/connect/src/state/transfer.rs @@ -173,8 +173,10 @@ impl ConnectState { self.set_current_track(current_index.unwrap_or_default())?; self.set_shuffle(true); - let shuffle = self.transfer_shuffle.take(); - self.shuffle(shuffle)?; + match self.transfer_shuffle.take() { + None => self.shuffle_new(), + Some(state) => self.shuffle_restore(state), + }? } else { self.reset_playback_to_position(current_index)?; }