diff --git a/apps/notifications/Cargo.toml b/apps/notifications/Cargo.toml index 5f56a81..615470b 100644 --- a/apps/notifications/Cargo.toml +++ b/apps/notifications/Cargo.toml @@ -3,7 +3,17 @@ name = "canary-notifications" version = "0.1.0" edition = "2021" +[[bin]] +name = "canary-notifications" +path = "src/main.rs" +required-features = ["bin"] + [dependencies] -canary-magpie = { path = "../magpie" } -smol = "1.2" -zbus = "3.5" +canary-magpie = { path = "../magpie", optional = true, features = ["async"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +smol = { version = "1.2", optional = true } +zbus = { version = "3.5", optional = true } + +[features] +bin = ["dep:canary-magpie", "dep:smol", "dep:zbus"] diff --git a/apps/notifications/src/lib.rs b/apps/notifications/src/lib.rs new file mode 100644 index 0000000..fb0ac41 --- /dev/null +++ b/apps/notifications/src/lib.rs @@ -0,0 +1,27 @@ +// Copyright (c) 2022 Marceline Cramer +// SPDX-License-Identifier: AGPL-3.0-or-later + +use serde::{Deserialize, Serialize}; + +pub use serde; +pub use serde_json; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Contents { + /// The optional name of the application sending the notification. + pub app_name: Option, + + /// The summary text briefly describing the notification. + pub summary: String, + + /// The optional detailed body text. + pub body: Option, + + /// The timeout time in milliseconds since the display of the notification + /// at which the notification should automatically close. + pub timeout: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(tag = "kind")] +pub enum OutMsg {} diff --git a/apps/notifications/src/main.rs b/apps/notifications/src/main.rs index dd59530..939c2c3 100644 --- a/apps/notifications/src/main.rs +++ b/apps/notifications/src/main.rs @@ -1,14 +1,18 @@ use std::collections::HashMap; use std::future::pending; +use std::path::PathBuf; use canary_magpie::protocol::*; +use canary_notifications::Contents; use smol::net::unix::UnixStream; use zbus::{dbus_interface, zvariant::Value, ConnectionBuilder, SignalContext}; pub type MagpieClient = ClientMessenger; pub struct Notifications { + module_path: PathBuf, magpie: MagpieClient, + next_id: u32, } #[dbus_interface(name = "org.freedesktop.Notifications")] @@ -30,19 +34,40 @@ impl Notifications { )) } - fn notify( - &self, + async fn notify( + &mut self, app_name: String, replaces_id: u32, app_icon: String, summary: String, body: String, actions: Vec, - hints: HashMap, - expire_timeout: i32, + hints: HashMap>, + timeout: i32, ) -> u32 { - println!("{}: {}", summary, body); - 0 + let contents = Contents { + app_name: Some(app_name).filter(String::is_empty), + summary, + body: Some(body).filter(String::is_empty), + timeout: Some(timeout).filter(|t| *t == 0), + }; + + let id = self.next_id; + self.next_id += 1; + + let msg = CreatePanel { + id, + protocol: "tebibyte-media.desktop.notification".to_string(), + script: self.module_path.to_owned(), + init_msg: serde_json::to_vec(&contents).unwrap(), + }; + + self.magpie + .send_async(&MagpieServerMsg::CreatePanel(msg)) + .await + .unwrap(); + + id } fn close_notification(&self, id: u32) {} @@ -60,11 +85,23 @@ impl Notifications { } pub fn main() { + let args: Vec = std::env::args().collect(); + let module_path = args + .get(1) + .expect("Please pass a path to a Canary script!") + .to_owned() + .into(); + smol::block_on(async { let sock_path = find_socket(); let socket = UnixStream::connect(sock_path).await.unwrap(); let magpie = MagpieClient::new(socket); - let notifications = Notifications { magpie }; + + let notifications = Notifications { + magpie, + next_id: 0, + module_path, + }; let _ = ConnectionBuilder::session() .unwrap()