sync username between server and client

This commit is contained in:
Adam 2024-07-27 04:34:15 -04:00
parent b653687c81
commit 7682b09aa2
4 changed files with 37 additions and 7 deletions

View file

@ -7,7 +7,16 @@ use serde_json::to_string;
#[component]
pub fn Auth() -> impl IntoView {
let websocket = expect_context::<WebSocketContext>();
let (username, set_username) = create_signal("Anonymous".to_string());
let user_context = expect_context::<ReadSignal<Option<UserUpdate>>>();
let (username, set_username) = create_signal("".to_string());
create_effect(move |_| {
user_context.with(|new_user| {
if let Some(user) = new_user {
set_username(user.username.to_string());
}
})
});
let username_input_ref = create_node_ref::<Input>();
let send_login = move |_| {

View file

@ -45,7 +45,6 @@ impl WebSocketContext {
pub fn close(&self) {
(self.close)()
}
}
#[component]
@ -71,9 +70,11 @@ pub fn Websocket() -> impl IntoView {
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 (user_update, set_user_update) = create_signal::<Option<UserUpdate>>(Option::None);
let (chat_message, set_chat_message) = create_signal::<Option<ChatMessage>>(Option::None);
provide_context::<ReadSignal<Option<Game>>>(game_object);
provide_context::<ReadSignal<Option<UserUpdate>>>(user_update);
provide_context::<ReadSignal<Option<ChatMessage>>>(chat_message);
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
@ -85,12 +86,12 @@ pub fn Websocket() -> impl IntoView {
if let Some(message) = message_raw {
if let Ok(game) = from_str::<Game>(message) {
set_game_object(Some(game));
} else if let Ok(state_summary) =
from_str::<ServerStateSummary>(message)
{
} else if let Ok(state_summary) = from_str::<ServerStateSummary>(message) {
set_state_summary(Some(state_summary));
} else if let Ok(chat_message) = from_str::<ChatMessage>(message) {
set_chat_message(Some(chat_message));
} else if let Ok(user_update) = from_str::<UserUpdate>(message) {
set_user_update(Some(user_update));
} else {
logging::log!("Unhandled message: {}", message);
}

View file

@ -1,5 +1,11 @@
use serde::{Deserialize, Serialize};
/// User update
#[derive(Serialize, Deserialize, Debug)]
pub struct UserUpdate {
pub username: String,
}
/// User login
#[derive(Serialize, Deserialize, Debug)]
pub struct UserLogIn {

View file

@ -32,11 +32,21 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, ad
let new_user = User {
name: "Anonymous".to_string(),
};
state.users.lock().unwrap().insert(addr, new_user);
// By splitting, we can send and receive at the same time.
let (mut sender, mut receiver) = stream.split();
let _ = &sender
.send(Message::Text(
to_string::<UserUpdate>(&UserUpdate {
username: new_user.name.to_string(),
})
.unwrap(),
))
.await;
state.users.lock().unwrap().insert(addr, new_user);
// hydrate user
let _ = &sender
.send(Message::Text(to_string::<ChatMessage>(&motd()).unwrap()))
@ -47,9 +57,13 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, ad
))
.await;
// ANNOUNCE THY PRESENCE
let msg = ChatMessage {
text: format!("{} joined.", state.users.lock().unwrap().get(&addr).unwrap().name),
text: format!(
"{} joined.",
state.users.lock().unwrap().get(&addr).unwrap().name
),
};
tracing::debug!("{}", msg.text);
let _ = &state.tx.send(to_string::<ChatMessage>(&msg).unwrap());