cards/client/src/components/websocket.rs

101 lines
2.7 KiB
Rust
Raw Normal View History

2024-07-23 22:21:05 -04:00
use std::rc::Rc;
2024-07-19 03:11:14 -04:00
use leptos::*;
use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebsocketReturn};
2024-07-21 02:35:13 -04:00
use lib::models::*;
2024-07-24 22:37:18 -04:00
use serde_json::from_str;
2024-07-19 03:11:14 -04:00
2024-07-23 22:21:05 -04:00
#[derive(Clone)]
pub struct WebSocketContext {
pub ready_state: Signal<ConnectionReadyState>,
2024-07-24 22:06:19 -04:00
// pub message: Signal<Option<String>>,
2024-07-24 22:37:18 -04:00
pub send: Rc<dyn Fn(&str)>,
pub open: Rc<dyn Fn()>,
pub close: Rc<dyn Fn()>,
2024-07-23 22:21:05 -04:00
}
impl WebSocketContext {
pub fn new(
ready_state: Signal<ConnectionReadyState>,
2024-07-24 22:06:19 -04:00
// message: Signal<Option<String>>,
2024-07-23 22:21:05 -04:00
send: Rc<dyn Fn(&str)>,
2024-07-24 22:37:18 -04:00
open: Rc<dyn Fn()>,
close: Rc<dyn Fn()>,
2024-07-23 22:21:05 -04:00
) -> Self {
Self {
ready_state,
2024-07-24 22:06:19 -04:00
// message,
2024-07-23 22:21:05 -04:00
send,
2024-07-24 22:37:18 -04:00
open,
close,
2024-07-23 22:21:05 -04:00
}
}
#[inline(always)]
pub fn send(&self, message: &str) {
(self.send)(message)
}
2024-07-24 22:37:18 -04:00
#[inline(always)]
pub fn open(&self) {
(self.open)()
}
#[inline(always)]
pub fn close(&self) {
(self.close)()
}
2024-07-23 22:21:05 -04:00
}
2024-07-19 03:11:14 -04:00
#[component]
pub fn Websocket() -> impl IntoView {
let UseWebsocketReturn {
ready_state,
message,
send,
open,
close,
..
} = use_websocket("ws://0.0.0.0:3030/websocket");
2024-07-23 22:21:05 -04:00
provide_context(WebSocketContext::new(
ready_state,
2024-07-24 22:06:19 -04:00
// message,
2024-07-23 22:21:05 -04:00
Rc::new(send.clone()),
2024-07-24 22:37:18 -04:00
Rc::new(open.clone()),
Rc::new(close.clone()),
2024-07-23 22:21:05 -04:00
));
2024-07-24 22:06:19 -04:00
// Contexts for message handler
let (state_summary, set_state_summary) =
create_signal::<Option<ServerStateSummary>>(Option::None);
let (game_object, set_game_object) = create_signal::<Option<Game>>(Option::None);
let (chat_message, set_chat_message) = create_signal::<Option<ChatMessage>>(Option::None);
2024-07-21 22:48:15 -04:00
2024-07-24 22:06:19 -04:00
provide_context::<ReadSignal<Option<Game>>>(game_object);
provide_context::<ReadSignal<Option<ChatMessage>>>(chat_message);
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
// Message handler
2024-07-19 03:11:14 -04:00
create_effect(move |_| {
2024-07-21 22:48:15 -04:00
message.with(move |message_raw| {
2024-07-19 03:11:14 -04:00
// Send all messages as strings into chat box
2024-07-21 22:48:15 -04:00
if let Some(message) = message_raw {
2024-07-24 22:37:18 -04:00
if let Ok(game) = from_str::<Game>(message) {
2024-07-24 22:06:19 -04:00
set_game_object(Some(game));
2024-07-22 01:32:09 -04:00
} else if let Ok(state_summary) =
2024-07-24 22:37:18 -04:00
from_str::<ServerStateSummary>(message)
2024-07-22 01:32:09 -04:00
{
2024-07-24 22:06:19 -04:00
set_state_summary(Some(state_summary));
2024-07-24 22:37:18 -04:00
} else if let Ok(chat_message) = from_str::<ChatMessage>(message) {
2024-07-24 22:06:19 -04:00
set_chat_message(Some(chat_message));
2024-07-21 22:48:15 -04:00
} else {
2024-07-24 22:06:19 -04:00
logging::log!("Unhandled message: {}", message);
2024-07-19 03:11:14 -04:00
}
}
})
});
2024-07-23 22:21:05 -04:00
}