mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-09-22 21:30:44 +02:00
chore: update documentation
This commit is contained in:
@@ -35,7 +35,7 @@ interface Options {
|
||||
*/
|
||||
channelId?: string
|
||||
/**
|
||||
* Notification title.
|
||||
* The title displayed on the notification.
|
||||
*/
|
||||
title: string
|
||||
/**
|
||||
@@ -139,11 +139,28 @@ interface Options {
|
||||
number?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of date fields a scheduled notification must match to be delivered.
|
||||
*
|
||||
* Fields that are not set match any value, so the notification fires on every date
|
||||
* whose remaining components match.
|
||||
*/
|
||||
interface ScheduleInterval {
|
||||
/**
|
||||
* The year the notification fires on.
|
||||
*/
|
||||
year?: number
|
||||
/**
|
||||
* The month of the year the notification fires on.
|
||||
*/
|
||||
month?: number
|
||||
/**
|
||||
* The day of the month the notification fires on.
|
||||
*/
|
||||
day?: number
|
||||
/**
|
||||
* The day of the week the notification fires on.
|
||||
*
|
||||
* 1 - Sunday
|
||||
* 2 - Monday
|
||||
* 3 - Tuesday
|
||||
@@ -153,26 +170,77 @@ interface ScheduleInterval {
|
||||
* 7 - Saturday
|
||||
*/
|
||||
weekday?: number
|
||||
/**
|
||||
* The hour of the day the notification fires on, in the 24-hour clock.
|
||||
*/
|
||||
hour?: number
|
||||
/**
|
||||
* The minute of the hour the notification fires on.
|
||||
*/
|
||||
minute?: number
|
||||
/**
|
||||
* The second of the minute the notification fires on.
|
||||
*/
|
||||
second?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* The unit of the repeating interval used by {@link Schedule.every}.
|
||||
*/
|
||||
enum ScheduleEvery {
|
||||
/**
|
||||
* The notification repeats every year.
|
||||
*
|
||||
* On Android a year is approximated as 52 weeks.
|
||||
*/
|
||||
Year = 'year',
|
||||
/**
|
||||
* The notification repeats every month.
|
||||
*
|
||||
* On Android a month is approximated as 30 days.
|
||||
*/
|
||||
Month = 'month',
|
||||
/**
|
||||
* The notification repeats every two weeks.
|
||||
*/
|
||||
TwoWeeks = 'twoWeeks',
|
||||
/**
|
||||
* The notification repeats every week.
|
||||
*/
|
||||
Week = 'week',
|
||||
/**
|
||||
* The notification repeats every day.
|
||||
*/
|
||||
Day = 'day',
|
||||
/**
|
||||
* The notification repeats every hour.
|
||||
*/
|
||||
Hour = 'hour',
|
||||
/**
|
||||
* The notification repeats every minute.
|
||||
*/
|
||||
Minute = 'minute',
|
||||
/**
|
||||
* Not supported on iOS.
|
||||
* The notification repeats every second.
|
||||
*
|
||||
* Not supported on iOS, where repeating triggers must be at least a minute apart.
|
||||
*/
|
||||
Second = 'second'
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines when a scheduled notification is delivered.
|
||||
*
|
||||
* Build one with the static {@link Schedule.at}, {@link Schedule.interval} and
|
||||
* {@link Schedule.every} helpers, then pass it to the `schedule` option of a notification.
|
||||
* Scheduling is only supported on mobile; desktop notifications are always shown immediately.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Schedule {
|
||||
/**
|
||||
* Set when the notification fires at a fixed date and time.
|
||||
*/
|
||||
at:
|
||||
| {
|
||||
date: Date
|
||||
@@ -181,6 +249,9 @@ class Schedule {
|
||||
}
|
||||
| undefined
|
||||
|
||||
/**
|
||||
* Set when the notification fires whenever the current date matches the given fields.
|
||||
*/
|
||||
interval:
|
||||
| {
|
||||
interval: ScheduleInterval
|
||||
@@ -188,6 +259,9 @@ class Schedule {
|
||||
}
|
||||
| undefined
|
||||
|
||||
/**
|
||||
* Set when the notification repeats on a fixed interval.
|
||||
*/
|
||||
every:
|
||||
| {
|
||||
interval: ScheduleEvery
|
||||
@@ -196,6 +270,22 @@ class Schedule {
|
||||
}
|
||||
| undefined
|
||||
|
||||
/**
|
||||
* Creates a schedule that fires the notification at the given date and time.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { Schedule, sendNotification } from '@tauri-apps/plugin-notification';
|
||||
* const schedule = Schedule.at(new Date(Date.now() + 60 * 1000));
|
||||
* sendNotification({ title: 'Tauri', body: 'One minute later', schedule });
|
||||
* ```
|
||||
*
|
||||
* @param date The date and time the notification fires at. It must be in the future.
|
||||
* @param repeating Whether the notification keeps repeating, using the duration between the moment it is scheduled and `date` as the interval. The interval must be at least one minute on iOS.
|
||||
* @param allowWhileIdle Whether the notification is allowed to fire while the device is in low-power idle (Doze) mode. Android only.
|
||||
*
|
||||
* @returns A schedule that can be assigned to the `schedule` option of a notification.
|
||||
*/
|
||||
static at(date: Date, repeating = false, allowWhileIdle = false): Schedule {
|
||||
return {
|
||||
at: { date, repeating, allowWhileIdle },
|
||||
@@ -204,6 +294,23 @@ class Schedule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a schedule that fires the notification whenever the current date matches
|
||||
* every field set on the given interval.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { Schedule, sendNotification } from '@tauri-apps/plugin-notification';
|
||||
* // fires every day at 9:00
|
||||
* const schedule = Schedule.interval({ hour: 9, minute: 0 });
|
||||
* sendNotification({ title: 'Tauri', body: 'Good morning', schedule });
|
||||
* ```
|
||||
*
|
||||
* @param interval The date fields the current date must match for the notification to fire.
|
||||
* @param allowWhileIdle Whether the notification is allowed to fire while the device is in low-power idle (Doze) mode. Android only.
|
||||
*
|
||||
* @returns A schedule that can be assigned to the `schedule` option of a notification.
|
||||
*/
|
||||
static interval(
|
||||
interval: ScheduleInterval,
|
||||
allowWhileIdle = false
|
||||
@@ -215,6 +322,22 @@ class Schedule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a schedule that repeatedly fires the notification, once every `count` interval units.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { Schedule, ScheduleEvery, sendNotification } from '@tauri-apps/plugin-notification';
|
||||
* const schedule = Schedule.every(ScheduleEvery.Hour, 2);
|
||||
* sendNotification({ title: 'Tauri', body: 'Every two hours', schedule });
|
||||
* ```
|
||||
*
|
||||
* @param kind The unit of the repeating interval.
|
||||
* @param count How many interval units elapse between each notification.
|
||||
* @param allowWhileIdle Whether the notification is allowed to fire while the device is in low-power idle (Doze) mode. Android only.
|
||||
*
|
||||
* @returns A schedule that can be assigned to the `schedule` option of a notification.
|
||||
*/
|
||||
static every(
|
||||
kind: ScheduleEvery,
|
||||
count: number,
|
||||
@@ -238,17 +361,53 @@ interface Attachment {
|
||||
url: string
|
||||
}
|
||||
|
||||
/**
|
||||
* A button the user can tap on a notification, belonging to an {@link ActionType}.
|
||||
*
|
||||
* Only used on mobile. On Android only the identifier, the title and the input flag are used.
|
||||
*/
|
||||
interface Action {
|
||||
/**
|
||||
* The identifier of this action, reported back when the user triggers it.
|
||||
*/
|
||||
id: string
|
||||
/**
|
||||
* The text displayed on the action button.
|
||||
*/
|
||||
title: string
|
||||
/**
|
||||
* Whether the device must be unlocked for the action to run. iOS only.
|
||||
*/
|
||||
requiresAuthentication?: boolean
|
||||
/**
|
||||
* Whether the app is brought to the foreground when the action is triggered. iOS only.
|
||||
*/
|
||||
foreground?: boolean
|
||||
/**
|
||||
* Whether the action is displayed as destructive, usually in red. iOS only.
|
||||
*/
|
||||
destructive?: boolean
|
||||
/**
|
||||
* Whether triggering the action lets the user type a text response.
|
||||
*/
|
||||
input?: boolean
|
||||
/**
|
||||
* The text displayed on the button that submits the text input. iOS only.
|
||||
*/
|
||||
inputButtonTitle?: string
|
||||
/**
|
||||
* The placeholder displayed on the empty text input field. iOS only.
|
||||
*/
|
||||
inputPlaceholder?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* A group of {@link Action}s a notification can display, referenced by the
|
||||
* `actionTypeId` option of a notification.
|
||||
*
|
||||
* Register it with {@link registerActionTypes} before sending a notification that uses it.
|
||||
* Only used on mobile.
|
||||
*/
|
||||
interface ActionType {
|
||||
/**
|
||||
* The identifier of this action type
|
||||
@@ -258,58 +417,206 @@ interface ActionType {
|
||||
* The list of associated actions
|
||||
*/
|
||||
actions: Action[]
|
||||
/**
|
||||
* The placeholder shown instead of the notification body when previews are hidden. iOS only.
|
||||
*/
|
||||
hiddenPreviewsBodyPlaceholder?: string
|
||||
/**
|
||||
* Whether the app is notified when the user dismisses the notification. iOS only.
|
||||
*/
|
||||
customDismissAction?: boolean
|
||||
/**
|
||||
* Whether the notification can be displayed in a CarPlay environment. iOS only.
|
||||
*/
|
||||
allowInCarPlay?: boolean
|
||||
/**
|
||||
* Whether the notification title is shown even when previews are hidden. iOS only.
|
||||
*/
|
||||
hiddenPreviewsShowTitle?: boolean
|
||||
/**
|
||||
* Whether the notification subtitle is shown even when previews are hidden. iOS only.
|
||||
*/
|
||||
hiddenPreviewsShowSubtitle?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* A notification that was scheduled and has not been delivered yet.
|
||||
*
|
||||
* Returned by {@link pending}, which is only supported on mobile.
|
||||
*/
|
||||
interface PendingNotification {
|
||||
/**
|
||||
* The identifier of the notification.
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* The title of the notification, if it was set.
|
||||
*/
|
||||
title?: string
|
||||
/**
|
||||
* The body of the notification, if it was set.
|
||||
*/
|
||||
body?: string
|
||||
/**
|
||||
* The schedule that determines when the notification is delivered.
|
||||
*/
|
||||
schedule: Schedule
|
||||
}
|
||||
|
||||
/**
|
||||
* A notification that was delivered and is still visible in the notification center.
|
||||
*
|
||||
* Returned by {@link active}, which is only supported on mobile. Which fields are
|
||||
* populated depends on the platform, since Android and iOS expose different
|
||||
* information about delivered notifications.
|
||||
*/
|
||||
interface ActiveNotification {
|
||||
/**
|
||||
* The identifier of the notification.
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* The tag the notification was posted with. Android only.
|
||||
*/
|
||||
tag?: string
|
||||
/**
|
||||
* The title of the notification, if it was set.
|
||||
*/
|
||||
title?: string
|
||||
/**
|
||||
* The body of the notification, if it was set.
|
||||
*/
|
||||
body?: string
|
||||
/**
|
||||
* The identifier of the group the notification belongs to. Android only.
|
||||
*/
|
||||
group?: string
|
||||
/**
|
||||
* Whether the notification is the summary of its group. Android only.
|
||||
*/
|
||||
groupSummary: boolean
|
||||
/**
|
||||
* The platform extras attached to the notification, as string values. Android only.
|
||||
*/
|
||||
data: Record<string, string>
|
||||
/**
|
||||
* The extra payload that was stored in the notification.
|
||||
*/
|
||||
extra: Record<string, unknown>
|
||||
/**
|
||||
* The attachments of the notification. iOS only.
|
||||
*/
|
||||
attachments: Attachment[]
|
||||
/**
|
||||
* The identifier of the action type the notification was registered with. iOS only.
|
||||
*/
|
||||
actionTypeId?: string
|
||||
/**
|
||||
* The schedule the notification was delivered with, if it was scheduled.
|
||||
*/
|
||||
schedule?: Schedule
|
||||
/**
|
||||
* The sound resource name of the notification. iOS only.
|
||||
*/
|
||||
sound?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* How much the notifications of a {@link Channel} interrupt the user.
|
||||
*
|
||||
* It maps to the Android `NotificationManager.IMPORTANCE_*` constants and is only used on Android.
|
||||
*/
|
||||
enum Importance {
|
||||
/**
|
||||
* The notifications are not shown.
|
||||
*/
|
||||
None = 0,
|
||||
/**
|
||||
* The notifications are only shown in the shade, below the fold, without a status bar icon.
|
||||
*/
|
||||
Min,
|
||||
/**
|
||||
* The notifications are shown without a sound.
|
||||
*/
|
||||
Low,
|
||||
/**
|
||||
* The notifications are shown and make a sound.
|
||||
*
|
||||
* This is the value used when the channel does not define an importance.
|
||||
*/
|
||||
Default,
|
||||
/**
|
||||
* The notifications are shown, make a sound and pop up as a heads-up notification.
|
||||
*/
|
||||
High
|
||||
}
|
||||
|
||||
/**
|
||||
* How much of a notification is shown on the lock screen.
|
||||
*
|
||||
* It maps to the Android `Notification.VISIBILITY_*` constants and is only used on Android.
|
||||
*/
|
||||
enum Visibility {
|
||||
/**
|
||||
* The notification is not shown on the lock screen at all.
|
||||
*/
|
||||
Secret = -1,
|
||||
/**
|
||||
* The notification is shown on the lock screen with its sensitive content hidden.
|
||||
*
|
||||
* This is the value used when the channel does not define a visibility.
|
||||
*/
|
||||
Private,
|
||||
/**
|
||||
* The notification is shown in full on the lock screen.
|
||||
*/
|
||||
Public
|
||||
}
|
||||
|
||||
/**
|
||||
* A notification channel, the category users configure notification behavior on.
|
||||
*
|
||||
* Notifications reference a channel through their `channelId` option and are not delivered
|
||||
* when the channel does not exist. Channels are only supported on Android.
|
||||
*/
|
||||
interface Channel {
|
||||
/**
|
||||
* The identifier of this channel.
|
||||
*/
|
||||
id: string
|
||||
/**
|
||||
* The user visible name of this channel.
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* The user visible description of this channel.
|
||||
*/
|
||||
description?: string
|
||||
/**
|
||||
* The name of the sound resource played by the notifications of this channel.
|
||||
*
|
||||
* The resource must be placed in the app's `res/raw` folder.
|
||||
*/
|
||||
sound?: string
|
||||
/**
|
||||
* Whether the notifications of this channel blink the device light.
|
||||
*/
|
||||
lights?: boolean
|
||||
/**
|
||||
* The color of the device light, as a color string such as `#ff0000`.
|
||||
*/
|
||||
lightColor?: string
|
||||
/**
|
||||
* Whether the notifications of this channel vibrate the device.
|
||||
*/
|
||||
vibration?: boolean
|
||||
/**
|
||||
* How much the notifications of this channel interrupt the user.
|
||||
*/
|
||||
importance?: Importance
|
||||
/**
|
||||
* How much of the notifications of this channel is shown on the lock screen.
|
||||
*/
|
||||
visibility?: Visibility
|
||||
}
|
||||
|
||||
@@ -321,6 +628,8 @@ interface Channel {
|
||||
* const permissionGranted = await isPermissionGranted();
|
||||
* ```
|
||||
*
|
||||
* @returns A promise resolving to whether the permission to send notifications is granted.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
async function isPermissionGranted(): Promise<boolean> {
|
||||
@@ -366,6 +675,8 @@ async function requestPermission(): Promise<NotificationPermission> {
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param options The notification content, or the notification title when a string is given.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function sendNotification(options: Options | string): void {
|
||||
@@ -391,6 +702,8 @@ function sendNotification(options: Options | string): void {
|
||||
* }])
|
||||
* ```
|
||||
*
|
||||
* @param types The action types to register.
|
||||
*
|
||||
* @returns A promise indicating the success or failure of the operation.
|
||||
*
|
||||
* @since 2.0.0
|
||||
@@ -425,6 +738,8 @@ async function pending(): Promise<PendingNotification[]> {
|
||||
* await cancel([-34234, 23432, 4311]);
|
||||
* ```
|
||||
*
|
||||
* @param notifications The identifiers of the pending notifications to cancel.
|
||||
*
|
||||
* @returns A promise indicating the success or failure of the operation.
|
||||
*
|
||||
* @since 2.0.0
|
||||
@@ -472,10 +787,12 @@ async function active(): Promise<ActiveNotification[]> {
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { cancel } from '@tauri-apps/plugin-notification';
|
||||
* await cancel([-34234, 23432, 4311])
|
||||
* import { removeActive } from '@tauri-apps/plugin-notification';
|
||||
* await removeActive([{ id: -34234 }, { id: 23432 }, { id: 4311 }])
|
||||
* ```
|
||||
*
|
||||
* @param notifications The active notifications to remove, identified by their id and, on Android, their optional tag.
|
||||
*
|
||||
* @returns A promise indicating the success or failure of the operation.
|
||||
*
|
||||
* @since 2.0.0
|
||||
@@ -519,6 +836,8 @@ async function removeAllActive(): Promise<void> {
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param channel The channel to create.
|
||||
*
|
||||
* @returns A promise indicating the success or failure of the operation.
|
||||
*
|
||||
* @since 2.0.0
|
||||
@@ -533,9 +852,11 @@ async function createChannel(channel: Channel): Promise<void> {
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { removeChannel } from '@tauri-apps/plugin-notification';
|
||||
* await removeChannel();
|
||||
* await removeChannel('new-messages');
|
||||
* ```
|
||||
*
|
||||
* @param id The identifier of the channel to remove.
|
||||
*
|
||||
* @returns A promise indicating the success or failure of the operation.
|
||||
*
|
||||
* @since 2.0.0
|
||||
@@ -561,12 +882,51 @@ async function channels(): Promise<Channel[]> {
|
||||
return await invoke('plugin:notification|listChannels')
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to notifications that are delivered while the app is running.
|
||||
*
|
||||
* Only emitted on mobile.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { onNotificationReceived } from '@tauri-apps/plugin-notification';
|
||||
* const unlisten = await onNotificationReceived((notification) => {
|
||||
* console.log(`received notification: ${notification.title}`);
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param cb The closure called with the notification that was delivered.
|
||||
*
|
||||
* @returns A promise resolving to a listener that can be used to stop listening for the event.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
async function onNotificationReceived(
|
||||
cb: (notification: Options) => void
|
||||
): Promise<PluginListener> {
|
||||
return await addPluginListener('notification', 'notification', cb)
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the actions the user performs on a notification.
|
||||
*
|
||||
* Only emitted on mobile, for notifications that reference an action type
|
||||
* registered with {@link registerActionTypes}.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { onAction } from '@tauri-apps/plugin-notification';
|
||||
* const unlisten = await onAction((notification) => {
|
||||
* console.log(`user acted on notification: ${notification.title}`);
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param cb The closure called with the notification the action was performed on.
|
||||
*
|
||||
* @returns A promise resolving to a listener that can be used to stop listening for the event.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
async function onAction(
|
||||
cb: (notification: Options) => void
|
||||
): Promise<PluginListener> {
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* Webview script injected by the notification plugin.
|
||||
*
|
||||
* It replaces `window.Notification` with an implementation backed by the plugin, so the
|
||||
* standard Notification Web API sends OS notifications, and keeps
|
||||
* `window.Notification.permission` and `window.Notification.requestPermission` in sync
|
||||
* with the permission state reported by the plugin.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import type { PermissionState } from '@tauri-apps/api/core'
|
||||
import type { Options } from './index'
|
||||
|
||||
@@ -10,6 +10,7 @@ use tauri::{
|
||||
|
||||
use crate::NotificationBuilder;
|
||||
|
||||
/// Initializes the desktop implementation of the notification APIs.
|
||||
pub fn init<R: Runtime, C: DeserializeOwned>(
|
||||
app: &AppHandle<R>,
|
||||
_api: PluginApi<R, C>,
|
||||
@@ -23,6 +24,22 @@ pub fn init<R: Runtime, C: DeserializeOwned>(
|
||||
pub struct Notification<R: Runtime>(AppHandle<R>);
|
||||
|
||||
impl<R: Runtime> crate::NotificationBuilder<R> {
|
||||
/// Shows the notification.
|
||||
///
|
||||
/// When no title was set with [`Self::title`], the `productName` from the Tauri configuration is used instead.
|
||||
/// Only the title, body, icon and sound of the notification are used on desktop;
|
||||
/// the scheduling, grouping and action related options are ignored.
|
||||
///
|
||||
/// The notification is dispatched on a background task, so this returns as soon as the payload is prepared.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error when the notification could not be prepared,
|
||||
/// e.g. when the path of the running executable cannot be resolved on Windows.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows**: Not supported on Windows 7 unless the `windows7-compat` Cargo feature is enabled.
|
||||
pub fn show(self) -> crate::Result<()> {
|
||||
let mut notification = imp::Notification::new(self.app.config().identifier.clone());
|
||||
|
||||
@@ -54,14 +71,38 @@ impl<R: Runtime> crate::NotificationBuilder<R> {
|
||||
}
|
||||
|
||||
impl<R: Runtime> Notification<R> {
|
||||
/// Creates a new builder for a notification.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tauri_plugin_notification::NotificationExt;
|
||||
///
|
||||
/// fn notify<R: tauri::Runtime>(app: &tauri::AppHandle<R>) {
|
||||
/// app.notification()
|
||||
/// .builder()
|
||||
/// .title("Tauri")
|
||||
/// .body("Tauri is awesome!")
|
||||
/// .show()
|
||||
/// .unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
pub fn builder(&self) -> NotificationBuilder<R> {
|
||||
NotificationBuilder::new(self.0.clone())
|
||||
}
|
||||
|
||||
/// Requests the permission to send notifications.
|
||||
///
|
||||
/// Desktop applications do not need to ask for this permission,
|
||||
/// so this always resolves to [`PermissionState::Granted`] without prompting the user.
|
||||
pub fn request_permission(&self) -> crate::Result<PermissionState> {
|
||||
Ok(PermissionState::Granted)
|
||||
}
|
||||
|
||||
/// Checks whether the permission to send notifications was granted.
|
||||
///
|
||||
/// Desktop applications do not need to ask for this permission,
|
||||
/// so this always resolves to [`PermissionState::Granted`].
|
||||
pub fn permission_state(&self) -> crate::Result<PermissionState> {
|
||||
Ok(PermissionState::Granted)
|
||||
}
|
||||
|
||||
@@ -4,12 +4,20 @@
|
||||
|
||||
use serde::{ser::Serializer, Serialize};
|
||||
|
||||
/// Alias for a [`std::result::Result`] with the error type set to [`Error`].
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Errors returned by the notification plugin.
|
||||
///
|
||||
/// The error is serialized to its [`Display`](std::fmt::Display) string when it crosses the IPC boundary.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
/// An I/O operation failed, e.g. resolving the path of the running executable on Windows.
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
/// Failed to run a command on the mobile plugin implementation (Kotlin on Android, Swift on iOS).
|
||||
///
|
||||
/// Only available on mobile.
|
||||
#[cfg(mobile)]
|
||||
#[error(transparent)]
|
||||
PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
|
||||
|
||||
@@ -75,10 +75,13 @@ impl<R: Runtime> NotificationBuilder<R> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Identifier of the {@link Channel} that deliveres this notification.
|
||||
/// Sets the identifier of the notification channel that delivers this notification.
|
||||
///
|
||||
/// If the channel does not exist, the notification won't fire.
|
||||
/// Make sure the channel exists with {@link listChannels} and {@link createChannel}.
|
||||
/// Make sure the channel exists with `Notification::list_channels` and
|
||||
/// `Notification::create_channel`.
|
||||
///
|
||||
/// Only used on Android.
|
||||
pub fn channel_id(mut self, id: impl Into<String>) -> Self {
|
||||
self.data.channel_id.replace(id.into());
|
||||
self
|
||||
@@ -213,6 +216,22 @@ impl<R: Runtime> NotificationBuilder<R> {
|
||||
|
||||
/// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the notification APIs.
|
||||
pub trait NotificationExt<R: Runtime> {
|
||||
/// Returns the notification APIs managed by the plugin.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tauri_plugin_notification::NotificationExt;
|
||||
///
|
||||
/// fn notify<R: tauri::Runtime>(app: &tauri::AppHandle<R>) {
|
||||
/// app.notification()
|
||||
/// .builder()
|
||||
/// .title("Tauri")
|
||||
/// .body("Tauri is awesome!")
|
||||
/// .show()
|
||||
/// .unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
fn notification(&self) -> &Notification<R>;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ const PLUGIN_IDENTIFIER: &str = "app.tauri.notification";
|
||||
#[cfg(target_os = "ios")]
|
||||
tauri::ios_plugin_binding!(init_plugin_notification);
|
||||
|
||||
// initializes the Kotlin or Swift plugin classes
|
||||
/// Initializes the mobile implementation of the notification APIs by registering
|
||||
/// the Kotlin (Android) or Swift (iOS) plugin class.
|
||||
pub fn init<R: Runtime, C: DeserializeOwned>(
|
||||
_app: &AppHandle<R>,
|
||||
api: PluginApi<R, C>,
|
||||
@@ -31,6 +32,12 @@ pub fn init<R: Runtime, C: DeserializeOwned>(
|
||||
}
|
||||
|
||||
impl<R: Runtime> crate::NotificationBuilder<R> {
|
||||
/// Shows the notification, or schedules it when [`Self::schedule`] was called.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`Error::PluginInvoke`](crate::Error::PluginInvoke) when the mobile plugin
|
||||
/// rejects the notification, e.g. when the scheduled date is in the past.
|
||||
pub fn show(self) -> crate::Result<()> {
|
||||
self.handle
|
||||
.run_mobile_plugin::<i32>("show", self.data)
|
||||
@@ -45,10 +52,29 @@ impl<R: Runtime> crate::NotificationBuilder<R> {
|
||||
pub struct Notification<R: Runtime>(PluginHandle<R>);
|
||||
|
||||
impl<R: Runtime> Notification<R> {
|
||||
/// Creates a new builder for a notification.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tauri_plugin_notification::NotificationExt;
|
||||
///
|
||||
/// fn notify<R: tauri::Runtime>(app: &tauri::AppHandle<R>) {
|
||||
/// app.notification()
|
||||
/// .builder()
|
||||
/// .title("Tauri")
|
||||
/// .body("Tauri is awesome!")
|
||||
/// .show()
|
||||
/// .unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
pub fn builder(&self) -> crate::NotificationBuilder<R> {
|
||||
crate::NotificationBuilder::new(self.0.clone())
|
||||
}
|
||||
|
||||
/// Requests the permission to send notifications, prompting the user when it was not decided yet.
|
||||
///
|
||||
/// On Android this requests the `POST_NOTIFICATIONS` runtime permission.
|
||||
pub fn request_permission(&self) -> crate::Result<PermissionState> {
|
||||
self.0
|
||||
.run_mobile_plugin::<PermissionResponse>("requestPermissions", ())
|
||||
@@ -56,6 +82,7 @@ impl<R: Runtime> Notification<R> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Checks the current state of the permission to send notifications without prompting the user.
|
||||
pub fn permission_state(&self) -> crate::Result<PermissionState> {
|
||||
self.0
|
||||
.run_mobile_plugin::<PermissionResponse>("checkPermissions", ())
|
||||
@@ -63,6 +90,13 @@ impl<R: Runtime> Notification<R> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Registers the action types a notification can reference
|
||||
/// through [`NotificationBuilder::action_type_id`](crate::NotificationBuilder::action_type_id).
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Android**: only the identifier, title and input flag of each [`Action`] are used.
|
||||
/// - **iOS**: each action type is registered as a `UNNotificationCategory`.
|
||||
pub fn register_action_types(&self, types: Vec<ActionType>) -> crate::Result<()> {
|
||||
let mut args = HashMap::new();
|
||||
args.insert("types", types);
|
||||
@@ -71,6 +105,9 @@ impl<R: Runtime> Notification<R> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Removes the delivered notifications with the given identifiers from the notification center.
|
||||
///
|
||||
/// Use [`Self::remove_all_active`] to remove every delivered notification.
|
||||
pub fn remove_active(&self, notifications: Vec<i32>) -> crate::Result<()> {
|
||||
let mut args = HashMap::new();
|
||||
args.insert(
|
||||
@@ -89,18 +126,21 @@ impl<R: Runtime> Notification<R> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Lists the notifications that were delivered and are still visible in the notification center.
|
||||
pub fn active(&self) -> crate::Result<Vec<ActiveNotification>> {
|
||||
self.0
|
||||
.run_mobile_plugin("getActive", ())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Removes all delivered notifications from the notification center.
|
||||
pub fn remove_all_active(&self) -> crate::Result<()> {
|
||||
self.0
|
||||
.run_mobile_plugin("removeActive", ())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Lists the scheduled notifications that have not been delivered yet.
|
||||
pub fn pending(&self) -> crate::Result<Vec<PendingNotification>> {
|
||||
self.0
|
||||
.run_mobile_plugin("getPending", ())
|
||||
@@ -119,6 +159,12 @@ impl<R: Runtime> Notification<R> {
|
||||
self.0.run_mobile_plugin("cancel", ()).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Creates a notification channel, which notifications can target
|
||||
/// through [`NotificationBuilder::channel_id`](crate::NotificationBuilder::channel_id).
|
||||
///
|
||||
/// Notifications that reference a channel that does not exist are not delivered.
|
||||
///
|
||||
/// Only available on Android.
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn create_channel(&self, channel: Channel) -> crate::Result<()> {
|
||||
self.0
|
||||
@@ -126,6 +172,9 @@ impl<R: Runtime> Notification<R> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Deletes the notification channel with the given identifier.
|
||||
///
|
||||
/// Only available on Android.
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn delete_channel(&self, id: impl Into<String>) -> crate::Result<()> {
|
||||
let mut args = HashMap::new();
|
||||
@@ -135,6 +184,9 @@ impl<R: Runtime> Notification<R> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Lists the notification channels that are currently registered for the app.
|
||||
///
|
||||
/// Only available on Android.
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn list_channels(&self) -> crate::Result<Vec<Channel>> {
|
||||
self.0
|
||||
|
||||
@@ -8,6 +8,9 @@ use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializ
|
||||
|
||||
use url::Url;
|
||||
|
||||
/// A media file attached to a notification.
|
||||
///
|
||||
/// Attachments are only used on mobile; desktop notifications ignore them.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Attachment {
|
||||
@@ -16,32 +19,65 @@ pub struct Attachment {
|
||||
}
|
||||
|
||||
impl Attachment {
|
||||
/// Creates a new attachment with the given identifier and URL.
|
||||
///
|
||||
/// The URL accepts the `asset` and `file` protocols.
|
||||
pub fn new(id: impl Into<String>, url: Url) -> Self {
|
||||
Self { id: id.into(), url }
|
||||
}
|
||||
}
|
||||
|
||||
/// The set of date fields a notification must match to be delivered.
|
||||
///
|
||||
/// Fields left as [`None`] match any value, so the notification fires on every date
|
||||
/// whose remaining components match. Used by [`Schedule::Interval`].
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ScheduleInterval {
|
||||
/// The year the notification fires on.
|
||||
pub year: Option<u8>,
|
||||
/// The month of the year the notification fires on.
|
||||
pub month: Option<u8>,
|
||||
/// The day of the month the notification fires on.
|
||||
pub day: Option<u8>,
|
||||
/// The day of the week the notification fires on.
|
||||
///
|
||||
/// 1 - Sunday, 2 - Monday, 3 - Tuesday, 4 - Wednesday, 5 - Thursday, 6 - Friday, 7 - Saturday.
|
||||
pub weekday: Option<u8>,
|
||||
/// The hour of the day the notification fires on, in the 24-hour clock.
|
||||
pub hour: Option<u8>,
|
||||
/// The minute of the hour the notification fires on.
|
||||
pub minute: Option<u8>,
|
||||
/// The second of the minute the notification fires on.
|
||||
pub second: Option<u8>,
|
||||
}
|
||||
|
||||
/// The unit of the repeating interval used by [`Schedule::Every`].
|
||||
///
|
||||
/// It is serialized as its lowercase camelCase name, e.g. `twoWeeks`.
|
||||
#[derive(Debug)]
|
||||
pub enum ScheduleEvery {
|
||||
/// Repeats every year.
|
||||
///
|
||||
/// On Android a year is approximated as 52 weeks.
|
||||
Year,
|
||||
/// Repeats every month.
|
||||
///
|
||||
/// On Android a month is approximated as 30 days.
|
||||
Month,
|
||||
/// Repeats every two weeks.
|
||||
TwoWeeks,
|
||||
/// Repeats every week.
|
||||
Week,
|
||||
/// Repeats every day.
|
||||
Day,
|
||||
/// Repeats every hour.
|
||||
Hour,
|
||||
/// Repeats every minute.
|
||||
Minute,
|
||||
/// Repeats every second.
|
||||
///
|
||||
/// Not supported on iOS, where repeating triggers must be at least a minute apart.
|
||||
Second,
|
||||
}
|
||||
|
||||
@@ -93,31 +129,58 @@ impl<'de> Deserialize<'de> for ScheduleEvery {
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines when a notification is delivered.
|
||||
///
|
||||
/// Scheduling is only implemented on mobile; the desktop implementation delivers the
|
||||
/// notification immediately and ignores the schedule.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum Schedule {
|
||||
/// Fires at a specific date and time, which must be in the future.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
At {
|
||||
/// The date and time the notification fires at, serialized as an ISO-8601 string.
|
||||
#[serde(
|
||||
serialize_with = "iso8601::serialize",
|
||||
deserialize_with = "time::serde::iso8601::deserialize"
|
||||
)]
|
||||
date: time::OffsetDateTime,
|
||||
/// Whether the notification keeps repeating, using the duration between the moment it is
|
||||
/// scheduled and `date` as the interval. Defaults to `false`.
|
||||
///
|
||||
/// The interval must be at least one minute on iOS.
|
||||
#[serde(default)]
|
||||
repeating: bool,
|
||||
/// Whether the notification is allowed to fire while the device is in low-power idle
|
||||
/// (Doze) mode. Defaults to `false`.
|
||||
///
|
||||
/// Only used on Android.
|
||||
#[serde(default)]
|
||||
allow_while_idle: bool,
|
||||
},
|
||||
/// Fires whenever the current date matches every field set on the given interval.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Interval {
|
||||
/// The date fields the current date must match for the notification to fire.
|
||||
interval: ScheduleInterval,
|
||||
/// Whether the notification is allowed to fire while the device is in low-power idle
|
||||
/// (Doze) mode. Defaults to `false`.
|
||||
///
|
||||
/// Only used on Android.
|
||||
#[serde(default)]
|
||||
allow_while_idle: bool,
|
||||
},
|
||||
/// Fires repeatedly, once every `count` times the given interval unit.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Every {
|
||||
/// The unit of the repeating interval.
|
||||
interval: ScheduleEvery,
|
||||
/// How many interval units elapse between each notification.
|
||||
count: u8,
|
||||
/// Whether the notification is allowed to fire while the device is in low-power idle
|
||||
/// (Doze) mode. Defaults to `false`.
|
||||
///
|
||||
/// Only used on Android.
|
||||
#[serde(default)]
|
||||
allow_while_idle: bool,
|
||||
},
|
||||
@@ -145,6 +208,10 @@ mod iso8601 {
|
||||
}
|
||||
}
|
||||
|
||||
/// The payload of a notification, as sent to the platform implementation.
|
||||
///
|
||||
/// Build it with [`NotificationBuilder`](crate::NotificationBuilder) rather than constructing it directly.
|
||||
/// The identifier defaults to a random 32-bit integer when it is not provided.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NotificationData {
|
||||
@@ -209,6 +276,9 @@ impl Default for NotificationData {
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that was scheduled and has not been delivered yet.
|
||||
///
|
||||
/// Returned by `Notification::pending`, which is only available on mobile.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PendingNotification {
|
||||
@@ -219,23 +289,32 @@ pub struct PendingNotification {
|
||||
}
|
||||
|
||||
impl PendingNotification {
|
||||
/// The notification identifier.
|
||||
pub fn id(&self) -> i32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
/// The notification title, if it was set.
|
||||
pub fn title(&self) -> Option<&str> {
|
||||
self.title.as_deref()
|
||||
}
|
||||
|
||||
/// The notification body, if it was set.
|
||||
pub fn body(&self) -> Option<&str> {
|
||||
self.body.as_deref()
|
||||
}
|
||||
|
||||
/// The schedule that determines when the notification is delivered.
|
||||
pub fn schedule(&self) -> &Schedule {
|
||||
&self.schedule
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that was delivered and is still visible in the notification center.
|
||||
///
|
||||
/// Returned by `Notification::active`, which is only available on mobile.
|
||||
/// Which fields are populated depends on the platform, since Android and iOS expose
|
||||
/// different information about delivered notifications.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ActiveNotification {
|
||||
@@ -258,55 +337,88 @@ pub struct ActiveNotification {
|
||||
}
|
||||
|
||||
impl ActiveNotification {
|
||||
/// The notification identifier.
|
||||
pub fn id(&self) -> i32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
/// The tag the notification was posted with.
|
||||
///
|
||||
/// Only set on Android.
|
||||
pub fn tag(&self) -> Option<&str> {
|
||||
self.tag.as_deref()
|
||||
}
|
||||
|
||||
/// The notification title, if it was set.
|
||||
pub fn title(&self) -> Option<&str> {
|
||||
self.title.as_deref()
|
||||
}
|
||||
|
||||
/// The notification body, if it was set.
|
||||
pub fn body(&self) -> Option<&str> {
|
||||
self.body.as_deref()
|
||||
}
|
||||
|
||||
/// The identifier of the group the notification belongs to.
|
||||
///
|
||||
/// Only set on Android.
|
||||
pub fn group(&self) -> Option<&str> {
|
||||
self.group.as_deref()
|
||||
}
|
||||
|
||||
/// Whether the notification is the summary of its group.
|
||||
///
|
||||
/// Only set on Android. Defaults to `false`.
|
||||
pub fn group_summary(&self) -> bool {
|
||||
self.group_summary
|
||||
}
|
||||
|
||||
/// The platform extras attached to the notification, as string values.
|
||||
///
|
||||
/// Only set on Android, where it holds the `android.app.Notification` extras bundle.
|
||||
pub fn data(&self) -> &HashMap<String, String> {
|
||||
&self.data
|
||||
}
|
||||
|
||||
/// The extra payload that was stored in the notification.
|
||||
pub fn extra(&self) -> &HashMap<String, serde_json::Value> {
|
||||
&self.extra
|
||||
}
|
||||
|
||||
/// The attachments of the notification.
|
||||
///
|
||||
/// Only set on iOS.
|
||||
pub fn attachments(&self) -> &[Attachment] {
|
||||
&self.attachments
|
||||
}
|
||||
|
||||
/// The identifier of the action type the notification was registered with.
|
||||
///
|
||||
/// Only set on iOS.
|
||||
pub fn action_type_id(&self) -> Option<&str> {
|
||||
self.action_type_id.as_deref()
|
||||
}
|
||||
|
||||
/// The schedule the notification was delivered with, if it was scheduled.
|
||||
pub fn schedule(&self) -> Option<&Schedule> {
|
||||
self.schedule.as_ref()
|
||||
}
|
||||
|
||||
/// The sound resource name of the notification.
|
||||
///
|
||||
/// Only set on iOS.
|
||||
pub fn sound(&self) -> Option<&str> {
|
||||
self.sound.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
/// A group of [`Action`]s a notification can display, referenced by
|
||||
/// [`NotificationBuilder::action_type_id`](crate::NotificationBuilder::action_type_id).
|
||||
///
|
||||
/// Register it with `Notification::register_action_types` before sending a notification that uses it.
|
||||
/// It maps to a `UNNotificationCategory` on iOS and to an action group on Android.
|
||||
///
|
||||
/// Only available on mobile. Use [`ActionType::builder`] to construct one.
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -320,12 +432,19 @@ pub struct ActionType {
|
||||
hidden_previews_show_subtitle: bool,
|
||||
}
|
||||
|
||||
/// Builder for an [`ActionType`], created with [`ActionType::builder`].
|
||||
///
|
||||
/// Only available on mobile.
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug)]
|
||||
pub struct ActionTypeBuilder(ActionType);
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl ActionType {
|
||||
/// Creates a builder for an action type with the given identifier.
|
||||
///
|
||||
/// All the optional settings default to `false` or [`None`];
|
||||
/// call [`ActionTypeBuilder::build`] to get the [`ActionType`].
|
||||
pub fn builder(id: impl Into<String>) -> ActionTypeBuilder {
|
||||
ActionTypeBuilder(Self {
|
||||
id: id.into(),
|
||||
@@ -338,30 +457,47 @@ impl ActionType {
|
||||
})
|
||||
}
|
||||
|
||||
/// The identifier of this action type.
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
/// The actions associated with this action type.
|
||||
pub fn actions(&self) -> &[Action] {
|
||||
&self.actions
|
||||
}
|
||||
|
||||
/// The placeholder shown instead of the notification body when previews are hidden.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn hidden_previews_body_placeholder(&self) -> Option<&str> {
|
||||
self.hidden_previews_body_placeholder.as_deref()
|
||||
}
|
||||
|
||||
/// Whether the app is notified when the user dismisses the notification.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn custom_dismiss_action(&self) -> bool {
|
||||
self.custom_dismiss_action
|
||||
}
|
||||
|
||||
/// Whether the notification can be displayed in a CarPlay environment.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn allow_in_car_play(&self) -> bool {
|
||||
self.allow_in_car_play
|
||||
}
|
||||
|
||||
/// Whether the notification title is shown even when previews are hidden.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn hidden_previews_show_title(&self) -> bool {
|
||||
self.hidden_previews_show_title
|
||||
}
|
||||
|
||||
/// Whether the notification subtitle is shown even when previews are hidden.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn hidden_previews_show_subtitle(&self) -> bool {
|
||||
self.hidden_previews_show_subtitle
|
||||
}
|
||||
@@ -369,11 +505,15 @@ impl ActionType {
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl ActionTypeBuilder {
|
||||
/// Sets the actions associated with this action type.
|
||||
pub fn actions(mut self, actions: Vec<Action>) -> Self {
|
||||
self.0.actions = actions;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the placeholder shown instead of the notification body when previews are hidden.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn hidden_previews_body_placeholder(
|
||||
mut self,
|
||||
hidden_previews_body_placeholder: impl Into<String>,
|
||||
@@ -384,31 +524,50 @@ impl ActionTypeBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the app is notified when the user dismisses the notification.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn custom_dismiss_action(mut self, custom_dismiss_action: bool) -> Self {
|
||||
self.0.custom_dismiss_action = custom_dismiss_action;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the notification can be displayed in a CarPlay environment.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn allow_in_car_play(mut self, allow_in_car_play: bool) -> Self {
|
||||
self.0.allow_in_car_play = allow_in_car_play;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the notification title is shown even when previews are hidden.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn hidden_previews_show_title(mut self, hidden_previews_show_title: bool) -> Self {
|
||||
self.0.hidden_previews_show_title = hidden_previews_show_title;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the notification subtitle is shown even when previews are hidden.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn hidden_previews_show_subtitle(mut self, hidden_previews_show_subtitle: bool) -> Self {
|
||||
self.0.hidden_previews_show_subtitle = hidden_previews_show_subtitle;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the [`ActionType`].
|
||||
pub fn build(self) -> ActionType {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// A button the user can tap on a notification, belonging to an [`ActionType`].
|
||||
///
|
||||
/// It maps to a `UNNotificationAction` on iOS. On Android only the identifier, the title
|
||||
/// and the input flag are used.
|
||||
///
|
||||
/// Only available on mobile. Use [`Action::builder`] to construct one.
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -423,12 +582,19 @@ pub struct Action {
|
||||
input_placeholder: Option<String>,
|
||||
}
|
||||
|
||||
/// Builder for an [`Action`], created with [`Action::builder`].
|
||||
///
|
||||
/// Only available on mobile.
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug)]
|
||||
pub struct ActionBuilder(Action);
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl Action {
|
||||
/// Creates a builder for an action with the given identifier and button title.
|
||||
///
|
||||
/// All the optional settings default to `false` or [`None`];
|
||||
/// call [`ActionBuilder::build`] to get the [`Action`].
|
||||
pub fn builder(id: impl Into<String>, title: impl Into<String>) -> ActionBuilder {
|
||||
ActionBuilder(Self {
|
||||
id: id.into(),
|
||||
@@ -442,34 +608,52 @@ impl Action {
|
||||
})
|
||||
}
|
||||
|
||||
/// The identifier of this action, reported back when the user triggers it.
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
/// The text displayed on the action button.
|
||||
pub fn title(&self) -> &str {
|
||||
&self.title
|
||||
}
|
||||
|
||||
/// Whether the device must be unlocked for the action to run.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn requires_authentication(&self) -> bool {
|
||||
self.requires_authentication
|
||||
}
|
||||
|
||||
/// Whether the app is brought to the foreground when the action is triggered.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn foreground(&self) -> bool {
|
||||
self.foreground
|
||||
}
|
||||
|
||||
/// Whether the action is displayed as destructive, usually in red.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn destructive(&self) -> bool {
|
||||
self.destructive
|
||||
}
|
||||
|
||||
/// Whether triggering the action lets the user type a text response.
|
||||
pub fn input(&self) -> bool {
|
||||
self.input
|
||||
}
|
||||
|
||||
/// The text displayed on the button that submits the text input.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn input_button_title(&self) -> Option<&str> {
|
||||
self.input_button_title.as_deref()
|
||||
}
|
||||
|
||||
/// The placeholder displayed on the empty text input field.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn input_placeholder(&self) -> Option<&str> {
|
||||
self.input_placeholder.as_deref()
|
||||
}
|
||||
@@ -477,36 +661,53 @@ impl Action {
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl ActionBuilder {
|
||||
/// Sets whether the device must be unlocked for the action to run.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn requires_authentication(mut self, requires_authentication: bool) -> Self {
|
||||
self.0.requires_authentication = requires_authentication;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the app is brought to the foreground when the action is triggered.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn foreground(mut self, foreground: bool) -> Self {
|
||||
self.0.foreground = foreground;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the action is displayed as destructive, usually in red.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn destructive(mut self, destructive: bool) -> Self {
|
||||
self.0.destructive = destructive;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether triggering the action lets the user type a text response.
|
||||
pub fn input(mut self, input: bool) -> Self {
|
||||
self.0.input = input;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the text displayed on the button that submits the text input.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn input_button_title(mut self, input_button_title: impl Into<String>) -> Self {
|
||||
self.0.input_button_title.replace(input_button_title.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the placeholder displayed on the empty text input field.
|
||||
///
|
||||
/// Only used on iOS.
|
||||
pub fn input_placeholder(mut self, input_placeholder: impl Into<String>) -> Self {
|
||||
self.0.input_placeholder.replace(input_placeholder.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the [`Action`].
|
||||
pub fn build(self) -> Action {
|
||||
self.0
|
||||
}
|
||||
@@ -520,13 +721,24 @@ mod android {
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
|
||||
/// How much the notifications of a [`Channel`] interrupt the user.
|
||||
///
|
||||
/// It maps to the `NotificationManager.IMPORTANCE_*` constants and is serialized as its
|
||||
/// integer value. Only available on Android.
|
||||
#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr)]
|
||||
#[repr(u8)]
|
||||
pub enum Importance {
|
||||
/// The notifications are not shown.
|
||||
None = 0,
|
||||
/// The notifications are only shown in the shade, below the fold, without a status bar icon.
|
||||
Min = 1,
|
||||
/// The notifications are shown without a sound.
|
||||
Low = 2,
|
||||
/// The notifications are shown and make a sound.
|
||||
///
|
||||
/// This is the value used when the channel does not define an importance.
|
||||
Default = 3,
|
||||
/// The notifications are shown, make a sound and pop up as a heads-up notification.
|
||||
High = 4,
|
||||
}
|
||||
|
||||
@@ -536,14 +748,29 @@ mod android {
|
||||
}
|
||||
}
|
||||
|
||||
/// How much of a notification is shown on the lock screen.
|
||||
///
|
||||
/// It maps to the `Notification.VISIBILITY_*` constants and is serialized as its
|
||||
/// integer value. Only available on Android.
|
||||
#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr)]
|
||||
#[repr(i8)]
|
||||
pub enum Visibility {
|
||||
/// The notification is not shown on the lock screen at all.
|
||||
Secret = -1,
|
||||
/// The notification is shown on the lock screen with its sensitive content hidden.
|
||||
///
|
||||
/// This is the value used when the channel does not define a visibility.
|
||||
Private = 0,
|
||||
/// The notification is shown in full on the lock screen.
|
||||
Public = 1,
|
||||
}
|
||||
|
||||
/// A notification channel, the category users configure notification behavior on.
|
||||
///
|
||||
/// Notifications reference a channel through
|
||||
/// [`NotificationBuilder::channel_id`](crate::NotificationBuilder::channel_id) and are not
|
||||
/// delivered when the channel does not exist. Only available on Android.
|
||||
/// Use [`Channel::builder`] to construct one.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Channel {
|
||||
@@ -558,10 +785,18 @@ mod android {
|
||||
visibility: Option<Visibility>,
|
||||
}
|
||||
|
||||
/// Builder for a [`Channel`], created with [`Channel::builder`].
|
||||
///
|
||||
/// Only available on Android.
|
||||
#[derive(Debug)]
|
||||
pub struct ChannelBuilder(Channel);
|
||||
|
||||
impl Channel {
|
||||
/// Creates a builder for a channel with the given identifier and user visible name.
|
||||
///
|
||||
/// Lights and vibration are disabled, the importance defaults to [`Importance::Default`]
|
||||
/// and the remaining settings default to [`None`];
|
||||
/// call [`ChannelBuilder::build`] to get the [`Channel`].
|
||||
pub fn builder(id: impl Into<String>, name: impl Into<String>) -> ChannelBuilder {
|
||||
ChannelBuilder(Self {
|
||||
id: id.into(),
|
||||
@@ -576,79 +811,102 @@ mod android {
|
||||
})
|
||||
}
|
||||
|
||||
/// The identifier of this channel.
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
/// The user visible name of this channel.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// The user visible description of this channel.
|
||||
pub fn description(&self) -> Option<&str> {
|
||||
self.description.as_deref()
|
||||
}
|
||||
|
||||
/// The name of the sound resource played by the notifications of this channel.
|
||||
///
|
||||
/// The resource must be placed in the app's `res/raw` folder.
|
||||
pub fn sound(&self) -> Option<&str> {
|
||||
self.sound.as_deref()
|
||||
}
|
||||
|
||||
/// Whether the notifications of this channel blink the device light.
|
||||
pub fn lights(&self) -> bool {
|
||||
self.lights
|
||||
}
|
||||
|
||||
/// The color of the device light, as a color string such as `#ff0000`.
|
||||
pub fn light_color(&self) -> Option<&str> {
|
||||
self.light_color.as_deref()
|
||||
}
|
||||
|
||||
/// Whether the notifications of this channel vibrate the device.
|
||||
pub fn vibration(&self) -> bool {
|
||||
self.vibration
|
||||
}
|
||||
|
||||
/// How much the notifications of this channel interrupt the user.
|
||||
pub fn importance(&self) -> Importance {
|
||||
self.importance
|
||||
}
|
||||
|
||||
/// How much of the notifications of this channel is shown on the lock screen.
|
||||
///
|
||||
/// [`Visibility::Private`] is used when this is [`None`].
|
||||
pub fn visibility(&self) -> Option<Visibility> {
|
||||
self.visibility
|
||||
}
|
||||
}
|
||||
|
||||
impl ChannelBuilder {
|
||||
/// Sets the user visible description of the channel.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.0.description.replace(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the name of the sound resource played by the notifications of this channel.
|
||||
///
|
||||
/// The resource must be placed in the app's `res/raw` folder.
|
||||
pub fn sound(mut self, sound: impl Into<String>) -> Self {
|
||||
self.0.sound.replace(sound.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the notifications of this channel blink the device light.
|
||||
pub fn lights(mut self, lights: bool) -> Self {
|
||||
self.0.lights = lights;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the color of the device light, as a color string such as `#ff0000`.
|
||||
pub fn light_color(mut self, color: impl Into<String>) -> Self {
|
||||
self.0.light_color.replace(color.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the notifications of this channel vibrate the device.
|
||||
pub fn vibration(mut self, vibration: bool) -> Self {
|
||||
self.0.vibration = vibration;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets how much the notifications of this channel interrupt the user.
|
||||
pub fn importance(mut self, importance: Importance) -> Self {
|
||||
self.0.importance = importance;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets how much of the notifications of this channel is shown on the lock screen.
|
||||
pub fn visibility(mut self, visibility: Visibility) -> Self {
|
||||
self.0.visibility.replace(visibility);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the [`Channel`].
|
||||
pub fn build(self) -> Channel {
|
||||
self.0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user