notifications.rs (1965B)
1 use url::Url; 2 use wasm_bindgen::prelude::*; 3 use wasm_bindgen::JsCast; 4 use web_sys::{Notification, NotificationOptions, NotificationPermission}; 5 6 #[derive(Clone)] 7 pub(crate) struct Notifications { 8 avatar: Option<Url>, 9 displayname: String, 10 content: String, 11 } 12 13 impl Notifications { 14 pub fn new(avatar: Option<Url>, displayname: String, content: String) -> Self { 15 Notifications { 16 avatar, 17 displayname, 18 content, 19 } 20 } 21 22 fn notifications_allowed(&self) -> bool { 23 match Notification::permission() { 24 NotificationPermission::Granted => true, 25 _ => false, 26 } 27 } 28 29 pub fn show(&self) { 30 if !self.notifications_allowed() { 31 let self_clone = self.clone(); 32 let cb = Closure::wrap(Box::new(move || { 33 if self_clone.notifications_allowed() { 34 self_clone.clone().show_actual(); 35 } 36 }) as Box<dyn FnMut()>); 37 38 if let Err(_e) = Notification::request_permission_with_permission_callback( 39 cb.as_ref().unchecked_ref(), 40 ) { 41 // Noop to please clippy/rust compiler 42 } 43 cb.forget(); 44 } else { 45 self.show_actual(); 46 } 47 } 48 49 fn show_actual(&self) { 50 let mut options_0 = NotificationOptions::new() as NotificationOptions; 51 let options_1 = options_0.body(&self.content).tag("daydream") as &mut NotificationOptions; 52 let options = match self.clone().avatar { 53 None => options_1, 54 Some(avatar) => { 55 let url = avatar.to_string(); 56 options_1.icon(&url) 57 } 58 }; 59 if let Err(_e) = Notification::new_with_options(&self.displayname, &options) { 60 // Noop to please clippy/rust compiler 61 // TODO check if we in this case should stop showing notifications 62 } 63 } 64 }