Skip to main content

wasm_toolkit/
notifications.rs

1use std::{rc::Rc, sync::Arc};
2
3use async_channel::{Receiver, Sender};
4use async_lock::Mutex;
5
6use crate::{WasmToolkitError, WasmToolkitResult, WasmWindow};
7
8pub type NotificationSender = Sender<NotificationType>;
9
10pub struct Notifications {
11    sender: NotificationSender,
12    receiver: Arc<Mutex<Receiver<NotificationType>>>,
13}
14
15impl Notifications {
16    pub fn init() -> Self {
17        let (sender, receiver) = async_channel::unbounded();
18
19        Self {
20            sender,
21            receiver: Arc::new(Mutex::new(receiver)),
22        }
23    }
24
25    pub fn sender(&self) -> NotificationSender {
26        self.sender.clone()
27    }
28
29    pub fn receiver(&self) -> Arc<Mutex<Receiver<NotificationType>>> {
30        self.receiver.clone()
31    }
32
33    pub async fn send(&self, notification: NotificationType) -> WasmToolkitResult<()> {
34        self.sender
35            .clone()
36            .send(notification)
37            .await
38            .map_err(|error| WasmToolkitError::Op(error.to_string()))
39    }
40
41    /// Logs the error to console instead of returning it
42    pub async fn send_final(&self, notification: NotificationType) {
43        if let Err(error) = self.sender.clone().send(notification).await {
44            web_sys::console::log_2(
45                &"NOTIFICATION CHANNEL ERROR: ".into(),
46                &error.to_string().into(),
47            );
48        }
49    }
50
51    pub fn schedule_removal(&self, secs: u32, element_id: String) {
52        let element_id = Rc::new(element_id);
53
54        let element_id = element_id.clone();
55
56        let timeout = gloo_timers::callback::Timeout::new(secs, move || match WasmWindow::new() {
57            Err(_) => {
58                web_sys::console::log_1(
59                    &"Unable to get the window to remove notifications from".into(),
60                );
61            }
62            Ok(window) => match window.document() {
63                Err(_) => {
64                    web_sys::console::error_1(
65                        &"Unable to get the document to remove notifications from".into(),
66                    );
67                }
68                Ok(document) => {
69                    if let Some(element) = document.inner().get_element_by_id(&element_id) {
70                        element.remove();
71                    } else {
72                        web_sys::console::error_2(
73                            &"Element with ID does not exist. Element ID: ".into(),
74                            &element_id.as_str().into(),
75                        );
76                    }
77                }
78            },
79        });
80        timeout.forget();
81    }
82
83    pub fn close_channel(self) -> bool {
84        self.sender.close()
85    }
86}
87
88#[derive(Debug, PartialEq, Eq, Clone)]
89pub enum NotificationType {
90    Success(String),
91    Failure(WasmToolkitError),
92}