diff options
Diffstat (limited to 'src/bin/volume.rs')
-rw-r--r-- | src/bin/volume.rs | 109 |
1 files changed, 55 insertions, 54 deletions
diff --git a/src/bin/volume.rs b/src/bin/volume.rs index 5e9d1d1..b5182b3 100644 --- a/src/bin/volume.rs +++ b/src/bin/volume.rs @@ -1,76 +1,77 @@ use std::sync::Arc; -use futures_util::StreamExt; use i3blocks::{ - color_listener, - dbus::{player::PlayerProxy, playerctld::PlayerctldProxy}, - i3bar::Block, - player_listener, Error, -}; -use tokio::{ - sync::{mpsc::Sender, Mutex}, - task::JoinSet, + dbus::player::{PlaybackStatus, PlayerProxy}, + i3bar::{Block, Click}, + Button, Component, Error, Update, }; +use tokio::sync::{mpsc::Sender, Mutex}; use zbus::Connection; #[tokio::main] async fn main() -> Result<(), main_error::MainError> { - let mut join_set = JoinSet::new(); + i3blocks::run::<Volume>(Default::default()) + .await + .map_err(Into::into) +} - let (tx_player, mut rx_player) = tokio::sync::mpsc::channel(128); - let (tx_status, mut rx_status) = tokio::sync::mpsc::channel(128); - let (tx_value, mut rx_value) = tokio::sync::mpsc::channel(128); +pub struct Volume; - let conn = Connection::session().await?; - let proxy = PlayerctldProxy::builder(&conn).build().await?; +impl Component for Volume { + const NAME: &'static str = "volume"; + type Updater = Self; + type Colorer = PlaybackStatus; + type Handler = Self; +} - tokio::spawn(player_listener(tx_player, proxy)); +impl Update for Volume { + type Value = f64; - let status: Arc<Mutex<Block>> = Default::default(); + async fn listen(tx: Sender<Self::Value>, proxy: PlayerProxy<'_>) -> Result<(), Error> { + use futures_util::StreamExt; - loop { - tokio::select! { - Some(name) = rx_player.recv() => { - join_set.shutdown().await; - if name.is_empty() { - let mut status = status.lock().await; - status.full_text = Default::default(); - } else { - let proxy = PlayerProxy::builder(&conn) - .destination(name)? - .build() - .await?; - join_set.spawn(color_listener(tx_status.clone(), proxy.clone())); - join_set.spawn(value_listener(tx_value.clone(), proxy)); - } - } - Some((color, background)) = rx_status.recv() => { - let mut status = status.lock().await; - status.color = color; - status.background = background; - } - Some(value) = rx_value.recv() => { - let mut status = status.lock().await; - status.full_text = match (value * 100_f64) as u32 { - v @ 66.. => format!(" {v}% "), - v @ 33.. => format!(" {v}% "), - v @ 0.. => format!(" {v}% "), - }; + tx.send(proxy.volume().await?).await?; + let mut stream = proxy.receive_volume_changed().await; + while let Some(signal) = stream.next().await { + if let Ok(value) = signal.get().await { + tx.send(value).await?; } } + Ok(()) + } - let s = status.lock().await; - s.write_stdout()?; + async fn update(value: Self::Value, block: Arc<Mutex<Block>>) -> Result<bool, Error> { + let mut block = block.lock().await; + block.full_text = match (value * 100_f64) as u32 { + v @ 66.. => format!(" {v}% "), + v @ 33.. => format!(" {v}% "), + v @ 0.. => format!(" {v}% "), + }; + Ok(true) } } -pub async fn value_listener(tx: Sender<f64>, proxy: PlayerProxy<'_>) -> Result<(), Error> { - tx.send(proxy.volume().await?).await?; - let mut stream = proxy.receive_volume_changed().await; - while let Some(signal) = stream.next().await { - if let Ok(value) = signal.get().await { - tx.send(value).await?; +impl Button for Volume { + async fn handle(conn: Connection, click: Click) -> Result<(), Error> { + let Some(name) = click.instance else { + return Ok(()); + }; + + let proxy = PlayerProxy::builder(&conn) + .destination(name)? + .build() + .await?; + + match click.button { + 4 if proxy.can_control().await? => { + proxy.set_volume(proxy.volume().await? - 0.05).await? + } + 5 if proxy.can_control().await? => { + proxy.set_volume(proxy.volume().await? + 0.05).await? + } + _ => {} } + + Ok(()) } - Ok(()) } |