From aec31b7e88fdd3b6a19e5474b57098eb1b41823f Mon Sep 17 00:00:00 2001 From: Jonas Kruckenberg Date: Tue, 15 Nov 2022 15:57:02 +0100 Subject: [PATCH 1/2] feat: add notification module --- Cargo.lock | 1 + Cargo.toml | 4 +- README.md | 2 +- examples/test/src-tauri/src/main.rs | 2 +- examples/test/src/main.rs | 6 ++- examples/test/src/notification.rs | 28 ++++++++++ src/lib.rs | 2 + src/notification.rs | 84 +++++++++++++++++++++++++++++ 8 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 examples/test/src/notification.rs create mode 100644 src/notification.rs diff --git a/Cargo.lock b/Cargo.lock index 2a2a132..d57e8e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2963,6 +2963,7 @@ name = "tauri-sys" version = "0.1.0" dependencies = [ "js-sys", + "log", "semver 1.0.14", "serde", "serde-wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index c496dd2..fd2c548 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ wasm-bindgen-futures = "0.4.32" url = { version = "2.3.1", optional = true, features = ["serde"] } thiserror = "1.0.37" semver = { version = "1.0.14", optional = true, features = ["serde"] } +log = "0.4.17" [dev-dependencies] wasm-bindgen-test = "0.3.33" @@ -24,7 +25,7 @@ tauri-sys = { path = ".", features = ["all"] } all-features = true [features] -all = ["app", "clipboard", "event", "mocks", "tauri", "window", "process", "dialog"] +all = ["app", "clipboard", "event", "mocks", "tauri", "window", "process", "dialog", "notification"] app = ["dep:semver"] clipboard = [] dialog = [] @@ -33,6 +34,7 @@ mocks = [] tauri = ["dep:url"] window = [] process = [] +notification = [] [workspace] members = ["examples/test", "examples/test/src-tauri"] diff --git a/README.md b/README.md index aa9c715..af420e2 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ These API bindings are not completely on-par with `@tauri-apps/api` yet, but her - [ ] `notification` - [ ] `os` - [ ] `path` -- [ ] `process` +- [x] `process` - [ ] `shell` - [x] `tauri` - [ ] `updater` diff --git a/examples/test/src-tauri/src/main.rs b/examples/test/src-tauri/src/main.rs index afccf34..e5eeef1 100644 --- a/examples/test/src-tauri/src/main.rs +++ b/examples/test/src-tauri/src/main.rs @@ -5,7 +5,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use tauri::{Manager, State}; +use tauri::{Manager, State, api::notification::Notification}; struct Received(AtomicBool); // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command diff --git a/examples/test/src/main.rs b/examples/test/src/main.rs index e4ff326..d2a25d5 100644 --- a/examples/test/src/main.rs +++ b/examples/test/src/main.rs @@ -3,6 +3,7 @@ mod clipboard; mod event; mod window; mod dialog; +mod notification; extern crate console_error_panic_hook; use std::future::Future; @@ -153,7 +154,10 @@ fn main() { InteractiveTest(name="dialog::pick_folder",test=dialog::pick_folder()) InteractiveTest(name="dialog::pick_folders",test=dialog::pick_folders()) InteractiveTest(name="dialog::save",test=dialog::save()) - + Test(name="notification::is_permission_granted",test=notification::is_permission_granted()) + Test(name="notification::request_permission",test=notification::request_permission()) + InteractiveTest(name="notification::show_notification",test=notification::show_notification()) + // Test(name="window::WebviewWindow::new",test=window::create_window()) Terminate diff --git a/examples/test/src/notification.rs b/examples/test/src/notification.rs new file mode 100644 index 0000000..1ce9dfd --- /dev/null +++ b/examples/test/src/notification.rs @@ -0,0 +1,28 @@ +use anyhow::ensure; +use tauri_sys::notification::{self, Permission}; + +pub async fn is_permission_granted() -> anyhow::Result<()> { + let granted = notification::is_permission_granted().await?; + + ensure!(granted); + + Ok(()) +} + +pub async fn request_permission() -> anyhow::Result<()> { + let permission = notification::request_permission().await?; + + ensure!(permission == Permission::Granted); + + Ok(()) +} + +pub async fn show_notification() -> anyhow::Result<()> { + let mut n = notification::Notification::default(); + n.set_title("TAURI"); + n.set_body("Tauri is awesome!"); + + n.show()?; + + Ok(()) +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 64c7a40..ccc3459 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,8 @@ pub mod process; pub mod tauri; #[cfg(feature = "window")] pub mod window; +#[cfg(feature = "notification")] +pub mod notification; #[derive(Debug, thiserror::Error)] pub enum Error { diff --git a/src/notification.rs b/src/notification.rs new file mode 100644 index 0000000..7391b88 --- /dev/null +++ b/src/notification.rs @@ -0,0 +1,84 @@ +use log::debug; +use serde::{Deserialize, Serialize}; +use wasm_bindgen::JsValue; + +pub async fn is_permission_granted() -> crate::Result { + let raw = inner::isPermissionGranted().await?; + + Ok(serde_wasm_bindgen::from_value(raw)?) +} + +pub async fn request_permission() -> crate::Result { + let raw = inner::requestPermission().await?; + + Ok(serde_wasm_bindgen::from_value(raw)?) +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum Permission { + #[default] + Default, + Granted, + Denied, +} + +impl<'de> Deserialize<'de> for Permission { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + match String::deserialize(deserializer)?.as_str() { + "default" => Ok(Permission::Default), + "granted" => Ok(Permission::Granted), + "denied" => Ok(Permission::Denied), + _ => Err(serde::de::Error::custom( + "expected one of default, granted, denied", + )), + } + } +} + +#[derive(Debug, Default, Serialize)] +pub struct Notification<'a> { + body: Option<&'a str>, + title: Option<&'a str>, + icon: Option<&'a str> +} + +impl<'a> Notification<'a> { + pub fn new() -> Self { + Self::default() + } + + pub fn set_title(&mut self, title: &'a str) { + self.title = Some(title); + } + + pub fn set_body(&mut self, body: &'a str) { + self.body = Some(body); + } + + pub fn set_icon(&mut self, icon: &'a str) { + self.icon = Some(icon); + } + + pub fn show(&self) -> crate::Result<()> { + inner::sendNotification(serde_wasm_bindgen::to_value(&self)?)?; + + Ok(()) + } +} + +mod inner { + use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; + + #[wasm_bindgen(module = "/src/notification.js")] + extern "C" { + #[wasm_bindgen(catch)] + pub async fn isPermissionGranted() -> Result; + #[wasm_bindgen(catch)] + pub async fn requestPermission() -> Result; + #[wasm_bindgen(catch)] + pub fn sendNotification(notification: JsValue) -> Result<(), JsValue>; + } +} From 0302f250438b57eecf989137249939657c4c4da7 Mon Sep 17 00:00:00 2001 From: Jonas Kruckenberg Date: Tue, 15 Nov 2022 15:57:52 +0100 Subject: [PATCH 2/2] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af420e2..bbec34e 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ These API bindings are not completely on-par with `@tauri-apps/api` yet, but her - [ ] `global_shortcut` - [ ] `http` - [x] `mocks` -- [ ] `notification` +- [x] `notification` - [ ] `os` - [ ] `path` - [x] `process`