use default_struct_builder::DefaultBuilder;
use std::rc::Rc;
use wasm_bindgen::JsValue;
#[derive(Default, Clone, Copy, Eq, PartialEq, Debug)]
pub enum NotificationDirection {
#[default]
Auto,
LeftToRight,
RightToLeft,
}
impl From<NotificationDirection> for web_sys::NotificationDirection {
fn from(direction: NotificationDirection) -> Self {
match direction {
NotificationDirection::Auto => Self::Auto,
NotificationDirection::LeftToRight => Self::Ltr,
NotificationDirection::RightToLeft => Self::Rtl,
}
}
}
#[derive(DefaultBuilder, Clone)]
#[cfg_attr(feature = "ssr", allow(dead_code))]
pub struct UseWebNotificationOptions {
#[builder(into)]
pub(crate) title: String,
#[builder(into)]
body: Option<String>,
direction: NotificationDirection,
#[builder(into)]
language: Option<String>,
#[builder(into)]
tag: Option<String>,
#[builder(into)]
icon: Option<String>,
#[builder(into)]
image: Option<String>,
require_interaction: bool,
#[builder(into)]
renotify: bool,
#[builder(into)]
silent: Option<bool>,
#[builder(into)]
vibrate: Option<Vec<u16>>,
pub(crate) on_click: Rc<dyn Fn(web_sys::Event)>,
pub(crate) on_close: Rc<dyn Fn(web_sys::Event)>,
pub(crate) on_error: Rc<dyn Fn(web_sys::Event)>,
pub(crate) on_show: Rc<dyn Fn(web_sys::Event)>,
}
impl Default for UseWebNotificationOptions {
fn default() -> Self {
Self {
title: "".to_string(),
body: None,
direction: NotificationDirection::default(),
language: None,
tag: None,
icon: None,
image: None,
require_interaction: false,
renotify: false,
silent: None,
vibrate: None,
on_click: Rc::new(|_| {}),
on_close: Rc::new(|_| {}),
on_error: Rc::new(|_| {}),
on_show: Rc::new(|_| {}),
}
}
}
impl From<&UseWebNotificationOptions> for web_sys::NotificationOptions {
fn from(options: &UseWebNotificationOptions) -> Self {
let web_sys_options = Self::new();
web_sys_options.set_dir(options.direction.into());
web_sys_options.set_require_interaction(options.require_interaction);
web_sys_options.set_renotify(options.renotify);
web_sys_options.set_silent(options.silent);
if let Some(body) = &options.body {
web_sys_options.set_body(body);
}
if let Some(icon) = &options.icon {
web_sys_options.set_icon(icon);
}
if let Some(image) = &options.image {
web_sys_options.set_image(image);
}
if let Some(language) = &options.language {
web_sys_options.set_lang(language);
}
if let Some(tag) = &options.tag {
web_sys_options.set_tag(tag);
}
if let Some(vibrate) = &options.vibrate {
web_sys_options.set_vibrate(&vibration_pattern_to_jsvalue(vibrate));
}
web_sys_options
}
}
#[derive(DefaultBuilder, Default)]
#[cfg_attr(feature = "ssr", allow(dead_code))]
pub struct ShowOptions {
#[builder(into)]
pub(crate) title: Option<String>,
#[builder(into)]
body: Option<String>,
#[builder(into)]
direction: Option<NotificationDirection>,
#[builder(into)]
language: Option<String>,
#[builder(into)]
tag: Option<String>,
#[builder(into)]
icon: Option<String>,
#[builder(into)]
image: Option<String>,
#[builder(into)]
require_interaction: Option<bool>,
#[builder(into)]
renotify: Option<bool>,
#[builder(into)]
silent: Option<bool>,
#[builder(into)]
vibrate: Option<Vec<u16>>,
}
#[cfg(not(feature = "ssr"))]
impl ShowOptions {
pub(crate) fn override_notification_options(&self, options: &mut web_sys::NotificationOptions) {
if let Some(direction) = self.direction {
options.set_dir(direction.into());
}
if let Some(require_interaction) = self.require_interaction {
options.set_require_interaction(require_interaction);
}
if let Some(body) = &self.body {
options.set_body(body);
}
if let Some(icon) = &self.icon {
options.set_icon(icon);
}
if let Some(image) = &self.image {
options.set_image(image);
}
if let Some(language) = &self.language {
options.set_lang(language);
}
if let Some(tag) = &self.tag {
options.set_tag(tag);
}
if let Some(renotify) = self.renotify {
options.set_renotify(renotify);
}
if let Some(silent) = self.silent {
options.set_silent(Some(silent));
}
if let Some(vibrate) = &self.vibrate {
options.set_vibrate(&vibration_pattern_to_jsvalue(vibrate));
}
}
}
fn vibration_pattern_to_jsvalue(pattern: &[u16]) -> JsValue {
let array = js_sys::Array::new();
for &value in pattern.iter() {
array.push(&JsValue::from(value));
}
array.into()
}