canary-rs/apps/notifications/src/main.rs

119 lines
3.2 KiB
Rust

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<UnixStream>;
pub struct Notifications {
module_path: PathBuf,
magpie: MagpieClient,
next_id: u32,
}
#[dbus_interface(name = "org.freedesktop.Notifications")]
impl Notifications {
fn get_capabilities(&self) -> Vec<String> {
vec!["body", "body-markup", "actions", "icon-static"]
.into_iter()
.map(ToString::to_string)
.collect()
}
#[dbus_interface(out_args("name", "vendor", "version", "spec_version"))]
fn get_server_information(&self) -> zbus::fdo::Result<(String, String, String, String)> {
Ok((
"canary-notifications".to_string(),
"Canary Development Team".to_string(),
"0.1.0".to_string(),
"1.2".to_string(),
))
}
async fn notify(
&mut self,
app_name: String,
replaces_id: u32,
app_icon: String,
summary: String,
body: String,
actions: Vec<String>,
hints: HashMap<String, Value<'_>>,
timeout: i32,
) -> u32 {
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) {}
#[dbus_interface(signal)]
async fn notification_closed(ctx: &SignalContext<'_>, id: u32, reason: u32)
-> zbus::Result<()>;
#[dbus_interface(signal)]
async fn action_invoked(
ctx: &SignalContext<'_>,
id: u32,
action_key: String,
) -> zbus::Result<()>;
}
pub fn main() {
let args: Vec<String> = 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,
next_id: 0,
module_path,
};
let _ = ConnectionBuilder::session()
.unwrap()
.name("org.freedesktop.Notifications")
.unwrap()
.serve_at("/org/freedesktop/Notifications", notifications)
.unwrap()
.build()
.await
.unwrap();
pending::<()>().await;
});
}