sync username between server and client
This commit is contained in:
parent
b653687c81
commit
7682b09aa2
4 changed files with 37 additions and 7 deletions
|
@ -7,7 +7,16 @@ use serde_json::to_string;
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Auth() -> impl IntoView {
|
pub fn Auth() -> impl IntoView {
|
||||||
let websocket = expect_context::<WebSocketContext>();
|
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 username_input_ref = create_node_ref::<Input>();
|
||||||
let send_login = move |_| {
|
let send_login = move |_| {
|
||||||
|
|
|
@ -45,7 +45,6 @@ impl WebSocketContext {
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
(self.close)()
|
(self.close)()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -71,9 +70,11 @@ pub fn Websocket() -> impl IntoView {
|
||||||
let (state_summary, set_state_summary) =
|
let (state_summary, set_state_summary) =
|
||||||
create_signal::<Option<ServerStateSummary>>(Option::None);
|
create_signal::<Option<ServerStateSummary>>(Option::None);
|
||||||
let (game_object, set_game_object) = create_signal::<Option<Game>>(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);
|
let (chat_message, set_chat_message) = create_signal::<Option<ChatMessage>>(Option::None);
|
||||||
|
|
||||||
provide_context::<ReadSignal<Option<Game>>>(game_object);
|
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<ChatMessage>>>(chat_message);
|
||||||
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
|
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
|
||||||
|
|
||||||
|
@ -85,12 +86,12 @@ pub fn Websocket() -> impl IntoView {
|
||||||
if let Some(message) = message_raw {
|
if let Some(message) = message_raw {
|
||||||
if let Ok(game) = from_str::<Game>(message) {
|
if let Ok(game) = from_str::<Game>(message) {
|
||||||
set_game_object(Some(game));
|
set_game_object(Some(game));
|
||||||
} else if let Ok(state_summary) =
|
} else if let Ok(state_summary) = from_str::<ServerStateSummary>(message) {
|
||||||
from_str::<ServerStateSummary>(message)
|
|
||||||
{
|
|
||||||
set_state_summary(Some(state_summary));
|
set_state_summary(Some(state_summary));
|
||||||
} else if let Ok(chat_message) = from_str::<ChatMessage>(message) {
|
} else if let Ok(chat_message) = from_str::<ChatMessage>(message) {
|
||||||
set_chat_message(Some(chat_message));
|
set_chat_message(Some(chat_message));
|
||||||
|
} else if let Ok(user_update) = from_str::<UserUpdate>(message) {
|
||||||
|
set_user_update(Some(user_update));
|
||||||
} else {
|
} else {
|
||||||
logging::log!("Unhandled message: {}", message);
|
logging::log!("Unhandled message: {}", message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// User update
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct UserUpdate {
|
||||||
|
pub username: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// User login
|
/// User login
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct UserLogIn {
|
pub struct UserLogIn {
|
||||||
|
|
|
@ -32,11 +32,21 @@ pub async fn on_websocket_connection(stream: WebSocket, state: Arc<AppState>, ad
|
||||||
let new_user = User {
|
let new_user = User {
|
||||||
name: "Anonymous".to_string(),
|
name: "Anonymous".to_string(),
|
||||||
};
|
};
|
||||||
state.users.lock().unwrap().insert(addr, new_user);
|
|
||||||
|
|
||||||
// By splitting, we can send and receive at the same time.
|
// By splitting, we can send and receive at the same time.
|
||||||
let (mut sender, mut receiver) = stream.split();
|
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
|
// hydrate user
|
||||||
let _ = &sender
|
let _ = &sender
|
||||||
.send(Message::Text(to_string::<ChatMessage>(&motd()).unwrap()))
|
.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;
|
.await;
|
||||||
|
|
||||||
|
|
||||||
// ANNOUNCE THY PRESENCE
|
// ANNOUNCE THY PRESENCE
|
||||||
let msg = ChatMessage {
|
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);
|
tracing::debug!("{}", msg.text);
|
||||||
let _ = &state.tx.send(to_string::<ChatMessage>(&msg).unwrap());
|
let _ = &state.tx.send(to_string::<ChatMessage>(&msg).unwrap());
|
||||||
|
|
Loading…
Add table
Reference in a new issue