From 5f7cfdc76cbd2271084c3377e1fe29a9b720595f Mon Sep 17 00:00:00 2001 From: Felix Prillwitz Date: Thu, 23 Jan 2025 19:13:30 +0100 Subject: [PATCH] Expose `autoplay` option to `SpircLoadCommand` (#1446) * connect: add autoplay option to SpircLoadCommand * update CHANGELOG.md * actually ignore options when starting autoplay --- CHANGELOG.md | 1 + connect/src/model.rs | 7 ++++++- connect/src/spirc.rs | 23 ++++++++++++++++++----- examples/play_connect.rs | 1 + 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad5c94329..305bf5d5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [connect] Add `seek_to` field to `SpircLoadCommand` (breaking) - [connect] Add `repeat_track` field to `SpircLoadCommand` (breaking) +- [connect] Add `autoplay` field to `SpircLoadCommand` (breaking) - [connect] Add `pause` parameter to `Spirc::disconnect` method (breaking) - [playback] Add `track` field to `PlayerEvent::RepeatChanged` (breaking) - [core] Add `request_with_options` and `request_with_protobuf_and_options` to `SpClient` diff --git a/connect/src/model.rs b/connect/src/model.rs index 8315ee29b..73f869993 100644 --- a/connect/src/model.rs +++ b/connect/src/model.rs @@ -9,10 +9,15 @@ pub struct SpircLoadCommand { pub shuffle: bool, pub repeat: bool, pub repeat_track: bool, + /// Decides if the context or the autoplay of the context is played + /// + /// ## Remarks: + /// If `true` is provided, the option values (`shuffle`, `repeat` and `repeat_track`) are ignored + pub autoplay: bool, /// Decides the starting position in the given context /// /// ## Remarks: - /// If none is provided and shuffle true, a random track is played, otherwise the first + /// If `None` is provided and `shuffle` is `true`, a random track is played, otherwise the first pub playing_track: Option, } diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 8546296c1..d4773fc04 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -37,6 +37,7 @@ use futures_util::StreamExt; use protobuf::MessageField; use std::{ future::Future, + ops::Deref, sync::atomic::{AtomicUsize, Ordering}, sync::Arc, time::{Duration, SystemTime, UNIX_EPOCH}, @@ -934,6 +935,7 @@ impl SpircTask { shuffle, repeat, repeat_track, + autoplay: false, }, Some(play.context), ) @@ -1127,7 +1129,6 @@ impl SpircTask { self.handle_activate(); } - let current_context_uri = self.connect_state.context_uri(); let fallback = if let Some(ref ctx) = context { match ConnectState::get_context_uri_from_context(ctx) { Some(ctx_uri) => ctx_uri, @@ -1137,6 +1138,16 @@ impl SpircTask { &cmd.context_uri }; + let update_context = if cmd.autoplay { + UpdateContext::Autoplay + } else { + UpdateContext::Default + }; + + self.connect_state + .set_active_context(*update_context.deref()); + + let current_context_uri = self.connect_state.context_uri(); if current_context_uri == &cmd.context_uri && fallback == cmd.context_uri { debug!("context <{current_context_uri}> didn't change, no resolving required") } else { @@ -1145,7 +1156,7 @@ impl SpircTask { self.context_resolver.add(ResolveContext::from_uri( &cmd.context_uri, fallback, - UpdateContext::Default, + update_context, ContextAction::Replace, )); let context = self.context_resolver.get_next_context(Vec::new).await; @@ -1182,9 +1193,11 @@ impl SpircTask { cmd.shuffle, cmd.repeat, cmd.repeat_track ); - self.connect_state.set_shuffle(cmd.shuffle); - self.connect_state.set_repeat_context(cmd.repeat); - self.connect_state.set_repeat_track(cmd.repeat_track); + self.connect_state.set_shuffle(!cmd.autoplay && cmd.shuffle); + self.connect_state + .set_repeat_context(!cmd.autoplay && cmd.repeat); + self.connect_state + .set_repeat_track(!cmd.autoplay && cmd.repeat_track); if cmd.shuffle { if let Some(index) = index { diff --git a/examples/play_connect.rs b/examples/play_connect.rs index 60cf631fb..8ea7eaca9 100644 --- a/examples/play_connect.rs +++ b/examples/play_connect.rs @@ -83,6 +83,7 @@ async fn main() { shuffle: false, repeat: false, repeat_track: false, + autoplay: false, // the index specifies which track in the context starts playing, in this case the first in the album playing_track: PlayingTrack::Index(0).into(), })