diff --git a/src/main.rs b/src/main.rs index 61113be..f8dfbdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,17 +21,21 @@ struct App { messages: Vec<(String, String)>, input: String, username: String, + current_room: String, } impl App { fn new(username: String) -> App { let mut messages = Vec::new(); + let default_room = "default".to_string(); messages.push(("System".to_string(), format!("Welcome to the chat, {}!", username))); messages.push(("System".to_string(), "To change your username, type /nick ".to_string())); + messages.push(("System".to_string(), format!("You are currently in room: {}. To change room, type /join ", default_room))); App { messages, input: String::new(), username, + current_room: default_room, } } } @@ -77,7 +81,7 @@ async fn run_app(terminal: &mut Terminal, mut app: App) -> io::Re mqttoptions.set_keep_alive(Duration::from_secs(5)); let (client, mut eventloop) = AsyncClient::new(mqttoptions, 10); - client.subscribe("chat/msg", QoS::AtMostOnce).await.unwrap(); + client.subscribe(&format!("chat/{}", app.current_room), QoS::AtMostOnce).await.unwrap(); // Publish connect message let connect_message = ChatMessage { @@ -85,7 +89,7 @@ async fn run_app(terminal: &mut Terminal, mut app: App) -> io::Re message: "has connected".to_string(), }; let connect_payload = serde_json::to_string(&connect_message).unwrap(); - client.publish("chat/msg", QoS::AtMostOnce, false, connect_payload.as_bytes()).await.unwrap(); + client.publish(&format!("chat/{}", app.current_room), QoS::AtMostOnce, false, connect_payload.as_bytes()).await.unwrap(); let client_clone = client.clone(); @@ -133,9 +137,36 @@ async fn run_app(terminal: &mut Terminal, mut app: App) -> io::Re }; let payload = serde_json::to_string(&chat_message).unwrap(); client_clone - .publish("chat/msg", QoS::AtMostOnce, false, payload.as_bytes()) + .publish(&format!("chat/{}", app.current_room), QoS::AtMostOnce, false, payload.as_bytes()) .await .unwrap(); + } else if message_text.starts_with("/join ") { + let old_room = app.current_room.clone(); + let new_room = message_text.split_whitespace().nth(1).unwrap_or(&app.current_room).to_string(); + if old_room != new_room { + // Send leaving message to old room + let leaving_message = ChatMessage { + username: app.username.clone(), + message: format!("is leaving for room {}", new_room), + }; + let leaving_payload = serde_json::to_string(&leaving_message).unwrap(); + client_clone.publish(&format!("chat/{}", old_room), QoS::AtMostOnce, false, leaving_payload.as_bytes()).await.unwrap(); + + client_clone.unsubscribe(&format!("chat/{}", old_room)).await.unwrap(); + client_clone.subscribe(&format!("chat/{}", new_room), QoS::AtMostOnce).await.unwrap(); + app.current_room = new_room.clone(); + app.messages.push(("System".to_string(), format!("Changed room to: {}", new_room))); + + // Send joining message to new room + let joining_message = ChatMessage { + username: app.username.clone(), + message: "has joined the room".to_string(), + }; + let joining_payload = serde_json::to_string(&joining_message).unwrap(); + client_clone.publish(&format!("chat/{}", new_room), QoS::AtMostOnce, false, joining_payload.as_bytes()).await.unwrap(); + } else { + app.messages.push(("System".to_string(), format!("Already in room: {}", new_room))); + } } else { let chat_message = ChatMessage { username: app.username.clone(), @@ -143,7 +174,7 @@ async fn run_app(terminal: &mut Terminal, mut app: App) -> io::Re }; let payload = serde_json::to_string(&chat_message).unwrap(); client_clone - .publish("chat/msg", QoS::AtMostOnce, false, payload.as_bytes()) + .publish(&format!("chat/{}", app.current_room), QoS::AtMostOnce, false, payload.as_bytes()) .await .unwrap(); }