connect: make playing_track optional and handle it correctly

This commit is contained in:
Felix Prillwitz 2024-12-17 21:01:35 +01:00
parent f59b43b9c4
commit dfbac73136
No known key found for this signature in database
GPG key ID: DE334B43606D1455
2 changed files with 30 additions and 17 deletions

View file

@ -9,7 +9,11 @@ pub struct SpircLoadCommand {
pub shuffle: bool, pub shuffle: bool,
pub repeat: bool, pub repeat: bool,
pub repeat_track: bool, pub repeat_track: bool,
pub playing_track: PlayingTrack, /// Decides the starting position in the given context
///
/// ## Remarks:
/// If none is provided and shuffle true, a random track is played, otherwise the first
pub playing_track: Option<PlayingTrack>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -19,19 +23,20 @@ pub enum PlayingTrack {
Uid(String), Uid(String),
} }
impl From<SkipTo> for PlayingTrack { impl TryFrom<SkipTo> for PlayingTrack {
fn from(value: SkipTo) -> Self { type Error = ();
fn try_from(value: SkipTo) -> Result<Self, ()> {
// order of checks is important, as the index can be 0, but still has an uid or uri provided, // order of checks is important, as the index can be 0, but still has an uid or uri provided,
// so we only use the index as last resort // so we only use the index as last resort
if let Some(uri) = value.track_uri { if let Some(uri) = value.track_uri {
PlayingTrack::Uri(uri) Ok(PlayingTrack::Uri(uri))
} else if let Some(uid) = value.track_uid { } else if let Some(uid) = value.track_uid {
PlayingTrack::Uid(uid) Ok(PlayingTrack::Uid(uid))
} else if let Some(index) = value.track_index {
Ok(PlayingTrack::Index(index))
} else { } else {
PlayingTrack::Index(value.track_index.unwrap_or_else(|| { Err(())
warn!("SkipTo didn't provided any point to skip to, falling back to index 0");
0
}))
} }
} }
} }

View file

@ -918,7 +918,7 @@ impl SpircTask {
context_uri: play.context.uri.clone(), context_uri: play.context.uri.clone(),
start_playing: true, start_playing: true,
seek_to: play.options.seek_to.unwrap_or_default(), seek_to: play.options.seek_to.unwrap_or_default(),
playing_track: play.options.skip_to.into(), playing_track: play.options.skip_to.try_into().ok(),
shuffle, shuffle,
repeat, repeat,
repeat_track, repeat_track,
@ -1141,16 +1141,21 @@ impl SpircTask {
debug!("play track <{:?}>", cmd.playing_track); debug!("play track <{:?}>", cmd.playing_track);
let index = match cmd.playing_track { let index = cmd.playing_track.map(|p| match p {
PlayingTrack::Index(i) => i as usize, PlayingTrack::Index(i) => Ok(i as usize),
PlayingTrack::Uri(uri) => { PlayingTrack::Uri(uri) => {
let ctx = self.connect_state.get_context(ContextType::Default)?; let ctx = self.connect_state.get_context(ContextType::Default)?;
ConnectState::find_index_in_context(ctx, |t| t.uri == uri)? ConnectState::find_index_in_context(ctx, |t| t.uri == uri)
} }
PlayingTrack::Uid(uid) => { PlayingTrack::Uid(uid) => {
let ctx = self.connect_state.get_context(ContextType::Default)?; let ctx = self.connect_state.get_context(ContextType::Default)?;
ConnectState::find_index_in_context(ctx, |t| t.uid == uid)? ConnectState::find_index_in_context(ctx, |t| t.uid == uid)
} }
});
let index = match index {
Some(value) => Some(value?),
None => None,
}; };
debug!( debug!(
@ -1163,7 +1168,9 @@ impl SpircTask {
self.connect_state.set_repeat_track(cmd.repeat_track); self.connect_state.set_repeat_track(cmd.repeat_track);
if cmd.shuffle { if cmd.shuffle {
if index.is_none() {
self.connect_state.set_current_track_random()?; self.connect_state.set_current_track_random()?;
}
if self.context_resolver.has_next() { if self.context_resolver.has_next() {
self.connect_state.update_queue_revision() self.connect_state.update_queue_revision()
@ -1172,8 +1179,9 @@ impl SpircTask {
self.add_autoplay_resolving_when_required(); self.add_autoplay_resolving_when_required();
} }
} else { } else {
self.connect_state.set_current_track(index)?; self.connect_state
self.connect_state.reset_playback_to_position(Some(index))?; .set_current_track(index.unwrap_or_default())?;
self.connect_state.reset_playback_to_position(index)?;
self.add_autoplay_resolving_when_required(); self.add_autoplay_resolving_when_required();
} }