From 961d4568f87e00757cc1730dc515cf3c88eaf2d3 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 4 Mar 2023 17:55:33 +0900 Subject: [PATCH] Add listen's clear option --- Cargo.toml | 2 +- src/client.rs | 45 ++++++++++++++++++++++++++++++++------------- src/main.rs | 8 +++----- src/notification.rs | 4 ++-- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0a86b4d..7020c56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -clap = { version = "4.1.8", features = ["derive"] } +clap = { version = "4.1.8", features = ["derive", "unstable-replace"] } serde = "1.0.152" serde_json = "1.0.93" tokio = { version = "1", features = ["full"] } diff --git a/src/client.rs b/src/client.rs index 666d2cd..8c162b8 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,3 +1,9 @@ +use std::{ + future::{self, Future}, + time::Duration, pin::Pin, +}; + +use tokio::{select, time::{sleep, Sleep}}; use zbus::{dbus_proxy, export::ordered_stream::OrderedStreamExt, Connection, Result}; use crate::{notification::Notification, Format}; @@ -14,23 +20,36 @@ trait Manager { fn new_notification(&self, notif: Notification) -> fdo::Result; } -pub async fn listen(format: Format) -> Result<()> { +pub async fn listen(format: Format, clear: bool) -> Result<()> { let connection = Connection::session().await?; let manager = ManagerProxy::new(&connection).await?; - // let props = zbus::fdo::PropertiesProxy::builder(&connection) - // .destination("org.freedesktop.Notifications")? - // .path("/org/freedesktop/Notifications")? - // .build() - // .await?; let mut stream = manager.receive_new_notification().await?; - while let Some(notif) = stream.next().await { - let notif = notif.args()?.notif; - match format { - Format::Json => println!("{}", serde_json::to_string(¬if).unwrap()), - Format::Short => println!("{}: {}", notif.summary, notif.body), - }; - } + let mut clearer: Sleep; + let mut clear_running = false; + loop { + clearer = sleep(Duration::from_secs(8)); + select! { + Some(notif) = stream.next() => { + let notif = notif.args()?.notif; + match format { + Format::Json => println!("{}", serde_json::to_string(¬if).unwrap()), + Format::Short => println!("{}: {}", notif.summary, notif.body), + }; + if clear { + clear_running = true; + } + }, + () = clearer, if clear_running => { + match format { + Format::Short => println!(""), + Format::Json => println!("{}", serde_json::to_string(&Notification::default()).unwrap()), + } + clear_running = false; + }, + else => { break } + } + } Ok(()) } diff --git a/src/main.rs b/src/main.rs index 1d4c05e..274679b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,8 @@ use zbus::Result; #[derive(Parser)] #[command(author, version, about, long_about = None)] +// TODO: Fix this replace that does not work. +#[command(replace("-j", ["--format json"]))] struct Args { #[command(subcommand)] command: Command, @@ -24,10 +26,6 @@ enum Command { #[arg(short, long, default_value = "short")] format: Format, - /// Use json instead of plain-text - #[arg(short, long)] - json: bool, - /// Print an empty line/json object when the notification should clear. #[arg(short, long)] clear: bool, @@ -56,6 +54,6 @@ async fn main() -> Result<()> { match cli.command { Command::Daemon => NotifyManager::new().start().await, Command::List { format } => client::list(format).await, - Command::Listen { format, .. } => client::listen(format).await, + Command::Listen { format, clear } => client::listen(format, clear).await, } } diff --git a/src/notification.rs b/src/notification.rs index 8b3a2ae..9c25579 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use zbus::zvariant::{DeserializeDict, SerializeDict, Type}; -#[derive(Debug, Deserialize, Serialize, Type)] +#[derive(Debug, Deserialize, Serialize, Type, Default)] pub struct Notification { pub id: u32, pub app_name: String, @@ -12,7 +12,7 @@ pub struct Notification { pub hints: Hints, } -#[derive(Debug, DeserializeDict, SerializeDict, Type)] +#[derive(Debug, DeserializeDict, SerializeDict, Type, Default)] #[zvariant(signature = "dict")] pub struct Hints { category: Option,