cards/client/src/components/chat.rs

104 lines
3.5 KiB
Rust
Raw Normal View History

2024-07-23 22:45:45 -04:00
use crate::components::websocket::WebSocketContext;
use html::{Input, Textarea};
use leptos::*;
use leptos_use::core::ConnectionReadyState;
use lib::models::*;
2024-07-25 00:18:27 -04:00
use serde_json::to_string;
2024-07-23 22:45:45 -04:00
#[component]
pub fn Chat() -> impl IntoView {
let websocket = expect_context::<WebSocketContext>();
2024-07-24 22:06:19 -04:00
let chat_context = expect_context::<ReadSignal<Option<ChatMessage>>>();
2024-07-23 22:45:45 -04:00
// Chat stuff
let (chat_history, set_chat_history) = create_signal::<Vec<String>>(vec![]);
let chat_history_ref = create_node_ref::<Textarea>();
let chat_input_ref = create_node_ref::<Input>();
fn update_chat_history(&history: &WriteSignal<Vec<String>>, message: String) {
let _ = &history.update(|history: &mut Vec<_>| history.push(message));
}
// Connection status updates in chat window
create_effect(move |_| {
websocket.ready_state.with(move |state| match *state {
ConnectionReadyState::Connecting => {
2024-07-24 19:21:16 -04:00
update_chat_history(
&set_chat_history,
"Connecting to game server...\n".to_string(),
);
2024-07-23 22:45:45 -04:00
}
ConnectionReadyState::Open => {
2024-07-24 19:21:16 -04:00
update_chat_history(&set_chat_history, "Connected!\n".to_string());
2024-07-23 22:45:45 -04:00
}
ConnectionReadyState::Closing => {
2024-07-24 19:21:16 -04:00
update_chat_history(&set_chat_history, "Disconnecting...\n".to_string());
2024-07-23 22:45:45 -04:00
}
ConnectionReadyState::Closed => {
2024-07-24 19:21:16 -04:00
update_chat_history(&set_chat_history, "Disconnected.\n".to_string());
2024-07-23 22:45:45 -04:00
}
})
});
2024-07-24 22:06:19 -04:00
// Handle incoming chat messages
2024-07-23 22:45:45 -04:00
create_effect(move |_| {
2024-07-24 22:06:19 -04:00
chat_context.with(move |chat_message| {
if let Some(message) = chat_message {
update_chat_history(&set_chat_history, format!("{}\n", message.text));
2024-07-23 22:45:45 -04:00
}
})
});
2024-07-24 22:06:19 -04:00
// Handle sending messages
2024-07-23 22:45:45 -04:00
let send_message = move |_| {
2024-07-24 22:06:19 -04:00
websocket.send(
2024-07-25 00:18:27 -04:00
&to_string(&ChatMessage {
2024-07-24 22:06:19 -04:00
text: chat_input_ref.get().unwrap().value(),
})
.unwrap(),
);
2024-07-23 22:45:45 -04:00
chat_input_ref.get().unwrap().set_value("");
logging::log!("Send Message");
};
// Keep chat scrolled to the bottom
create_effect(move |_| {
chat_history.with(move |_| {
// Scroll chat textarea to bottom
if let Some(hist) = chat_history_ref.get() {
hist.set_scroll_top(hist.scroll_height());
}
})
});
view! {
<div class="p-1">
<h2 class="text-2xl">Chat:</h2>
<textarea
node_ref=chat_history_ref
class="w-96 h-60 font-mono rounded-sm resize-none bg-slate-900 text-slate-200"
readonly=true
wrap="soft"
>
{move || chat_history.get()}
</textarea>
<br/>
<span>
<input
class="w-80 h-11 font-mono rounded-sm bg-slate-900 text-slate-200"
placeholder="talk shit..."
node_ref=chat_input_ref
on:change=send_message.clone()
/>
<input
class="py-2 px-4 pl-4 font-bold text-white rounded border-b-4 bg-slate-600 border-slate-800 hover:bg-slate-700 hover:border-slate-500"
type="submit"
value="Send"
on:change=send_message.clone()
/>
</span>
<br/>
</div>
}
}