break out chat

This commit is contained in:
Adam 2024-07-23 22:45:45 -04:00
parent 0021c0be79
commit b88ecb29c0
4 changed files with 121 additions and 113 deletions

View file

@ -0,0 +1,105 @@
use crate::components::websocket::WebSocketContext;
use html::{Input, Textarea};
use leptos::*;
use leptos_use::core::ConnectionReadyState;
use lib::models::*;
#[component]
pub fn Chat() -> impl IntoView {
let websocket = expect_context::<WebSocketContext>();
// 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 => {
update_chat_history(&set_chat_history, format!("Connecting to game server...\n"));
}
ConnectionReadyState::Open => {
update_chat_history(&set_chat_history, format!("Connected!\n"));
}
ConnectionReadyState::Closing => {
update_chat_history(&set_chat_history, format!("Disconnecting...\n"));
}
ConnectionReadyState::Closed => {
update_chat_history(&set_chat_history, format!("Disconnected.\n"));
}
})
});
// let chat = move || {
// if let Some(ye) = chat_input_ref.get() {
// &websocket.send(&ye.value());
// };
// };
// This should be done elsewhere
create_effect(move |_| {
websocket.message.with(move |message_raw| {
// Send all messages as strings into chat box
if let Some(message) = message_raw {
if let Ok(_game) = serde_json::from_str::<Game>(message) {
logging::log!("Game object received at chat component");
} else if let Ok(_) = serde_json::from_str::<ServerStateSummary>(message) {
logging::log!("State Summary received at chat component");
} else {
update_chat_history(&set_chat_history, format!("{}\n", message));
}
}
})
});
let send_message = move |_| {
websocket.send(&chat_input_ref.get().unwrap().value());
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>
}
}

View file

@ -1 +1,2 @@
pub mod chat;
pub mod websocket; pub mod websocket;

View file

@ -1,6 +1,5 @@
use std::rc::Rc; use std::rc::Rc;
use html::{Input, Textarea};
use leptos::*; use leptos::*;
use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebsocketReturn}; use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebsocketReturn};
use lib::models::*; use lib::models::*;
@ -109,7 +108,7 @@ pub fn Websocket() -> impl IntoView {
}); });
view! { view! {
<div class="w-auto bg-slate-500"> <div class="w-auto">
<hr/> <hr/>
<h2 class="p-1 text-2xl">Server Info:</h2> <h2 class="p-1 text-2xl">Server Info:</h2>
<p class="p-1">"Users Online: " {online_users}</p> <p class="p-1">"Users Online: " {online_users}</p>
@ -122,115 +121,10 @@ pub fn Websocket() -> impl IntoView {
<button on:click=close_connection disabled=move || !connected()> <button on:click=close_connection disabled=move || !connected()>
"Disconnect" "Disconnect"
</button> </button>
</div>
<hr/>
<Auth/>
<hr/>
<Chat/>
<hr/>
<button on:click=new_game_test disabled=move || !connected()> <button on:click=new_game_test disabled=move || !connected()>
"Test New Game" "Test New Game"
</button> </button>
</div> </div>
}
}
#[component]
pub fn Chat() -> impl IntoView {
let websocket = expect_context::<WebSocketContext>();
// 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 => {
update_chat_history(&set_chat_history, format!("Connecting to game server...\n"));
}
ConnectionReadyState::Open => {
update_chat_history(&set_chat_history, format!("Connected!\n"));
}
ConnectionReadyState::Closing => {
update_chat_history(&set_chat_history, format!("Disconnecting...\n"));
}
ConnectionReadyState::Closed => {
update_chat_history(&set_chat_history, format!("Disconnected.\n"));
}
})
});
// let chat = move || {
// if let Some(ye) = chat_input_ref.get() {
// &websocket.send(&ye.value());
// };
// };
// This should be done elsewhere
create_effect(move |_| {
websocket.message.with(move |message_raw| {
// Send all messages as strings into chat box
if let Some(message) = message_raw {
if let Ok(_game) = serde_json::from_str::<Game>(message) {
logging::log!("Game object received at chat component");
} else if let Ok(_) = serde_json::from_str::<ServerStateSummary>(message) {
logging::log!("State Summary received at chat component");
} else {
update_chat_history(&set_chat_history, format!("{}\n", message));
}
}
})
});
let send_message = move |_| {
websocket.send(&chat_input_ref.get().unwrap().value());
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> </div>
} }
} }

View file

@ -1,4 +1,5 @@
use crate::components::websocket::Websocket; use crate::components::websocket::*;
use crate::components::chat::*;
use leptos::*; use leptos::*;
/// Default Home Page /// Default Home Page
@ -26,9 +27,16 @@ pub fn Home() -> impl IntoView {
<div class="container m-auto"> <div class="container m-auto">
<h1 class="text-6xl text-slate-300">"Cards For Humanity"</h1> <h1 class="text-6xl text-slate-300">"Cards For Humanity"</h1>
<div class="bg-slate-500">
<Websocket/> <Websocket/>
<hr/>
<Auth/>
<hr/>
<Chat/>
<hr/>
<a href="https://git.doordesk.net/adam/cards/">git</a> <a href="https://git.doordesk.net/adam/cards/">git</a>
</div> </div>
</div>
</ErrorBoundary> </ErrorBoundary>
} }
} }