From 36d086eadac4ebde0a296ed07243447bc1fa979f Mon Sep 17 00:00:00 2001
From: scratchyone <scratchywon@gmail.com>
Date: Wed, 23 Dec 2020 22:24:36 -0500
Subject: [PATCH] Add HTML files to examples

---
 examples/event.html                   | 28 ++++++++++++++++++++
 examples/event.rs                     |  4 ++-
 examples/{index.html => polling.html} |  0
 examples/polling.rs                   |  1 +
 src/lib.rs                            | 37 +++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 examples/event.html
 rename examples/{index.html => polling.html} (100%)

diff --git a/examples/event.html b/examples/event.html
new file mode 100644
index 0000000..d90630a
--- /dev/null
+++ b/examples/event.html
@@ -0,0 +1,28 @@
+<html>
+  <head>
+    <meta charset="UTF-8" />
+    <style>
+      body {
+        background: linear-gradient(
+          135deg,
+          white 0%,
+          white 49%,
+          black 49%,
+          black 51%,
+          white 51%,
+          white 100%
+        );
+        background-repeat: repeat;
+        background-size: 20px 20px;
+        margin: 0px;
+      }
+      canvas {
+        background-color: white;
+      }
+    </style>
+  </head>
+  <script type="module">
+    import init from '../target/event.js';
+    init();
+  </script>
+</html>
diff --git a/examples/event.rs b/examples/event.rs
index 5d4683b..cb9764c 100644
--- a/examples/event.rs
+++ b/examples/event.rs
@@ -22,7 +22,9 @@ fn main() -> Result<(), JsValue> {
         c.send_string("test...").unwrap();
         c.send_binary(vec![20]).unwrap();
     })));
-
+    client.set_on_close(Some(Box::new(|| {
+        info!("Closed");
+    })));
     client.set_on_message(Some(Box::new(
         |c: &wasm_sockets::EventClient, e: wasm_sockets::Message| {
             info!("New Message: {:#?}", e);
diff --git a/examples/index.html b/examples/polling.html
similarity index 100%
rename from examples/index.html
rename to examples/polling.html
diff --git a/examples/polling.rs b/examples/polling.rs
index 1a864c7..8d5029a 100644
--- a/examples/polling.rs
+++ b/examples/polling.rs
@@ -19,6 +19,7 @@ fn main() -> Result<(), JsValue> {
 
     let f = Closure::wrap(Box::new(move || {
         info!("{:#?}", client.borrow_mut().receive());
+        info!("{:#?}", client.borrow().status());
     }) as Box<dyn FnMut()>);
     setInterval(&f, 100); // Create non-blocking loop
     f.forget();
diff --git a/src/lib.rs b/src/lib.rs
index 1fd78cf..3e449f4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,8 @@ pub enum ConnectionStatus {
     Connected,
     /// Disconnected from a server due to an error
     Error(ErrorEvent),
+    /// Disconnected from a server without an error
+    Disconnected,
 }
 
 /// Message is a representation of a websocket message that can be sent or recieved
@@ -59,6 +61,12 @@ impl PollingClient {
             *status_ref.borrow_mut() = ConnectionStatus::Error(e);
         })));
 
+        let status_ref = status.clone();
+
+        client.set_on_close(Some(Box::new(move || {
+            *status_ref.borrow_mut() = ConnectionStatus::Disconnected;
+        })));
+
         client.set_on_message(Some(Box::new(move |c: &EventClient, m: Message| {
             data_ref.borrow_mut().push(m);
         })));
@@ -114,6 +122,8 @@ pub struct EventClient {
     pub on_connection: Rc<RefCell<Option<Box<dyn Fn(&EventClient, JsValue) -> ()>>>>,
     /// The function bound to the on_message event
     pub on_message: Rc<RefCell<Option<Box<dyn Fn(&EventClient, Message) -> ()>>>>,
+    /// The function bound to the on_close event
+    pub on_close: Rc<RefCell<Option<Box<dyn Fn() -> ()>>>>,
 }
 impl EventClient {
     /// Create a new EventClient and connect to a WebSocket URL
@@ -144,6 +154,19 @@ impl EventClient {
         ws.set_onerror(Some(onerror_callback.as_ref().unchecked_ref()));
         onerror_callback.forget();
 
+        let on_close: Rc<RefCell<Option<Box<dyn Fn() -> ()>>>> = Rc::new(RefCell::new(None));
+        let on_close_ref = on_close.clone();
+        let ref_status = status.clone();
+
+        let onclose_callback = Closure::wrap(Box::new(move || {
+            *ref_status.borrow_mut() = ConnectionStatus::Disconnected;
+            if let Some(f) = &*on_close_ref.borrow() {
+                f.as_ref()();
+            }
+        }) as Box<dyn FnMut()>);
+        ws.set_onclose(Some(onclose_callback.as_ref().unchecked_ref()));
+        onclose_callback.forget();
+
         let on_connection: Rc<RefCell<Option<Box<dyn Fn(&EventClient, JsValue) -> ()>>>> =
             Rc::new(RefCell::new(None));
         let on_connection_ref = on_connection.clone();
@@ -164,6 +187,7 @@ impl EventClient {
             on_connection: on_connection.clone(),
             status: status.clone(),
             on_message: on_message.clone(),
+            on_close: on_close.clone(),
         }));
         let client_ref = client.clone();
 
@@ -231,6 +255,7 @@ impl EventClient {
             on_error,
             on_connection,
             on_message,
+            on_close,
             status: status,
         })
     }
@@ -272,6 +297,18 @@ impl EventClient {
     pub fn set_on_message(&mut self, f: Option<Box<dyn Fn(&EventClient, Message) -> ()>>) {
         *self.on_message.borrow_mut() = f;
     }
+    /// Set an on_close event handler.
+    /// This handler will be run when the client disconnects from a server without an error.
+    /// This will overwrite the previous handler.
+    /// You can set [None](std::option) to disable the on_close handler.
+    /// ```
+    /// client.set_on_close(Some(Box::new(|| {
+    ///     info!("Closed");
+    /// })));
+    /// ```
+    pub fn set_on_close(&mut self, f: Option<Box<dyn Fn() -> ()>>) {
+        *self.on_close.borrow_mut() = f;
+    }
 
     /// Send a text message to the server
     /// ```
-- 
GitLab