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}