Files
tauri-plugins-workspace/plugins/notification/src/commands.rs
T
46381516b7 feat(notification): report actions on desktop (#3671)
* feat(notification): report actions on desktop

A click on a notification (tap) or on one of the actions of its action
type now reaches the JavaScript onAction listeners on desktop, and the
new Rust Notification::on_action on every platform. On Linux and the
BSDs the click comes from the notification server's ActionInvoked
signal; on Windows and macOS from notify-rust's wait_for_response,
which needs notify-rust 4.18.

register_action_types, remove_active (Linux and the BSDs) and the
listener commands are implemented for desktop, so they no longer fail
with "command not found".

The api example sends a notification with two actions and shows the
action it hears.

Closes #2150, closes #1903.

* fix(notification): complete desktop action API

* cleanup

---------

Co-authored-by: Haex <hexxx@ok.de>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2026-10-08 14:14:19 -03:00

96 lines
2.6 KiB
Rust

// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use tauri::{AppHandle, Runtime, State, command, plugin::PermissionState};
use crate::{Notification, NotificationData, Result};
#[command]
pub(crate) async fn is_permission_granted<R: Runtime>(
_app: AppHandle<R>,
notification: State<'_, Notification<R>>,
) -> Result<Option<bool>> {
let state = notification.permission_state()?;
match state {
PermissionState::Granted => Ok(Some(true)),
PermissionState::Denied => Ok(Some(false)),
PermissionState::Prompt | PermissionState::PromptWithRationale => Ok(None),
}
}
#[command]
pub(crate) async fn request_permission<R: Runtime>(
_app: AppHandle<R>,
notification: State<'_, Notification<R>>,
) -> Result<PermissionState> {
notification.request_permission()
}
#[command]
pub(crate) async fn notify<R: Runtime>(
_app: AppHandle<R>,
notification: State<'_, Notification<R>>,
options: NotificationData,
) -> Result<()> {
let mut builder = notification.builder();
builder.data = options;
builder.show()
}
// The commands below are implemented by the Kotlin and Swift plugins on mobile.
#[cfg(desktop)]
#[command]
pub(crate) async fn register_action_types<R: Runtime>(
_app: AppHandle<R>,
notification: State<'_, Notification<R>>,
types: Vec<crate::ActionType>,
) -> Result<()> {
notification.register_action_types(types)
}
/// A notification of `remove_active`, as the JavaScript API sends it.
#[cfg(desktop)]
#[derive(serde::Deserialize)]
pub(crate) struct ActiveId {
id: i32,
}
#[cfg(desktop)]
#[command]
pub(crate) async fn remove_active<R: Runtime>(
_app: AppHandle<R>,
notification: State<'_, Notification<R>>,
notifications: Option<Vec<ActiveId>>,
) -> Result<()> {
match notifications {
Some(notifications) => {
notification.remove_active(notifications.into_iter().map(|n| n.id).collect())
}
None => notification.remove_all_active(),
}
}
#[cfg(desktop)]
#[command]
pub(crate) fn register_listener<R: Runtime>(
webview: tauri::Webview<R>,
notification: State<'_, Notification<R>>,
event: String,
handler: tauri::ipc::Channel<serde_json::Value>,
) {
notification.register_listener(event, handler, &webview);
}
#[cfg(desktop)]
#[command]
pub(crate) fn remove_listener<R: Runtime>(
_app: AppHandle<R>,
notification: State<'_, Notification<R>>,
event: String,
channel_id: u32,
) {
notification.remove_listener(&event, channel_id);
}