leptos_use_web_notification/options.rs
1use default_struct_builder::DefaultBuilder;
2use std::rc::Rc;
3use wasm_bindgen::JsValue;
4
5#[derive(Default, Clone, Copy, Eq, PartialEq, Debug)]
6pub enum NotificationDirection {
7 #[default]
8 Auto,
9 LeftToRight,
10 RightToLeft,
11}
12
13impl From<NotificationDirection> for web_sys::NotificationDirection {
14 fn from(direction: NotificationDirection) -> Self {
15 match direction {
16 NotificationDirection::Auto => Self::Auto,
17 NotificationDirection::LeftToRight => Self::Ltr,
18 NotificationDirection::RightToLeft => Self::Rtl,
19 }
20 }
21}
22
23/// Options for [`use_web_notification_with_options`](crate::use_web_notification_with_options).
24/// See [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/API/notification) for more info.
25///
26/// The following implementations are missing:
27#[derive(DefaultBuilder, Clone)]
28#[cfg_attr(feature = "ssr", allow(dead_code))]
29pub struct UseWebNotificationOptions {
30 /// The title property of the Notification interface indicates
31 /// the title of the notification
32 #[builder(into)]
33 pub(crate) title: String,
34
35 /// The body string of the notification as specified in the constructor's
36 /// options parameter.
37 #[builder(into)]
38 body: Option<String>,
39
40 /// The text direction of the notification as specified in the constructor's
41 /// options parameter. Can be `LeftToRight`, `RightToLeft` or `Auto` (default).
42 /// See [`web_sys::NotificationDirection`] for more info.
43 direction: NotificationDirection,
44
45 /// The language code of the notification as specified in the constructor's
46 /// options parameter.
47 #[builder(into)]
48 language: Option<String>,
49
50 /// The ID of the notification(if any) as specified in the constructor's options
51 /// parameter.
52 #[builder(into)]
53 tag: Option<String>,
54
55 /// The URL of the image used as an icon of the notification as specified
56 /// in the constructor's options parameter.
57 #[builder(into)]
58 icon: Option<String>,
59
60 /// The URL of the image to be displayed as part of the notification as specified
61 /// in the constructor's options parameter.
62 #[builder(into)]
63 image: Option<String>,
64
65 /// A boolean value indicating that a notification should remain active until the
66 /// user clicks or dismisses it, rather than closing automatically.
67 require_interaction: bool,
68
69 /// A boolean value specifying whether the user should be notified after a new notification replaces an old one.
70 /// The default is `false`, which means they won't be notified. If `true`, then `tag` also must be set.
71 #[builder(into)]
72 renotify: bool,
73
74 /// A boolean value specifying whether the notification should be silent, regardless of the device settings.
75 /// The default is `null`, which means the notification is not silent. If `true`, then the notification will be silent.
76 #[builder(into)]
77 silent: Option<bool>,
78
79 /// A `Vec<u16>` specifying the vibration pattern in milliseconds for vibrating and not vibrating.
80 /// The last entry can be a vibration since it stops automatically after each period.
81 #[builder(into)]
82 vibrate: Option<Vec<u16>>,
83
84 /// Called when the user clicks on displayed `Notification`.
85 pub(crate) on_click: Rc<dyn Fn(web_sys::Event)>,
86
87 /// Called when the user closes a `Notification`.
88 pub(crate) on_close: Rc<dyn Fn(web_sys::Event)>,
89
90 /// Called when something goes wrong with a `Notification`
91 /// (in many cases an error preventing the notification from being displayed.)
92 pub(crate) on_error: Rc<dyn Fn(web_sys::Event)>,
93
94 /// Called when a `Notification` is displayed
95 pub(crate) on_show: Rc<dyn Fn(web_sys::Event)>,
96}
97
98impl Default for UseWebNotificationOptions {
99 fn default() -> Self {
100 Self {
101 title: "".to_string(),
102 body: None,
103 direction: NotificationDirection::default(),
104 language: None,
105 tag: None,
106 icon: None,
107 image: None,
108 require_interaction: false,
109 renotify: false,
110 silent: None,
111 vibrate: None,
112 on_click: Rc::new(|_| {}),
113 on_close: Rc::new(|_| {}),
114 on_error: Rc::new(|_| {}),
115 on_show: Rc::new(|_| {}),
116 }
117 }
118}
119
120impl From<&UseWebNotificationOptions> for web_sys::NotificationOptions {
121 fn from(options: &UseWebNotificationOptions) -> Self {
122 let web_sys_options = Self::new();
123
124 web_sys_options.set_dir(options.direction.into());
125 web_sys_options.set_require_interaction(options.require_interaction);
126 web_sys_options.set_renotify(options.renotify);
127 web_sys_options.set_silent(options.silent);
128
129 if let Some(body) = &options.body {
130 web_sys_options.set_body(body);
131 }
132
133 if let Some(icon) = &options.icon {
134 web_sys_options.set_icon(icon);
135 }
136
137 if let Some(image) = &options.image {
138 web_sys_options.set_image(image);
139 }
140
141 if let Some(language) = &options.language {
142 web_sys_options.set_lang(language);
143 }
144
145 if let Some(tag) = &options.tag {
146 web_sys_options.set_tag(tag);
147 }
148
149 if let Some(vibrate) = &options.vibrate {
150 web_sys_options.set_vibrate(&vibration_pattern_to_jsvalue(vibrate));
151 }
152 web_sys_options
153 }
154}
155
156/// Options for [`UseWebNotificationReturn::show`](crate::UseWebNotificationReturn::show).
157///
158/// This can be used to override options passed to [`use_web_notification`](crate::use_web_notification).
159/// See [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/API/notification) for more info.
160///
161/// The following implementations are missing:
162#[derive(DefaultBuilder, Default)]
163#[cfg_attr(feature = "ssr", allow(dead_code))]
164pub struct ShowOptions {
165 /// The title property of the Notification interface indicates
166 /// the title of the notification
167 #[builder(into)]
168 pub(crate) title: Option<String>,
169
170 /// The body string of the notification as specified in the constructor's
171 /// options parameter.
172 #[builder(into)]
173 body: Option<String>,
174
175 /// The text direction of the notification as specified in the constructor's
176 /// options parameter. Can be `LeftToRight`, `RightToLeft` or `Auto` (default).
177 /// See [`web_sys::NotificationDirection`] for more info.
178 #[builder(into)]
179 direction: Option<NotificationDirection>,
180
181 /// The language code of the notification as specified in the constructor's
182 /// options parameter.
183 #[builder(into)]
184 language: Option<String>,
185
186 /// The ID of the notification(if any) as specified in the constructor's options
187 /// parameter.
188 #[builder(into)]
189 tag: Option<String>,
190
191 /// The URL of the image used as an icon of the notification as specified
192 /// in the constructor's options parameter.
193 #[builder(into)]
194 icon: Option<String>,
195
196 /// The URL of the image to be displayed as part of the notification as specified
197 /// in the constructor's options parameter.
198 #[builder(into)]
199 image: Option<String>,
200
201 /// A boolean value indicating that a notification should remain active until the
202 /// user clicks or dismisses it, rather than closing automatically.
203 #[builder(into)]
204 require_interaction: Option<bool>,
205
206 /// A boolean value specifying whether the user should be notified after a new notification replaces an old one.
207 /// The default is `false`, which means they won't be notified. If `true`, then `tag` also must be set.
208 #[builder(into)]
209 renotify: Option<bool>,
210
211 /// A boolean value specifying whether the notification should be silent, regardless of the device settings.
212 /// The default is `null`, which means the notification is not silent. If `true`, then the notification will be silent.
213 #[builder(into)]
214 silent: Option<bool>,
215
216 /// A `Vec<u16>` specifying the vibration pattern in milliseconds for vibrating and not vibrating.
217 /// The last entry can be a vibration since it stops automatically after each period.
218 #[builder(into)]
219 vibrate: Option<Vec<u16>>,
220}
221
222#[cfg(not(feature = "ssr"))]
223impl ShowOptions {
224 pub(crate) fn override_notification_options(&self, options: &mut web_sys::NotificationOptions) {
225 if let Some(direction) = self.direction {
226 options.set_dir(direction.into());
227 }
228
229 if let Some(require_interaction) = self.require_interaction {
230 options.set_require_interaction(require_interaction);
231 }
232
233 if let Some(body) = &self.body {
234 options.set_body(body);
235 }
236
237 if let Some(icon) = &self.icon {
238 options.set_icon(icon);
239 }
240
241 if let Some(image) = &self.image {
242 options.set_image(image);
243 }
244
245 if let Some(language) = &self.language {
246 options.set_lang(language);
247 }
248
249 if let Some(tag) = &self.tag {
250 options.set_tag(tag);
251 }
252
253 if let Some(renotify) = self.renotify {
254 options.set_renotify(renotify);
255 }
256
257 if let Some(silent) = self.silent {
258 options.set_silent(Some(silent));
259 }
260
261 if let Some(vibrate) = &self.vibrate {
262 options.set_vibrate(&vibration_pattern_to_jsvalue(vibrate));
263 }
264 }
265}
266
267/// Helper function to convert a slice of `u16` into a `JsValue` array that represents a vibration pattern
268fn vibration_pattern_to_jsvalue(pattern: &[u16]) -> JsValue {
269 let array = js_sys::Array::new();
270 for &value in pattern.iter() {
271 array.push(&JsValue::from(value));
272 }
273 array.into()
274}