diff options
Diffstat (limited to 'src/component/next.rs')
-rw-r--r-- | src/component/next.rs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/component/next.rs b/src/component/next.rs new file mode 100644 index 0000000..567f5f2 --- /dev/null +++ b/src/component/next.rs @@ -0,0 +1,65 @@ +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 Next; + +impl Component for Next { + const NAME: &'static str = "next"; + type Updater = Self; + type Colorer = PlaybackStatus; + type Handler = Self; +} + +impl Update for Next { + type Value = bool; + + async fn listen(tx: Sender<Self::Value>, proxy: PlayerProxy<'_>) -> Result<(), Error> { + use futures_util::StreamExt; + + tx.send(proxy.can_go_previous().await?).await?; + let mut stream = proxy.receive_can_go_previous_changed().await; + while let Some(signal) = stream.next().await { + if let Ok(value) = signal.get().await { + tx.send(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 = value.then_some(" ".into()).unwrap_or_default(); + Ok(true) + } +} + +impl Button for Next { + 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 { + 1 if proxy.can_go_next().await? => proxy.next().await?, + 3 if proxy.can_seek().await? => proxy.seek(5000).await?, + _ => {} + } + + Ok(()) + } +} |