aboutsummaryrefslogtreecommitdiffstats
path: root/teleterm-web
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-11-22 03:19:02 -0500
committerJesse Luehrs <doy@tozt.net>2019-11-22 03:19:02 -0500
commitd3fe70943c0957c977b44965fe300f6c1b101e32 (patch)
tree1f3347d4059a15307ca79f43842ceabdcbee249f /teleterm-web
parent29c8f1ae0a54e0dcceb3eac42a2e4e033f1918c4 (diff)
downloadteleterm-d3fe70943c0957c977b44965fe300f6c1b101e32.tar.gz
teleterm-d3fe70943c0957c977b44965fe300f6c1b101e32.zip
implement listing and watching on the web side
watching doesn't do anything yet, because the server side doesn't yet know how to send messages to a watch client
Diffstat (limited to 'teleterm-web')
-rw-r--r--teleterm-web/Cargo.toml3
-rw-r--r--teleterm-web/src/lib.rs99
2 files changed, 81 insertions, 21 deletions
diff --git a/teleterm-web/Cargo.toml b/teleterm-web/Cargo.toml
index 7a9a7f9..57a7d25 100644
--- a/teleterm-web/Cargo.toml
+++ b/teleterm-web/Cargo.toml
@@ -11,7 +11,10 @@ publish = false
crate-type = ["cdylib", "rlib"]
[dependencies]
+futures = "0.1.29"
js-sys = "0.3"
seed = "0.4"
+serde = "1"
+serde_json = "1"
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 99c68f1..c78c600 100644
--- a/teleterm-web/src/lib.rs
+++ b/teleterm-web/src/lib.rs
@@ -9,59 +9,116 @@ extern "C" {
fn log(s: &str);
}
+const LIST_URL: &str = "http://127.0.0.1:4145/list";
const WATCH_URL: &str = "ws://127.0.0.1:4145/watch";
+#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
enum Msg {
+ List(seed::fetch::ResponseDataResult<Vec<Session>>),
+ Refresh,
+ StartWatching(String),
Watch(ws::WebSocketEvent),
}
+struct WatchConn {
+ id: String,
+ #[allow(dead_code)] // no idea why it thinks this is dead
+ ws: WebSocket,
+}
+
+#[derive(Clone, Debug, serde::Deserialize)]
+struct Session {
+ id: String,
+ username: String,
+}
+
+#[derive(Default)]
struct Model {
- watch_conn: WebSocket,
+ sessions: Vec<Session>,
+ watch_conn: Option<WatchConn>,
+}
+
+impl Model {
+ fn list(&self) -> impl futures::Future<Item = Msg, Error = Msg> {
+ seed::Request::new(LIST_URL).fetch_json_data(Msg::List)
+ }
+
+ fn watch(&mut self, id: &str, orders: &mut impl Orders<Msg>) {
+ let ws = ws::connect(WATCH_URL, Msg::Watch, orders);
+ self.watch_conn = Some(WatchConn {
+ id: id.to_string(),
+ ws,
+ })
+ }
}
fn init(_: Url, orders: &mut impl Orders<Msg>) -> Init<Model> {
log("init");
- let watch_conn = ws::connect(WATCH_URL, Msg::Watch, orders);
- Init::new(Model { watch_conn })
+ let model = Model::default();
+ orders.perform_cmd(model.list());
+ Init::new(model)
}
-fn update(msg: Msg, model: &mut Model, _orders: &mut impl Orders<Msg>) {
+fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
log("update");
match msg {
+ Msg::List(sessions) => match sessions {
+ Ok(sessions) => {
+ log("got sessions");
+ model.sessions = sessions;
+ }
+ Err(e) => {
+ log(&format!("error getting sessions: {:?}", e));
+ }
+ },
+ Msg::Refresh => {
+ orders.perform_cmd(model.list());
+ }
+ Msg::StartWatching(id) => {
+ log(&format!("watching {}", id));
+ model.watch(&id, orders);
+ }
Msg::Watch(event) => match event {
ws::WebSocketEvent::Connected(_) => {
log("connected");
- match model.watch_conn.send_with_str("ping1") {
- Ok(_) => log("sent ping1 successfully"),
- Err(e) => {
- log(&format!("error sending ping: {:?}", e));
- return;
- }
- }
- match model.watch_conn.send_with_str("ping2") {
- Ok(_) => log("sent ping2 successfully"),
- Err(e) => {
- log(&format!("error sending ping: {:?}", e));
- }
- }
}
ws::WebSocketEvent::Disconnected(_) => {
log("disconnected");
+ model.watch_conn = None;
}
ws::WebSocketEvent::Message(msg) => {
- log(&format!("message {:?}", msg));
+ log(&format!(
+ "message from id {}: {:?}",
+ model.watch_conn.as_ref().unwrap().id,
+ msg
+ ));
}
ws::WebSocketEvent::Error(e) => {
- log(&format!("error {:?}", e));
+ log(&format!(
+ "error from id {}: {:?}",
+ model.watch_conn.as_ref().unwrap().id,
+ e
+ ));
}
},
}
}
-fn view(_model: &Model) -> impl View<Msg> {
+fn view(model: &Model) -> impl View<Msg> {
log("view");
- vec![seed::h1!["it's a seed app"]]
+ let mut list = vec![];
+ for session in &model.sessions {
+ list.push(seed::li![seed::button![
+ simple_ev(Ev::Click, Msg::StartWatching(session.id.clone())),
+ format!("{}: {}", session.username, session.id),
+ ]]);
+ }
+ vec![
+ seed::h1!["it's a seed app"],
+ seed::ul![list],
+ seed::button![simple_ev(Ev::Click, Msg::Refresh), "refresh"],
+ ]
}
#[wasm_bindgen(start)]