cards/client/src/components/websocket.rs

150 lines
4.8 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};
2024-07-21 02:35:13 -04:00
use lib::models::*;
use serde_json::to_string;
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-22 01:32:09 -04:00
// Signals
let (online_users, set_online_users) = create_signal(0);
let (active_games, set_active_games) = create_signal(0);
let (chat_history, set_chat_history) = create_signal::<Vec<String>>(vec![]);
2024-07-19 03:11:14 -04:00
2024-07-22 01:32:09 -04:00
// Websocket stuff
2024-07-19 03:11:14 -04:00
let status = move || ready_state.get().to_string();
let connected = move || ready_state.get() == ConnectionReadyState::Open;
let open_connection = move |_| {
open();
};
2024-07-21 02:35:13 -04:00
let fake_new_game_request = NewGameRequest {
name: String::from("Ligma"),
2024-07-21 22:48:15 -04:00
host: Player {
2024-07-21 02:35:13 -04:00
name: String::from("Adam"),
role: PlayerRole::Host,
white: vec![],
black: vec![],
},
packs: vec![0],
};
2024-07-22 01:32:09 -04:00
// Game stuff
2024-07-21 02:35:13 -04:00
let new_game_test = move |_| {
send(&to_string(&fake_new_game_request).unwrap());
};
2024-07-22 01:32:09 -04:00
let close_connection = move |_| {
close();
set_online_users(0);
set_active_games(0);
update_chat_history(&set_chat_history, format!("Disconnected.\n"));
};
2024-07-20 23:00:19 -04:00
// Chat stuff
2024-07-19 03:11:14 -04:00
let chat_history_ref = create_node_ref::<Textarea>();
fn update_chat_history(&history: &WriteSignal<Vec<String>>, message: String) {
let _ = &history.update(|history: &mut Vec<_>| history.push(message));
}
// handle incoming messages
2024-07-21 22:48:15 -04:00
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-22 01:38:02 -04:00
if let Ok(_game) = serde_json::from_str::<Game>(message) {
2024-07-22 01:32:09 -04:00
logging::log!("Game object received.");
} else if let Ok(state_summary) =
serde_json::from_str::<ServerStateSummary>(message)
{
logging::log!(
"Users: {}\nGames: {}",
state_summary.online_users,
state_summary.active_games
);
set_online_users(state_summary.online_users);
set_active_games(state_summary.active_games);
2024-07-21 22:48:15 -04:00
} else {
update_chat_history(&set_chat_history, format!("{}\n", message));
2024-07-19 03:11:14 -04:00
}
}
})
});
2024-07-22 01:32:09 -04:00
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());
}
})
});
2024-07-20 23:00:19 -04:00
// Login stuff
let (username, _set_username) = create_signal("ligma");
2024-07-19 03:11:14 -04:00
view! {
2024-07-20 23:00:19 -04:00
<div class="w-auto bg-slate-500">
2024-07-19 03:11:14 -04:00
<hr/>
2024-07-20 23:00:19 -04:00
<h2 class="text-2xl">Connection</h2>
2024-07-22 01:32:09 -04:00
<p class="p-1">"Users Online: " {online_users}</p>
<p class="p-1">"Active Games: " {active_games}</p>
<p class="p-1">"Connection Status: " {status}</p>
2024-07-19 03:11:14 -04:00
<div class="p-1">
<button on:click=open_connection disabled=connected>
2024-07-21 02:35:13 -04:00
"Connect"
2024-07-19 03:11:14 -04:00
</button>
<button on:click=close_connection disabled=move || !connected()>
2024-07-21 02:35:13 -04:00
"Disconnect"
2024-07-19 03:11:14 -04:00
</button>
</div>
<hr/>
<div class="p-1">
2024-07-20 23:00:19 -04:00
<h2 class="text-2xl">Sign in</h2>
<p>Username:</p>
2024-07-19 03:11:14 -04:00
<input
2024-07-20 23:00:19 -04:00
class="w-96 font-mono rounded-sm bg-slate-900 text-slate-200"
placeholder={move || username.get()}
2024-07-19 03:11:14 -04:00
/>
</div>
<hr />
<div class="p-1">
2024-07-20 23:00:19 -04:00
<h2 class="text-2xl">Chat</h2>
2024-07-19 03:11:14 -04:00
<textarea
node_ref=chat_history_ref
2024-07-20 23:00:19 -04:00
class="w-96 h-60 font-mono rounded-sm resize-none bg-slate-900 text-slate-200"
2024-07-19 03:11:14 -04:00
readonly=true
wrap="soft"
>
{move || chat_history.get()}
</textarea>
<br/>
<input
2024-07-20 23:00:19 -04:00
class="w-96 font-mono rounded-sm bg-slate-900 text-slate-200"
2024-07-19 03:11:14 -04:00
placeholder="talk shit..."
/>
<br/>
2024-07-21 02:35:13 -04:00
// <button on:click=send_message disabled=move || !connected()>
// "Send"
// </button>
<br />
<button on:click=new_game_test disabled=move || !connected()>
"Test New Game"
2024-07-19 03:11:14 -04:00
</button>
</div>
<hr/>
</div>
}
}