cards/client/src/components/websocket.rs

100 lines
2.9 KiB
Rust
Raw Normal View History

2024-07-19 03:11:14 -04:00
use html::Textarea;
use leptos::*;
use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebsocketReturn};
#[component]
pub fn Websocket() -> impl IntoView {
let UseWebsocketReturn {
ready_state,
message,
send,
open,
close,
..
} = use_websocket("ws://0.0.0.0:3030/websocket");
let send_message = move |_| {
send("Hello, world!");
};
let status = move || ready_state.get().to_string();
let connected = move || ready_state.get() == ConnectionReadyState::Open;
let open_connection = move |_| {
open();
};
let close_connection = move |_| {
close();
};
let chat_history_ref = create_node_ref::<Textarea>();
let (chat_history, set_chat_history) = create_signal(vec![]);
fn update_chat_history(&history: &WriteSignal<Vec<String>>, message: String) {
let _ = &history.update(|history: &mut Vec<_>| history.push(message));
}
// handle incoming messages
create_effect(move |_| {
message.with(move |message| {
// Send all messages as strings into chat box
if let Some(m) = message {
update_chat_history(&set_chat_history, format!("{}\n", m));
// Scroll chat textarea to bottom
if let Some(hist) = chat_history_ref.get() {
hist.set_scroll_top(hist.scroll_height());
}
}
})
});
view! {
<div class="bg-slate-500 w-auto">
<hr/>
<p class="p-1">"status: " {status}</p>
<hr/>
<div class="p-1">
<button on:click=open_connection disabled=connected>
"Open"
</button>
<button on:click=close_connection disabled=move || !connected()>
"Close"
</button>
</div>
<hr/>
<div class="p-1">
<input
class="w-96 bg-slate-900 text-slate-200 font-mono rounded-sm"
placeholder="who are you?"
/>
</div>
<hr />
<div class="p-1">
<p>Chat:</p>
<textarea
node_ref=chat_history_ref
class="w-96 h-60 bg-slate-900 text-slate-200 font-mono resize-none rounded-sm"
readonly=true
wrap="soft"
>
{move || chat_history.get()}
</textarea>
<br/>
<input
class="w-96 bg-slate-900 text-slate-200 font-mono rounded-sm"
placeholder="talk shit..."
/>
<br/>
<button on:click=send_message disabled=move || !connected()>
"Send"
</button>
</div>
<hr/>
</div>
}
}