summaryrefslogtreecommitdiffstats
path: root/src/component/volume.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/component/volume.rs')
-rw-r--r--src/component/volume.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/component/volume.rs b/src/component/volume.rs
new file mode 100644
index 0000000..2cc7600
--- /dev/null
+++ b/src/component/volume.rs
@@ -0,0 +1,71 @@
+use std::sync::Arc;
+
+use tokio::sync::{mpsc::Sender, Mutex};
+use zbus::Connection;
+
+use crate::{
+ dbus::player::{PlaybackStatus, PlayerProxy},
+ i3bar::{Block, Click},
+ Error,
+};
+
+use super::{Button, Component, Update};
+
+pub struct Volume;
+
+impl Component for Volume {
+ const NAME: &'static str = "volume";
+ type Updater = Self;
+ type Colorer = PlaybackStatus;
+ type Handler = Self;
+}
+
+impl Update for Volume {
+ type Value = Option<f64>;
+
+ async fn listen(tx: Sender<Self::Value>, proxy: PlayerProxy<'_>) -> Result<(), Error> {
+ use futures_util::StreamExt;
+
+ tx.send(proxy.volume().await.ok()).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(Some(value)).await?;
+ }
+ }
+ Ok(())
+ }
+
+ async fn update(value: Self::Value, block: Arc<Mutex<Block>>) -> Result<bool, Error> {
+ let mut block = block.lock().await;
+ block.full_text = match value.map(|v| (v * 100_f64) as u32) {
+ Some(v @ 66..) => format!(" 󰕾 {v}% "),
+ Some(v @ 33..) => format!(" 󰖀 {v}% "),
+ Some(v @ 0..) => format!(" 󰕿 {v}% "),
+ None => " ".to_string(),
+ };
+
+ Ok(true)
+ }
+}
+
+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, proxy.volume().await) {
+ (4, Ok(v)) if proxy.can_control().await? => proxy.set_volume(v + 0.05).await?,
+ (5, Ok(v)) if proxy.can_control().await? => proxy.set_volume(v - 0.05).await?,
+ _ => (),
+ }
+
+ Ok(())
+ }
+}