use super::model::{
AlbumId, ArtistId, ContextId, Device, PlaybackMetadata, PlaylistId, ShowId, TracksId,
};
#[derive(Default, Debug)]
pub struct PlayerState {
pub devices: Vec<Device>,
pub playback: Option<rspotify::model::CurrentPlaybackContext>,
pub playback_last_updated_time: Option<std::time::Instant>,
pub buffered_playback: Option<PlaybackMetadata>,
pub queue: Option<rspotify::model::CurrentUserQueue>,
pub currently_playing_tracks_id: Option<TracksId>,
}
impl PlayerState {
pub fn current_playback(&self) -> Option<rspotify::model::CurrentPlaybackContext> {
let mut playback = self.playback.clone()?;
playback.progress = playback.progress.map(|d| {
d + if playback.is_playing {
chrono::Duration::from_std(self.playback_last_updated_time.unwrap().elapsed())
.unwrap()
} else {
chrono::Duration::zero()
}
});
if let Some(ref p) = self.buffered_playback {
playback.device.name.clone_from(&p.device_name);
playback.device.id.clone_from(&p.device_id);
playback.is_playing = p.is_playing;
playback.device.volume_percent = p.volume;
playback.repeat_state = p.repeat_state;
playback.shuffle_state = p.shuffle_state;
}
Some(playback)
}
pub fn currently_playing(&self) -> Option<&rspotify::model::PlayableItem> {
self.playback.as_ref().and_then(|p| p.item.as_ref())
}
pub fn playback_progress(&self) -> Option<chrono::Duration> {
match self.playback {
None => None,
Some(ref playback) => {
let progress = playback.progress.unwrap()
+ if playback.is_playing {
chrono::Duration::from_std(
self.playback_last_updated_time.unwrap().elapsed(),
)
.ok()?
} else {
chrono::Duration::zero()
};
Some(progress)
}
}
}
pub fn playing_context_id(&self) -> Option<ContextId> {
match self.playback {
Some(ref playback) => match playback.context {
Some(ref context) => {
let uri = crate::utils::parse_uri(&context.uri);
match context._type {
rspotify::model::Type::Playlist => Some(ContextId::Playlist(
PlaylistId::from_uri(&uri).ok()?.into_static(),
)),
rspotify::model::Type::Album => Some(ContextId::Album(
AlbumId::from_uri(&uri).ok()?.into_static(),
)),
rspotify::model::Type::Artist => Some(ContextId::Artist(
ArtistId::from_uri(&uri).ok()?.into_static(),
)),
rspotify::model::Type::Show => {
Some(ContextId::Show(ShowId::from_uri(&uri).ok()?.into_static()))
}
_ => None,
}
}
None => self
.currently_playing_tracks_id
.clone()
.map(ContextId::Tracks),
},
None => None,
}
}
}