diff --git a/client/src/components/auth.rs b/client/src/components/auth.rs index cc4123d..f9f8563 100644 --- a/client/src/components/auth.rs +++ b/client/src/components/auth.rs @@ -7,7 +7,16 @@ use serde_json::to_string; #[component] pub fn Auth() -> impl IntoView { let websocket = expect_context::(); - let (username, set_username) = create_signal("Anonymous".to_string()); + let user_context = expect_context::>>(); + 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::(); let send_login = move |_| { diff --git a/client/src/components/websocket.rs b/client/src/components/websocket.rs index bf5c0bc..3f57c7c 100644 --- a/client/src/components/websocket.rs +++ b/client/src/components/websocket.rs @@ -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::None); let (game_object, set_game_object) = create_signal::>(Option::None); + let (user_update, set_user_update) = create_signal::>(Option::None); let (chat_message, set_chat_message) = create_signal::>(Option::None); provide_context::>>(game_object); + provide_context::>>(user_update); provide_context::>>(chat_message); provide_context::>>(state_summary); @@ -85,12 +86,12 @@ pub fn Websocket() -> impl IntoView { if let Some(message) = message_raw { if let Ok(game) = from_str::(message) { set_game_object(Some(game)); - } else if let Ok(state_summary) = - from_str::(message) - { + } else if let Ok(state_summary) = from_str::(message) { set_state_summary(Some(state_summary)); } else if let Ok(chat_message) = from_str::(message) { set_chat_message(Some(chat_message)); + } else if let Ok(user_update) = from_str::(message) { + set_user_update(Some(user_update)); } else { logging::log!("Unhandled message: {}", message); } diff --git a/lib/src/models.rs b/lib/src/models.rs index 6c2372e..4b4b418 100644 --- a/lib/src/models.rs +++ b/lib/src/models.rs @@ -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 { diff --git a/server/src/api.rs b/server/src/api.rs index 1768d00..e83a581 100644 --- a/server/src/api.rs +++ b/server/src/api.rs @@ -32,11 +32,21 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc, 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 { + 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::(&motd()).unwrap())) @@ -47,9 +57,13 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc, 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::(&msg).unwrap());