summaryrefslogtreecommitdiffstats
path: root/src/bin/volume.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/volume.rs')
-rw-r--r--src/bin/volume.rs109
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(())
}