Skip to content

Commit

Permalink
feat: add notification sound (#7269)
Browse files Browse the repository at this point in the history
Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.studio>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
  • Loading branch information
3 people authored Aug 8, 2023
1 parent c272e4a commit 6c408b7
Show file tree
Hide file tree
Showing 17 changed files with 866 additions and 768 deletions.
6 changes: 6 additions & 0 deletions .changes/notification-sound.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'tauri': 'minor:feat'
'@tauri-apps/api': 'minor:feat'
---

Add option to specify notification sound.
5 changes: 1 addition & 4 deletions .github/workflows/check-generated-files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ jobs:
filters: |
api:
- 'tooling/api/src/**'
- 'tooling/api/docs/js-api.json'
- 'core/tauri/scripts/bundle.global.js'
schema:
- 'core/tauri-utils/src/config.rs'
Expand All @@ -50,9 +49,7 @@ jobs:
working-directory: tooling/api
run: yarn && yarn build
- name: check api
run: |
git restore tooling/api/docs/js-api.json
./.scripts/ci/has-diff.sh
run: ./.scripts/ci/has-diff.sh

schema:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
cargo update -p is-terminal --precise 0.4.7
cargo update -p colored --precise 2.0.2
cargo update -p tempfile --precise 3.6.0
cargo update -p serde_with:3.1.0 --precise 3.0.0
cargo update -p serde_with:3.2.0 --precise 3.0.0
- name: test
run: cargo test --target ${{ matrix.platform.target }} ${{ matrix.features.args }}
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ dist
/tooling/cli/templates
/tooling/cli/node
/tooling/cli/schema.json
/tooling/api/docs/js-api.json
/core/tauri-config-schema/schema.json
2 changes: 1 addition & 1 deletion core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ objc = "0.2"

[target."cfg(windows)".dependencies]
webview2-com = "0.19.1"
win7-notifications = { version = "0.3.1", optional = true }
win7-notifications = { version = "0.4", optional = true }

[target."cfg(windows)".dependencies.windows]
version = "0.39.0"
Expand Down
65 changes: 65 additions & 0 deletions core/tauri/src/api/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,50 @@ pub struct Notification {
icon: Option<String>,
/// The notification identifier
identifier: String,
/// The notification sound
sound: Option<Sound>,
}

/// Notification sound.
#[derive(Debug)]
pub enum Sound {
/// The default notification sound.
Default,
/// A custom notification sound.
///
/// ## Platform-specific
///
/// Each OS has a different sound name so you will need to conditionally specify an appropriate sound
/// based on the OS in use, for a list of sounds see:
/// - **Linux**: can be one of the sounds listed in <https://0pointer.de/public/sound-naming-spec.html>
/// - **Windows**: can be one of the sounds listed in <https://learn.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-audio>
/// but without the prefix, for example, if `ms-winsoundevent:Notification.Default` you would use `Default` and
/// if `ms-winsoundevent:Notification.Looping.Alarm2`, you would use `Alarm2`.
/// Windows 7 is not supported, if a sound is provided, it will play the default sound, otherwise it will be silent.
/// - **macOS**: you can specify the name of the sound you'd like to play when the notification is shown.
/// Any of the default sounds (under System Preferences > Sound) can be used, in addition to custom sound files.
/// Be sure that the sound file is under one of the following locations:
/// - `~/Library/Sounds`
/// - `/Library/Sounds`
/// - `/Network/Library/Sounds`
/// - `/System/Library/Sounds`
///
/// See the [`NSSound`] docs for more information.
///
/// [`NSSound`]: https://developer.apple.com/documentation/appkit/nssound
Custom(String),
}

impl From<String> for Sound {
fn from(value: String) -> Self {
Self::Custom(value)
}
}

impl From<&str> for Sound {
fn from(value: &str) -> Self {
Self::Custom(value.into())
}
}

impl Notification {
Expand Down Expand Up @@ -72,6 +116,15 @@ impl Notification {
self
}

/// Sets the notification sound. By default the notification has no sound.
///
/// See [`Sound`] for more information.
#[must_use]
pub fn sound(mut self, sound: impl Into<Sound>) -> Self {
self.sound.replace(sound.into());
self
}

/// Shows the notification.
///
/// # Examples
Expand Down Expand Up @@ -108,6 +161,17 @@ impl Notification {
} else {
notification.auto_icon();
}
if let Some(sound) = self.sound {
notification.sound_name(&match sound {
#[cfg(target_os = "macos")]
Sound::Default => "NSUserNotificationDefaultSoundName".to_string(),
#[cfg(windows)]
Sound::Default => "Default".to_string(),
#[cfg(all(unix, not(target_os = "macos")))]
Sound::Default => "message-new-instant".to_string(),
Sound::Custom(c) => c,
});
}
#[cfg(windows)]
{
let exe = tauri_utils::platform::current_exe()?;
Expand Down Expand Up @@ -191,6 +255,7 @@ impl Notification {
if let Some(title) = self.title {
notification.summary(&title);
}
notification.silent(self.sound.is_none());
if let Some(crate::Icon::Rgba {
rgba,
width,
Expand Down
50 changes: 48 additions & 2 deletions core/tauri/src/endpoints/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use super::InvokeContext;
use crate::Runtime;
use serde::Deserialize;
use serde::{Deserialize, Deserializer};
use tauri_macros::{command_enum, module_command_handler, CommandModule};

#[cfg(notification_all)]
Expand All @@ -17,6 +17,36 @@ const PERMISSION_GRANTED: &str = "granted";
// `Denied` response from `request_permission`. Matches the Web API return value.
const PERMISSION_DENIED: &str = "denied";

#[derive(Debug, Clone)]
pub enum SoundDto {
Default,
Custom(String),
}

#[cfg(notification_all)]
impl From<SoundDto> for crate::api::notification::Sound {
fn from(sound: SoundDto) -> Self {
match sound {
SoundDto::Default => crate::api::notification::Sound::Default,
SoundDto::Custom(s) => crate::api::notification::Sound::Custom(s),
}
}
}

impl<'de> Deserialize<'de> for SoundDto {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
if s.to_lowercase() == "default" {
Ok(Self::Default)
} else {
Ok(Self::Custom(s))
}
}
}

/// The options for the notification API.
#[derive(Debug, Clone, Deserialize)]
pub struct NotificationOptions {
Expand All @@ -26,6 +56,8 @@ pub struct NotificationOptions {
pub body: Option<String>,
/// The notification icon.
pub icon: Option<String>,
/// The notification sound.
pub sound: Option<SoundDto>,
}

/// The API descriptor.
Expand Down Expand Up @@ -56,6 +88,9 @@ impl Cmd {
if let Some(icon) = options.icon {
notification = notification.icon(icon);
}
if let Some(sound) = options.sound {
notification = notification.sound(sound);
}
#[cfg(feature = "windows7-compat")]
{
notification.notify(&context.window.app_handle)?;
Expand Down Expand Up @@ -84,16 +119,27 @@ impl Cmd {

#[cfg(test)]
mod tests {
use super::NotificationOptions;
use super::{NotificationOptions, SoundDto};

use quickcheck::{Arbitrary, Gen};

impl Arbitrary for SoundDto {
fn arbitrary(g: &mut Gen) -> Self {
if bool::arbitrary(g) {
Self::Default
} else {
Self::Custom(String::arbitrary(g))
}
}
}

impl Arbitrary for NotificationOptions {
fn arbitrary(g: &mut Gen) -> Self {
Self {
title: String::arbitrary(g),
body: Option::arbitrary(g),
icon: Option::arbitrary(g),
sound: Option::arbitrary(g),
}
}
}
Expand Down
1 change: 0 additions & 1 deletion core/tests/app-updater/frameworks/test.framework/Headers

This file was deleted.

1 change: 1 addition & 0 deletions core/tests/app-updater/frameworks/test.framework/Headers
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Versions/Current/Headers
1 change: 0 additions & 1 deletion core/tests/app-updater/frameworks/test.framework/Resources

This file was deleted.

1 change: 1 addition & 0 deletions core/tests/app-updater/frameworks/test.framework/Resources
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Versions/Current/Resources
Empty file.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A
1 change: 0 additions & 1 deletion core/tests/app-updater/frameworks/test.framework/test

This file was deleted.

1 change: 1 addition & 0 deletions core/tests/app-updater/frameworks/test.framework/test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Versions/Current/test
62 changes: 31 additions & 31 deletions examples/api/dist/assets/index.js

Large diffs are not rendered by default.

Loading

0 comments on commit 6c408b7

Please sign in to comment.