diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-11-22 02:18:06 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-11-22 02:18:06 -0500 |
commit | 16f9dfd4a1a1989c06d8e5d88a23d306c0813b68 (patch) | |
tree | d930db439b08e5b3b206f6005fb6cf10e395e658 /teleterm-web | |
parent | 7d2300ff8cd4cc7c8e64f2d13dea66411e0de9fb (diff) | |
download | teleterm-16f9dfd4a1a1989c06d8e5d88a23d306c0813b68.tar.gz teleterm-16f9dfd4a1a1989c06d8e5d88a23d306c0813b68.zip |
start using seed on the web side
Diffstat (limited to 'teleterm-web')
-rw-r--r-- | teleterm-web/Cargo.toml | 2 | ||||
-rw-r--r-- | teleterm-web/src/lib.rs | 99 | ||||
-rw-r--r-- | teleterm-web/src/prelude.rs | 2 | ||||
-rw-r--r-- | teleterm-web/src/ws.rs | 55 |
4 files changed, 120 insertions, 38 deletions
diff --git a/teleterm-web/Cargo.toml b/teleterm-web/Cargo.toml index be9fed2..7a9a7f9 100644 --- a/teleterm-web/Cargo.toml +++ b/teleterm-web/Cargo.toml @@ -11,5 +11,7 @@ publish = false crate-type = ["cdylib", "rlib"] [dependencies] +js-sys = "0.3" +seed = "0.4" wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["ErrorEvent", "MessageEvent", "WebSocket"] } diff --git a/teleterm-web/src/lib.rs b/teleterm-web/src/lib.rs index 4d3e84d..8b770a5 100644 --- a/teleterm-web/src/lib.rs +++ b/teleterm-web/src/lib.rs @@ -1,5 +1,7 @@ -use wasm_bindgen::prelude::*; -use wasm_bindgen::JsCast as _; +mod prelude; +mod ws; + +use crate::prelude::*; #[wasm_bindgen] extern "C" { @@ -7,44 +9,65 @@ extern "C" { fn log(s: &str); } -#[wasm_bindgen(start)] -pub fn main() -> Result<(), JsValue> { - log("loaded"); - - let ws = web_sys::WebSocket::new("ws://127.0.0.1:4145/watch")?; - - let msg_cb = - Closure::wrap(Box::new(move |event: web_sys::MessageEvent| { - log(&format!("message {:?}", event)); - }) as Box<dyn FnMut(web_sys::MessageEvent)>); - ws.set_onmessage(Some(msg_cb.as_ref().unchecked_ref())); - msg_cb.forget(); - - let err_cb = Closure::wrap(Box::new(move |event: web_sys::ErrorEvent| { - log(&format!("error {:?}", event)); - }) as Box<dyn FnMut(web_sys::ErrorEvent)>); - ws.set_onerror(Some(err_cb.as_ref().unchecked_ref())); - err_cb.forget(); - - let cloned_ws = ws.clone(); - let open_cb = Closure::wrap(Box::new(move |_| { - log("opened"); - match cloned_ws.send_with_str("ping1") { - Ok(_) => log("sent ping1 successfully"), - Err(e) => { - log(&format!("error sending ping: {:?}", e)); - return; +const WATCH_URL: &str = "ws://127.0.0.1:4145/watch"; + +#[derive(Clone)] +enum Msg { + Connected(JsValue), + Disconnected(JsValue), + Message(MessageEvent), + Error(JsValue), +} + +struct Model { + ws: WebSocket, +} + +fn init(_: Url, orders: &mut impl Orders<Msg>) -> Init<Model> { + log("init"); + let ws = ws::connect(WATCH_URL, orders); + log("created ws"); + Init::new(Model { ws }) +} + +fn update(msg: Msg, model: &mut Model, _orders: &mut impl Orders<Msg>) { + log("update"); + match msg { + Msg::Connected(_) => { + log("connected"); + match model.ws.send_with_str("ping1") { + Ok(_) => log("sent ping1 successfully"), + Err(e) => { + log(&format!("error sending ping: {:?}", e)); + return; + } } - } - match cloned_ws.send_with_str("ping2") { - Ok(_) => log("sent ping2 successfully"), - Err(e) => { - log(&format!("error sending ping: {:?}", e)); + match model.ws.send_with_str("ping2") { + Ok(_) => log("sent ping2 successfully"), + Err(e) => { + log(&format!("error sending ping: {:?}", e)); + } } } - }) as Box<dyn FnMut(JsValue)>); - ws.set_onopen(Some(open_cb.as_ref().unchecked_ref())); - open_cb.forget(); + Msg::Disconnected(_) => { + log("disconnected"); + } + Msg::Message(msg) => { + log(&format!("message {:?}", msg)); + } + Msg::Error(e) => { + log(&format!("error {:?}", e)); + } + } +} + +fn view(_model: &Model) -> impl View<Msg> { + log("view"); + vec![seed::h1!["it's a seed app"]] +} - Ok(()) +#[wasm_bindgen(start)] +pub fn start() { + log("start"); + seed::App::build(init, update, view).build_and_start(); } diff --git a/teleterm-web/src/prelude.rs b/teleterm-web/src/prelude.rs new file mode 100644 index 0000000..369318c --- /dev/null +++ b/teleterm-web/src/prelude.rs @@ -0,0 +1,2 @@ +pub use seed::prelude::*; +pub use web_sys::*; diff --git a/teleterm-web/src/ws.rs b/teleterm-web/src/ws.rs new file mode 100644 index 0000000..a2ab566 --- /dev/null +++ b/teleterm-web/src/ws.rs @@ -0,0 +1,55 @@ +use crate::prelude::*; +use wasm_bindgen::JsCast as _; + +pub(crate) fn connect( + url: &str, + orders: &mut impl Orders<crate::Msg>, +) -> WebSocket { + let ws = WebSocket::new(url).unwrap(); + + register_ws_handler( + WebSocket::set_onopen, + crate::Msg::Connected, + &ws, + orders, + ); + register_ws_handler( + WebSocket::set_onclose, + crate::Msg::Disconnected, + &ws, + orders, + ); + register_ws_handler( + WebSocket::set_onmessage, + crate::Msg::Message, + &ws, + orders, + ); + register_ws_handler( + WebSocket::set_onerror, + crate::Msg::Error, + &ws, + orders, + ); + + ws +} + +fn register_ws_handler<T, F>( + ws_cb_setter: fn(&WebSocket, Option<&js_sys::Function>), + msg: F, + ws: &web_sys::WebSocket, + orders: &mut impl Orders<crate::Msg>, +) where + T: wasm_bindgen::convert::FromWasmAbi + 'static, + F: Fn(T) -> crate::Msg + 'static, +{ + let (app, msg_mapper) = (orders.clone_app(), orders.msg_mapper()); + + let closure = Closure::new(move |data| { + app.update(msg_mapper(msg(data))); + }); + + ws_cb_setter(ws, Some(closure.as_ref().unchecked_ref())); + closure.forget(); +} |