use std::sync::Arc; use i3blocks::{ 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> { i3blocks::run::(Default::default()) .await .map_err(Into::into) } pub struct Previous; impl Component for Previous { const NAME: &'static str = "previous"; type Updater = Self; type Colorer = PlaybackStatus; type Handler = Self; } impl Update for Previous { type Value = bool; async fn listen(tx: Sender, 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>) -> Result { let mut block = block.lock().await; block.full_text = value.then_some(" 󰒮 ".into()).unwrap_or_default(); Ok(true) } } impl Button for Previous { 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_previous().await? => proxy.previous().await?, 3 if proxy.can_seek().await? => proxy.seek(-5000).await?, _ => {} } Ok(()) } }