bitque/jirs-client/src/api.rs

146 lines
4.3 KiB
Rust
Raw Normal View History

2020-03-31 23:49:46 +02:00
use seed::Method;
2020-04-05 15:15:09 +02:00
use wasm_bindgen::prelude::*;
2020-03-31 23:49:46 +02:00
2020-04-05 15:15:09 +02:00
use jirs_data::{UpdateIssuePayload, WsMsg};
2020-03-31 22:05:18 +02:00
2020-03-30 14:26:25 +02:00
use crate::shared::host_client;
use crate::Msg;
2020-04-05 15:15:09 +02:00
use seed::prelude::Closure;
use std::sync::Once;
use wasm_bindgen::JsCast;
2020-03-30 14:26:25 +02:00
pub async fn fetch_current_project(host_url: String) -> Result<Msg, Msg> {
match host_client(host_url, "/project") {
Ok(client) => client.fetch_string(Msg::CurrentProjectResult).await,
Err(e) => Err(Msg::InternalFailure(e)),
}
}
pub async fn fetch_current_user(host_url: String) -> Result<Msg, Msg> {
match host_client(host_url, "/currentUser") {
Ok(client) => client.fetch_string(Msg::CurrentUserResult).await,
Err(e) => Err(Msg::InternalFailure(e)),
}
}
2020-03-31 22:05:18 +02:00
pub async fn update_issue(
host_url: String,
id: i32,
payload: UpdateIssuePayload,
) -> Result<Msg, Msg> {
2020-03-31 23:49:46 +02:00
match host_client(host_url, format!("/issues/{id}", id = id).as_str()) {
2020-03-31 22:05:18 +02:00
Ok(client) => {
client
2020-03-31 23:49:46 +02:00
.method(Method::Put)
.header("Content-Type", "application/json")
2020-03-31 22:05:18 +02:00
.body_json(&payload)
2020-04-02 16:14:07 +02:00
.fetch_string(Msg::IssueUpdateResult)
2020-03-31 22:05:18 +02:00
.await
}
Err(e) => return Ok(Msg::InternalFailure(e)),
}
}
2020-04-04 17:42:02 +02:00
pub async fn delete_issue(host_url: String, id: i32) -> Result<Msg, Msg> {
match host_client(host_url, format!("/issues/{id}", id = id).as_str()) {
Ok(client) => {
client
.method(Method::Delete)
.header("Content-Type", "application/json")
.fetch_string(Msg::IssueDeleteResult)
.await
}
Err(e) => return Ok(Msg::InternalFailure(e)),
}
}
2020-04-05 15:15:09 +02:00
pub struct WebSocket {
ws: web_sys::WebSocket,
queue: Vec<WsMsg>,
}
impl Default for WebSocket {
fn default() -> WebSocket {
use js_sys::*;
use seed::prelude::*;
use web_sys::*;
let native = web_sys::WebSocket::new("ws://localhost:5000/ws/").unwrap();
native.set_binary_type(web_sys::BinaryType::Arraybuffer);
let onmessage_callback =
Closure::wrap(Box::new(move |e: MessageEvent| {}) as Box<dyn FnMut(MessageEvent)>);
native.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
onmessage_callback.forget();
// let onerror_callback = Closure::wrap(Box::new(move |e: ErrorEvent| {
// seed::log!("error event: {:?}", e);
// }) as Box<dyn FnMut(ErrorEvent)>);
// native.set_onerror(Some(onerror_callback.as_ref().unchecked_ref()));
// onerror_callback.forget();
let cloned_ws = native.clone();
let onopen_callback = Closure::wrap(Box::new(move |_| {
seed::log!("socket opened");
match cloned_ws.send_with_str("ping") {
Ok(_) => seed::log!("message successfully sent"),
Err(err) => seed::log!("error sending message: {:?}", err),
}
}) as Box<dyn FnMut(JsValue)>);
native.set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
onopen_callback.forget();
Self {
ws: native,
queue: vec![],
}
}
}
impl WebSocket {
pub fn send_with_u8_array(&self, buffer: &[u8]) {
use seed::*;
self.ws
.send_with_u8_array(buffer)
.unwrap_or_else(|e| error!(e));
}
pub fn send(&mut self) {
use bincode;
for msg in self.queue.iter() {
let encoded: Vec<u8> = bincode::serialize(msg).unwrap();
self.send_with_u8_array(encoded.as_slice());
}
self.queue.clear();
}
}
static INIT_WS: Once = Once::new();
static mut WS: Option<WebSocket> = None;
pub fn ws() -> &'static mut WebSocket {
unsafe {
INIT_WS.call_once(|| WS = Some(WebSocket::default()));
let ws_ping = Box::new(|| match WS.as_mut().map(|ws| ws.ws.ready_state()) {
Some(0) => {}
Some(1) => {
ws_send(WsMsg::Ping);
WS.as_mut().unwrap().send();
}
_ => {
WS = Some(WebSocket::default());
}
}) as Box<dyn Fn()>;
seed::set_interval(ws_ping, 10_000);
WS.as_mut().unwrap()
}
}
// pub fn ws_received() {}
//
pub fn ws_send(msg: jirs_data::WsMsg) {
ws().queue.push(msg);
}