10
10
//! Todo:
11
11
//!
12
12
//! * Add support for Adaptive Content
13
- //! * Add support for Actions
14
13
//!
15
14
//! Known Issues:
16
15
//!
@@ -36,7 +35,9 @@ use windows::{
36
35
core:: { IInspectable , Interface } ,
37
36
Data :: Xml :: Dom :: XmlDocument ,
38
37
Foundation :: TypedEventHandler ,
39
- UI :: Notifications :: { ToastActivatedEventArgs , ToastNotificationManager } ,
38
+ UI :: Notifications :: {
39
+ ToastActivatedEventArgs , ToastDismissedEventArgs , ToastNotificationManager ,
40
+ } ,
40
41
} ;
41
42
42
43
use std:: fmt:: Display ;
@@ -47,6 +48,14 @@ use std::str::FromStr;
47
48
pub use windows:: core:: { Error , Result , HSTRING } ;
48
49
pub use windows:: UI :: Notifications :: ToastNotification ;
49
50
51
+ /// `ToastDismissalReason` is a struct representing the reason a toast notification was dismissed.
52
+ ///
53
+ /// Variants:
54
+ /// - `UserCanceled`: The user explicitly dismissed the toast notification.
55
+ /// - `ApplicationHidden`: The application hid the toast notification programmatically.
56
+ /// - `TimedOut`: The toast notification was dismissed because it timed out.
57
+ pub use windows:: UI :: Notifications :: ToastDismissalReason ;
58
+
50
59
pub struct Toast {
51
60
duration : String ,
52
61
title : String ,
@@ -57,6 +66,7 @@ pub struct Toast {
57
66
app_id : String ,
58
67
scenario : String ,
59
68
on_activated : Option < TypedEventHandler < ToastNotification , IInspectable > > ,
69
+ on_dismissed : Option < TypedEventHandler < ToastNotification , ToastDismissedEventArgs > > ,
60
70
buttons : Vec < Button > ,
61
71
}
62
72
@@ -276,6 +286,7 @@ impl Toast {
276
286
app_id : app_id. to_string ( ) ,
277
287
scenario : String :: new ( ) ,
278
288
on_activated : None ,
289
+ on_dismissed : None ,
279
290
buttons : Vec :: new ( ) ,
280
291
}
281
292
}
@@ -322,7 +333,7 @@ impl Toast {
322
333
Duration :: Long => "duration=\" long\" " ,
323
334
Duration :: Short => "duration=\" short\" " ,
324
335
}
325
- . to_owned ( ) ;
336
+ . to_string ( ) ;
326
337
self
327
338
}
328
339
@@ -337,7 +348,7 @@ impl Toast {
337
348
Scenario :: Reminder => "scenario=\" reminder\" " ,
338
349
Scenario :: IncomingCall => "scenario=\" incomingCall\" " ,
339
350
}
340
- . to_owned ( ) ;
351
+ . to_string ( ) ;
341
352
self
342
353
}
343
354
@@ -391,7 +402,7 @@ impl Toast {
391
402
pub fn image ( mut self , source : & Path , alt_text : & str ) -> Toast {
392
403
if !is_newer_than_windows81 ( ) {
393
404
// win81 cannot have more than 1 image and shows nothing if there is more than that
394
- self . images = "" . to_owned ( ) ;
405
+ self . images = String :: new ( ) ;
395
406
}
396
407
self . images = format ! (
397
408
r#"{}<image id="1" src="file:///{}" alt="{}" />"# ,
@@ -459,6 +470,49 @@ impl Toast {
459
470
None
460
471
}
461
472
473
+ /// Set the function to be called when the toast is dismissed
474
+ /// `f` will be called with the reason the toast was dismissed.
475
+ /// If the toast was dismissed by the user, the reason will be `ToastDismissalReason::UserCanceled`.
476
+ /// If the toast was dismissed by the application, the reason will be `ToastDismissalReason::ApplicationHidden`.
477
+ /// If the toast was dismissed because it timed out, the reason will be `ToastDismissalReason::TimedOut`.
478
+ /// If the reason is unknown, the reason will be `None`.
479
+ ///
480
+ /// # Example
481
+ /// ```rust
482
+ /// use tauri_winrt_notification::{Toast, ToastDismissalReason};
483
+ ///
484
+ /// let toast = Toast::new(Toast::POWERSHELL_APP_ID);
485
+ /// toast.on_dismissed(|reason| {
486
+ /// match reason {
487
+ /// Some(ToastDismissalReason::UserCanceled) => println!("UserCanceled"),
488
+ /// Some(ToastDismissalReason::ApplicationHidden) => println!("ApplicationHidden"),
489
+ /// Some(ToastDismissalReason::TimedOut) => println!("TimedOut"),
490
+ /// _ => println!("Unknown"),
491
+ /// }
492
+ /// Ok(())
493
+ /// }).show().expect("notification failed");
494
+ /// ```
495
+ pub fn on_dismissed < F : Fn ( Option < ToastDismissalReason > ) -> Result < ( ) > + Send + ' static > (
496
+ mut self ,
497
+ f : F ,
498
+ ) -> Self {
499
+ self . on_dismissed = Some ( TypedEventHandler :: new ( move |_, args| {
500
+ f ( Self :: get_dismissed_reason ( args) )
501
+ } ) ) ;
502
+ self
503
+ }
504
+
505
+ fn get_dismissed_reason (
506
+ args : & Option < ToastDismissedEventArgs > ,
507
+ ) -> Option < ToastDismissalReason > {
508
+ if let Some ( args) = args {
509
+ if let Ok ( reason) = args. Reason ( ) {
510
+ return Some ( reason) ;
511
+ }
512
+ }
513
+ None
514
+ }
515
+
462
516
fn create_template ( & self ) -> windows:: core:: Result < ToastNotification > {
463
517
//using this to get an instance of XmlDocument
464
518
let toast_xml = XmlDocument :: new ( ) ?;
@@ -520,6 +574,10 @@ impl Toast {
520
574
toast_template. Activated ( handler) ?;
521
575
}
522
576
577
+ if let Some ( handler) = & self . on_dismissed {
578
+ toast_template. Dismissed ( handler) ?;
579
+ }
580
+
523
581
let toast_notifier =
524
582
ToastNotificationManager :: CreateToastNotifierWithId ( & HSTRING :: from ( & self . app_id ) ) ?;
525
583
0 commit comments