spoticord/src/session/pbi.rs

134 lines
3.3 KiB
Rust

use librespot::core::spotify_id::SpotifyId;
use crate::utils::{self, spotify};
#[derive(Clone)]
pub struct PlaybackInfo {
last_updated: u128,
position_ms: u32,
pub track: Option<spotify::Track>,
pub episode: Option<spotify::Episode>,
pub spotify_id: Option<SpotifyId>,
pub duration_ms: u32,
pub is_playing: bool,
}
impl PlaybackInfo {
/// Create a new instance of PlaybackInfo
pub fn new(duration_ms: u32, position_ms: u32, is_playing: bool) -> Self {
Self {
last_updated: utils::get_time_ms(),
track: None,
episode: None,
spotify_id: None,
duration_ms,
position_ms,
is_playing,
}
}
/// Update position, duration and playback state
pub fn update_pos_dur(&mut self, position_ms: u32, duration_ms: u32, is_playing: bool) {
self.position_ms = position_ms;
self.duration_ms = duration_ms;
self.is_playing = is_playing;
self.last_updated = utils::get_time_ms();
}
/// Update spotify id, track and episode
pub fn update_track_episode(
&mut self,
spotify_id: SpotifyId,
track: Option<spotify::Track>,
episode: Option<spotify::Episode>,
) {
self.spotify_id = Some(spotify_id);
self.track = track;
self.episode = episode;
}
/// Get the current playback position
pub fn get_position(&self) -> u32 {
if self.is_playing {
let now = utils::get_time_ms();
let diff = now - self.last_updated;
self.position_ms + diff as u32
} else {
self.position_ms
}
}
/// Get the name of the track or episode
pub fn get_name(&self) -> Option<String> {
if let Some(track) = &self.track {
Some(track.name.clone())
} else {
self.episode.as_ref().map(|episode| episode.name.clone())
}
}
/// Get the artist(s) or show name of the current track
pub fn get_artists(&self) -> Option<String> {
if let Some(track) = &self.track {
Some(
track
.artists
.iter()
.map(|a| a.name.clone())
.collect::<Vec<String>>()
.join(", "),
)
} else {
self
.episode
.as_ref()
.map(|episode| episode.show.name.clone())
}
}
/// Get the album art url
pub fn get_thumbnail_url(&self) -> Option<String> {
if let Some(track) = &self.track {
let mut images = track.album.images.clone();
images.sort_by(|a, b| b.width.cmp(&a.width));
images.get(0).as_ref().map(|image| image.url.clone())
} else if let Some(episode) = &self.episode {
let mut images = episode.show.images.clone();
images.sort_by(|a, b| b.width.cmp(&a.width));
images.get(0).as_ref().map(|image| image.url.clone())
} else {
None
}
}
/// Get the type of audio (track or episode)
#[allow(dead_code)]
pub fn get_type(&self) -> Option<String> {
if self.track.is_some() {
Some("track".into())
} else if self.episode.is_some() {
Some("episode".into())
} else {
None
}
}
/// Get the public facing url of the track or episode
#[allow(dead_code)]
pub fn get_url(&self) -> Option<&str> {
if let Some(ref track) = self.track {
Some(track.external_urls.spotify.as_str())
} else if let Some(ref episode) = self.episode {
Some(episode.external_urls.spotify.as_str())
} else {
None
}
}
}