diff options
Diffstat (limited to 'src/components.rs')
-rw-r--r-- | src/components.rs | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/src/components.rs b/src/components.rs deleted file mode 100644 index 1548365..0000000 --- a/src/components.rs +++ /dev/null @@ -1,234 +0,0 @@ -use std::{collections::HashMap, option::Option, time::Duration}; - -use futures_util::StreamExt; -use tokio::{sync::mpsc::Sender, task::JoinHandle}; -use zbus::zvariant::OwnedValue; - -use crate::{ - dbus::player::{PlaybackStatus, PlayerProxy}, - error::Result, - i3bar::Block, -}; - -const TICK_RATE: Duration = Duration::from_millis(500); - -pub trait Component: std::marker::Sized { - fn listen( - &self, - proxy: PlayerProxy<'static>, - tx: Sender<Block>, - ) -> impl std::future::Future<Output = Result<()>> + Send; -} - -#[derive(Debug, Clone, Default)] -pub struct Icon; - -impl Component for Icon { - async fn listen(&self, _: PlayerProxy<'static>, tx: Sender<Block>) -> Result<()> { - tx.send(Block { - full_text: " ".into(), - instance: "mpris-icon".into(), - ..Default::default() - }) - .await - .map_err(Into::into) - } -} - -#[derive(Debug, Clone, Default)] -pub struct Title; - -impl Title { - async fn process_metadata( - tx: Sender<Block>, - metadata: HashMap<String, OwnedValue>, - rotator: &mut Option<JoinHandle<Result<()>>>, - last: &mut Option<String>, - ) -> Result<()> { - let Some(val) = metadata.get("xesam:title") else { - return Ok(()); - }; - - let title: String = val.try_to_owned()?.try_into()?; - - if last.as_ref().is_some_and(|s| *s == title) { - return Ok(()); - } - - let mut block = Block { - instance: "mpris-title".into(), - ..Default::default() - }; - - if let Some(h) = rotator.take() { - h.abort() - }; - - if title.len() > 10 { - let mut chars = title.chars().collect::<Vec<char>>(); - *last = Some(title); - *rotator = Some(tokio::spawn(async move { - let mut interval = tokio::time::interval(TICK_RATE); - chars.push(' '); - - loop { - interval.tick().await; - block.full_text = chars[0..10].iter().collect(); - tx.send(block.clone()).await?; - chars.rotate_left(1); - } - })); - } else { - *last = Some(title.clone()); - block.full_text = title; - tx.send(block).await?; - } - - Ok(()) - } -} - -impl Component for Title { - async fn listen(&self, proxy: PlayerProxy<'static>, tx: Sender<Block>) -> Result<()> { - let mut stream = proxy.receive_metadata_changed().await; - let mut rotator = None; - let mut last = None; - - Self::process_metadata(tx.clone(), proxy.metadata().await?, &mut rotator, &mut last) - .await?; - - while let Some(signal) = stream.next().await { - if let Ok(metadata) = signal.get().await { - Self::process_metadata(tx.clone(), metadata, &mut rotator, &mut last).await?; - }; - } - Ok(()) - } -} - -#[derive(Debug, Clone, Default)] -pub struct Prev; - -impl Component for Prev { - async fn listen(&self, proxy: PlayerProxy<'static>, tx: Sender<Block>) -> Result<()> { - let mut block = Block { - full_text: proxy - .can_go_previous() - .await - .unwrap_or_default() - .then_some(" ".into()) - .unwrap_or_default(), - instance: "mpris-prev".into(), - ..Default::default() - }; - - tx.send(block.clone()).await?; - - let mut stream = proxy.receive_can_go_previous_changed().await; - while let Some(signal) = stream.next().await { - if let Ok(val) = signal.get().await { - block.full_text = val.then_some(" ".into()).unwrap_or_default(); - - tx.send(block.clone()).await?; - }; - } - Ok(()) - } -} - -#[derive(Debug, Clone, Default)] -pub struct PlayPause; - -impl Component for PlayPause { - async fn listen(&self, proxy: PlayerProxy<'static>, tx: Sender<Block>) -> Result<()> { - let mut block = Block { - instance: "mpris-playpause".into(), - ..Default::default() - }; - - block.full_text = match proxy.playback_status().await? { - PlaybackStatus::Playing => " ", - PlaybackStatus::Paused | PlaybackStatus::Stopped => " ", - } - .to_string(); - - tx.send(block.clone()).await?; - - let mut stream = proxy.receive_playback_status_changed().await; - while let Some(signal) = stream.next().await { - if let Ok(val) = signal.get().await { - block.full_text = match val { - PlaybackStatus::Playing => " ", - PlaybackStatus::Paused | PlaybackStatus::Stopped => " ", - } - .to_string(); - - tx.send(block.clone()).await?; - }; - } - Ok(()) - } -} - -#[derive(Debug, Clone, Default)] -pub struct Next; - -impl Component for Next { - async fn listen(&self, proxy: PlayerProxy<'static>, tx: Sender<Block>) -> Result<()> { - let mut block = Block { - full_text: proxy - .can_go_next() - .await - .unwrap_or_default() - .then_some(" ".into()) - .unwrap_or_default(), - instance: "mpris-next".into(), - ..Default::default() - }; - - tx.send(block.clone()).await?; - - let mut stream = proxy.receive_can_go_next_changed().await; - while let Some(signal) = stream.next().await { - if let Ok(val) = signal.get().await { - block.full_text = val.then_some(" ".into()).unwrap_or_default(); - tx.send(block.clone()).await?; - }; - } - Ok(()) - } -} - -#[derive(Debug, Clone, Default)] -pub struct Volume; - -impl Component for Volume { - async fn listen(&self, proxy: PlayerProxy<'static>, tx: Sender<Block>) -> Result<()> { - let mut block = Block { - instance: "mpris-volume".into(), - ..Default::default() - }; - - block.full_text = match (proxy.volume().await? * 100_f64) as u32 { - v @ 66.. => format!(" {v}% "), - v @ 33.. => format!(" {v}% "), - v @ 0.. => format!(" {v}% "), - }; - - tx.send(block.clone()).await?; - - let mut stream = proxy.receive_volume_changed().await; - while let Some(signal) = stream.next().await { - if let Ok(val) = signal.get().await { - block.full_text = match (val * 100_f64) as u32 { - v @ 66.. => format!(" {v}% "), - v @ 33.. => format!(" {v}% "), - v @ 0.. => format!(" {v}% "), - }; - - tx.send(block.clone()).await?; - }; - } - Ok(()) - } -} |