nw_sys/chrome/
notifications.rs

1//!
2//! Chrome system notification API, allows creation of desktop / system notifications.
3//!
4//!  # Synopsis
5//! ```rust
6//! use nw_sys::notifications;
7//!
8//! // Create basic notification
9//! let options = notifications::Options::new()
10//!     .title("Title text")
11//!     .icon_url("/resources/icons/tray-icon@2x.png")
12//!     .set_type(notifications::TemplateType::Basic)
13//!     .message("Message Text")
14//!     .context_message("Context Message");
15//!
16//! notifications::create(None, &options, None);
17//!
18//! // Create notification with buttons
19//! let button1 = notifications::Button::new()
20//!     .title("Button A")
21//!     .icon_url("/resources/icons/tray-icon@2x.png");
22//!
23//! let button2 = notifications::Button::new()
24//!     .title("Button B")
25//!     .icon_url("/resources/icons/tray-icon@2x.png");
26//!
27//! let options = notifications::Options::new()
28//!     .title("Title text")
29//!     .icon_url("/resources/icons/tray-icon@2x.png")
30//!     .set_type(notifications::TemplateType::Basic)
31//!     .message("Message Text")
32//!     .buttons(vec![button1, button2]);
33//!
34//! notifications::create(None, &options, None);
35//!
36//! // Create image notification
37//! let options = notifications::Options::new()
38//!     .title("Title text")
39//!     .icon_url("/resources/icons/tray-icon@2x.png")
40//!     .set_type(notifications::TemplateType::Image)
41//!     .message("Message Text")
42//!     .image_url("/resources/setup/document.png");
43//!
44//! notifications::create(None, &options, None);
45//!
46//! // Create notification with items
47//! let item1 = notifications::Item::new()
48//!     .title("Item A")
49//!     .message("Mesage A");
50//! let item2 = notifications::Item::new()
51//!     .title("Item B")
52//!     .message("Mesage B");
53//!
54//! let options = notifications::Options::new()
55//!     .title("Title text")
56//!     .icon_url("/resources/icons/tray-icon@2x.png")
57//!     .set_type(notifications::TemplateType::List)
58//!     .message("Message Text")
59//!     .items(vec![item1, item2]);
60//!
61//! notifications::create(None, &options, None);
62//!
63//! // Create notification with progress
64//! let options = notifications::Options::new()
65//!     .title("Title text")
66//!     .icon_url("/resources/icons/tray-icon@2x.png")
67//!     .set_type(notifications::TemplateType::Progress)
68//!     .message("Mesage text")
69//!     .progress(50);
70//! notifications::create(None, &options, None);
71//!  
72//! ```
73//!
74
75use crate::options::OptionsTrait;
76use js_sys::{Array, Function, Object};
77use wasm_bindgen::prelude::*;
78
79#[wasm_bindgen]
80extern "C" {
81    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="create")]
82    fn create_impl(options: &Options);
83
84    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="create")]
85    fn create_with_id_impl(id: &str, options: &Options);
86
87    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="create")]
88    fn create_with_callback_impl(options: &Options, callback: &Function);
89
90    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="create")]
91    fn create_with_id_and_callback_impl(id: &str, options: &Options, callback: &Function);
92
93    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="clear")]
94    fn clear_impl(id: &str);
95
96    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="clear")]
97    fn clear_with_callback_impl(id: &str, callback: &Function);
98
99    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="getAll")]
100    /// Retrieves all the notifications of this app or extension.
101    ///
102    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#method-getAll)
103    ///
104    pub fn get_all(callback: &Function);
105
106    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="getPermissionLevel")]
107    /// Retrieves whether the user has enabled notifications from this app or extension.
108    ///
109    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#method-getPermissionLevel)
110    ///
111    pub fn get_permission_level(callback: &Function);
112
113    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="update")]
114    fn update_impl(id: &str, options: &Options);
115
116    #[wasm_bindgen(js_namespace=["chrome", "notifications"], js_name="update")]
117    fn update_with_callback_impl(id: &str, options: &Options, callback: &Function);
118
119    #[wasm_bindgen(js_namespace=["chrome", "notifications", "onButtonClicked"], js_name="addListener")]
120    /// The user pressed a button in the notification.
121    ///
122    /// The `callback` parameter looks like:
123    /// (notification_id: String, button_index: u16) => ()
124    ///
125    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#event-onButtonClicked)
126    pub fn on_button_clicked(callback: &Function);
127
128    #[wasm_bindgen(js_namespace=["chrome", "notifications", "onClicked"], js_name="addListener")]
129    /// The user clicked in a non-button area of the notification.
130    ///
131    /// The `callback` parameter looks like:
132    /// (notification_id: String) => ()
133    ///
134    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#event-onClicked)
135    pub fn on_clicked(callback: &Function);
136
137    #[wasm_bindgen(js_namespace=["chrome", "notifications", "onClosed"], js_name="addListener")]
138    /// The notification closed, either by the system or by user action.
139    ///
140    /// The `callback` parameter looks like:
141    /// (notification_id: String, by_user:bool) => ()
142    ///
143    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#event-onClosed)
144    pub fn on_closed(callback: &Function);
145
146    #[wasm_bindgen(js_namespace=["chrome", "notifications", "onPermissionLevelChanged"], js_name="addListener")]
147    /// The user changes the permission level.
148    /// As of Chrome 47, only ChromeOS has UI that dispatches this event.
149    ///
150    /// The `callback` parameter looks like:
151    /// (level: JsValue ) => ()
152    ///
153    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#event-onPermissionLevelChanged)
154    pub fn on_permission_level_changed(callback: &Function);
155
156    /// Notification Options
157    ///
158    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#type-NotificationOptions)
159    #[wasm_bindgen(extends = Object)]
160    #[derive(Debug, Clone, PartialEq, Eq)]
161    pub type Options;
162
163    /// Notification Button
164    ///
165    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#type-NotificationButton)
166    #[wasm_bindgen(extends = Object)]
167    #[derive(Debug, Clone, PartialEq, Eq)]
168    pub type Button;
169
170    /// Notification Item
171    ///
172    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#type-NotificationItem)
173    #[wasm_bindgen(extends = Object)]
174    #[derive(Debug, Clone, PartialEq, Eq)]
175    pub type Item;
176}
177
178impl OptionsTrait for Options {}
179impl OptionsTrait for Button {}
180impl OptionsTrait for Item {}
181
182/// Notification template type
183pub enum TemplateType {
184    Basic,
185    Image,
186    List,
187    Progress,
188}
189
190impl std::fmt::Display for TemplateType {
191    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192        match self {
193            Self::Basic => write!(f, "Basic"),
194            Self::Image => write!(f, "Image"),
195            Self::List => write!(f, "List"),
196            Self::Progress => write!(f, "Progress"),
197        }
198    }
199}
200
201impl From<TemplateType> for JsValue {
202    fn from(value: TemplateType) -> Self {
203        Self::from(value.to_string().to_lowercase())
204    }
205}
206
207impl Button {
208    /// Button icons not visible for Mac OS X users.
209    ///
210    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationButton-iconUrl)
211    pub fn icon_url(self, url: &str) -> Self {
212        self.set("iconUrl", JsValue::from(url))
213    }
214
215    /// Button text
216    ///
217    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationButton-title)
218    pub fn title(self, title: &str) -> Self {
219        self.set("title", JsValue::from(title))
220    }
221}
222
223impl Item {
224    /// Additional details about this item.
225    ///
226    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationItem-message)
227    pub fn message(self, message: &str) -> Self {
228        self.set("message", JsValue::from(message))
229    }
230
231    /// Title of one item of a list notification.
232    ///
233    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationItem-title)
234    pub fn title(self, title: &str) -> Self {
235        self.set("title", JsValue::from(title))
236    }
237}
238
239impl Options {
240    ///
241    /// *Note* : The app icon mask is not visible for Mac OS X users.
242    ///
243    /// A URL to the app icon mask.
244    /// URLs have the same restrictions as iconUrl.
245    /// The app icon mask should be in alpha channel, as only the alpha channel
246    /// of the image will be considered.
247    ///
248    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-appIconMaskUrl)
249    pub fn app_icon_mask_url(self, url: &str) -> Self {
250        self.set("appIconMaskUrl", JsValue::from(url))
251    }
252
253    /// Text and icons for up to two notification action buttons.
254    ///
255    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-buttons)
256    pub fn buttons(self, buttons: Vec<Button>) -> Self {
257        let array = Array::new();
258        for button in buttons {
259            array.push(&JsValue::from(button));
260        }
261        self.set("buttons", JsValue::from(array))
262    }
263
264    /// Alternate notification content with a lower-weight font.
265    ///
266    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-contextMessage)
267    pub fn context_message(self, context_message: &str) -> Self {
268        self.set("contextMessage", JsValue::from(context_message))
269    }
270
271    /// A timestamp associated with the notification, in milliseconds past the epoch (e.g. Date.now() + n).
272    ///
273    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-eventTime)
274    pub fn event_time(self, event_time: u32) -> Self {
275        self.set("eventTime", JsValue::from(event_time))
276    }
277
278    /// A URL to the sender's avatar, app icon, or a thumbnail for image notifications.
279    ///
280    /// URLs can be a data URL, a blob URL, or a URL relative to a
281    /// resource within this extension's .crx file Required for [notifications.create()](self::create) method.
282    ///
283    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-iconUrl)
284    pub fn icon_url(self, icon_url: &str) -> Self {
285        self.set("iconUrl", JsValue::from(icon_url))
286    }
287
288    /// The image is not visible for Mac OS X users.
289    ///
290    /// A URL to the image thumbnail for image-type notifications.
291    /// URLs have the same restrictions as [iconUrl](self::Options#method.icon_url).
292    ///
293    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-imageUrl)
294    pub fn image_url(self, image_url: &str) -> Self {
295        self.set("imageUrl", JsValue::from(image_url))
296    }
297
298    /// Items for multi-item notifications.
299    /// Users on Mac OS X only see the first item.
300    ///
301    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-items)
302    pub fn items(self, items: Vec<Item>) -> Self {
303        let array = Array::new();
304        for item in items {
305            array.push(&JsValue::from(item));
306        }
307        self.set("items", JsValue::from(array))
308    }
309
310    /// Main notification content.
311    /// Required for [notifications.create](self::create) method.
312    ///
313    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-message)
314    pub fn message(self, message: &str) -> Self {
315        self.set("message", JsValue::from(message))
316    }
317
318    /// Priority ranges from -2 to 2. -2 is lowest priority. 2 is highest.
319    /// Zero is default.
320    /// On platforms that don't support a notification center
321    /// (Windows, Linux & Mac), -2 and -1 result in an error as notifications with
322    /// those priorities will not be shown at all.
323    ///
324    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-priority)
325    pub fn priority(self, priority: i8) -> Self {
326        self.set("priority", JsValue::from(priority))
327    }
328
329    /// Current progress ranges from 0 to 100.
330    ///
331    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-progress)
332    pub fn progress(self, progress: u8) -> Self {
333        self.set("progress", JsValue::from(progress))
334    }
335
336    /// Indicates that the notification should remain visible on screen until
337    /// the user activates or dismisses the notification. This defaults to false.
338    ///
339    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-requireInteraction)
340    pub fn require_interaction(self, require_interaction: bool) -> Self {
341        self.set("requireInteraction", JsValue::from(require_interaction))
342    }
343
344    /// Indicates that no sounds or vibrations should be made when the
345    /// notification is being shown. This defaults to false.
346    ///
347    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-silent)
348    pub fn silent(self, silent: bool) -> Self {
349        self.set("silent", JsValue::from(silent))
350    }
351
352    /// Title of the notification (e.g. sender name for email).
353    /// Required for [notifications.create](self::create) method.
354    ///
355    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-title)
356    pub fn title(self, title: &str) -> Self {
357        self.set("title", JsValue::from(title))
358    }
359
360    /// Which type of notification to display.
361    ///
362    /// Required for [notifications.create](self::create) method.
363    ///
364    /// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#property-NotificationOptions-type)
365    pub fn set_type(self, template_type: TemplateType) -> Self {
366        self.set("type", template_type.into())
367    }
368}
369
370/// Creates and displays a notification.
371///
372/// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#method-create)
373///
374pub fn create(id: Option<String>, options: &Options, callback: Option<&Function>) {
375    match (id, callback) {
376        (Some(id), Some(callback)) => {
377            create_with_id_and_callback_impl(&id, options, callback);
378        }
379        (Some(id), None) => {
380            create_with_id_impl(&id, options);
381        }
382        (None, Some(callback)) => {
383            create_with_callback_impl(options, callback);
384        }
385        (None, None) => {
386            create_impl(options);
387        }
388    }
389}
390
391/// Clears the specified notification.
392///
393/// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#method-clear)
394///
395pub fn clear(id: &str, callback: Option<&Function>) {
396    if let Some(callback) = callback {
397        clear_with_callback_impl(id, callback);
398    } else {
399        clear_impl(id);
400    }
401}
402
403/// Updates an existing notification.
404///
405/// [Chrome Doc](https://developer.chrome.com/docs/extensions/reference/notifications/#method-update)
406///
407pub fn update(id: &str, options: &Options, callback: Option<&Function>) {
408    if let Some(callback) = callback {
409        update_with_callback_impl(id, options, callback);
410    } else {
411        update_impl(id, options);
412    }
413}