notification.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! Types and functions related to desktop notifications.
  5. #[cfg(windows)]
  6. use std::path::MAIN_SEPARATOR;
  7. /// The desktop notification definition.
  8. ///
  9. /// Allows you to construct a Notification data and send it.
  10. ///
  11. /// # Examples
  12. /// ```rust,no_run
  13. /// use tauri::api::notification::Notification;
  14. /// // first we build the application to access the Tauri configuration
  15. /// let app = tauri::Builder::default()
  16. /// // on an actual app, remove the string argument
  17. /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json"))
  18. /// .expect("error while building tauri application");
  19. ///
  20. /// // shows a notification with the given title and body
  21. /// Notification::new(&app.config().tauri.bundle.identifier)
  22. /// .title("New message")
  23. /// .body("You've got a new message.")
  24. /// .show();
  25. ///
  26. /// // run the app
  27. /// app.run(|_app_handle, _event| {});
  28. /// ```
  29. #[allow(dead_code)]
  30. #[derive(Debug, Default)]
  31. pub struct Notification {
  32. /// The notification body.
  33. body: Option<String>,
  34. /// The notification title.
  35. title: Option<String>,
  36. /// The notification icon.
  37. icon: Option<String>,
  38. /// The notification identifier
  39. identifier: String,
  40. }
  41. impl Notification {
  42. /// Initializes a instance of a Notification.
  43. pub fn new(identifier: impl Into<String>) -> Self {
  44. Self {
  45. identifier: identifier.into(),
  46. ..Default::default()
  47. }
  48. }
  49. /// Sets the notification body.
  50. #[must_use]
  51. pub fn body(mut self, body: impl Into<String>) -> Self {
  52. self.body = Some(body.into());
  53. self
  54. }
  55. /// Sets the notification title.
  56. #[must_use]
  57. pub fn title(mut self, title: impl Into<String>) -> Self {
  58. self.title = Some(title.into());
  59. self
  60. }
  61. /// Sets the notification icon.
  62. #[must_use]
  63. pub fn icon(mut self, icon: impl Into<String>) -> Self {
  64. self.icon = Some(icon.into());
  65. self
  66. }
  67. /// Shows the notification.
  68. pub fn show(self) -> crate::api::Result<()> {
  69. let mut notification = notify_rust::Notification::new();
  70. if let Some(body) = self.body {
  71. notification.body(&body);
  72. }
  73. if let Some(title) = self.title {
  74. notification.summary(&title);
  75. }
  76. if let Some(icon) = self.icon {
  77. notification.icon(&icon);
  78. }
  79. #[cfg(windows)]
  80. {
  81. let exe = tauri_utils::platform::current_exe()?;
  82. let exe_dir = exe.parent().expect("failed to get exe directory");
  83. let curr_dir = exe_dir.display().to_string();
  84. // set the notification's System.AppUserModel.ID only when running the installed app
  85. if !(curr_dir.ends_with(format!("{S}target{S}debug", S = MAIN_SEPARATOR).as_str())
  86. || curr_dir.ends_with(format!("{S}target{S}release", S = MAIN_SEPARATOR).as_str()))
  87. {
  88. notification.app_id(&self.identifier);
  89. }
  90. }
  91. #[cfg(target_os = "macos")]
  92. {
  93. let _ = notify_rust::set_application(if cfg!(feature = "custom-protocol") {
  94. &self.identifier
  95. } else {
  96. "com.apple.Terminal"
  97. });
  98. }
  99. crate::async_runtime::spawn(async move {
  100. notification.show().expect("failed to show notification");
  101. });
  102. Ok(())
  103. }
  104. }