From c3c6379091d1ac0a2ebe869dc68996cb19271fae Mon Sep 17 00:00:00 2001 From: Joshua Higgins Date: Tue, 15 Oct 2024 22:11:47 -0400 Subject: [PATCH] first try at messaging --- auth/src/server.rs | 34 +----------- auth/src/types.rs | 3 +- client/Cargo.toml | 3 +- client/src/app.rs | 26 +++++---- client/src/ui/gui.rs | 124 +++++++++++++++++++++++++++++++++++++++---- 5 files changed, 134 insertions(+), 56 deletions(-) diff --git a/auth/src/server.rs b/auth/src/server.rs index 8b04e41..010ccdc 100644 --- a/auth/src/server.rs +++ b/auth/src/server.rs @@ -460,45 +460,13 @@ impl RealmAuth for RealmAuthServer { } } - async fn delete_account_flow(self, _: Context, username: String, token: String) -> Result<(), ErrorCode> { + async fn delete_account(self, _: Context, username: String, token: String) -> Result<(), ErrorCode> { info!("API Request: delete_account_flow( username -> {}, token -> {} )", username, token); if !self.is_authorized(&username, &token).await? { return Err(Unauthorized); } - let email = match query!("SELECT email FROM user WHERE username = ?;", username).fetch_one(&self.db_pool).await { - Ok(row) => Ok(row.email), - Err(_) => Err(InvalidUsername), - }?; - - let code = self.gen_login_code(); - - let result = query!("UPDATE user SET login_code = ? WHERE username = ?;", code, username) - .execute(&self.db_pool).await; - - match result { - Ok(_) => { - self.send_login_message(&username, &email, code); - Ok(()) - } - Err(_) => Err(InvalidUsername) - } - } - - async fn finish_delete_account_flow(self, _: Context, username: String, token: String, login_code: u32) -> Result<(), ErrorCode> { - info!("API Request: finish_delete_account_flow( username -> {}, token -> {}, login_code -> {} )", username, token, login_code); - - if !self.is_authorized(&username, &token).await? { - return Err(Unauthorized); - } - - if !self.is_login_code_valid(&username, login_code).await? { - return Err(InvalidLoginCode); - } - - self.reset_login_code(&username).await?; - let result = query!("DELETE FROM user WHERE username = ?", username).execute(&self.db_pool).await; match result { Ok(_) => Ok(()), diff --git a/auth/src/types.rs b/auth/src/types.rs index dc350e1..e1ae144 100644 --- a/auth/src/types.rs +++ b/auth/src/types.rs @@ -16,8 +16,7 @@ pub trait RealmAuth { async fn change_avatar(username: String, token: String, new_avatar: String) -> Result<(), ErrorCode>; async fn get_all_data(username: String, token: String) -> Result; async fn sign_out(username: String, token: String) -> Result<(), ErrorCode>; - async fn delete_account_flow(username: String, token: String) -> Result<(), ErrorCode>; - async fn finish_delete_account_flow(username: String, token: String, login_code: u32) -> Result<(), ErrorCode>; + async fn delete_account(username: String, token: String) -> Result<(), ErrorCode>; async fn add_server(username: String, token: String, domain: String, port: u16) -> Result<(), ErrorCode>; async fn remove_server(username: String, token: String, domain: String, port: u16) -> Result<(), ErrorCode>; async fn get_joined_servers(username: String, token: String) -> Result, ErrorCode>; diff --git a/client/Cargo.toml b/client/Cargo.toml index a255df4..c797d8e 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -19,4 +19,5 @@ tarpc = { version = "0.34.0", features = ["full"] } tracing = "0.1.40" tracing-subscriber = "0.3.18" regex = "1.10.6" -native-dialog = "0.7.0" \ No newline at end of file +native-dialog = "0.7.0" +chrono = "0.4.38" \ No newline at end of file diff --git a/client/src/app.rs b/client/src/app.rs index f717d4f..531c182 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -35,7 +35,7 @@ pub struct RealmApp { pub active_servers: Option>, #[serde(skip)] - pub value: f32, + pub text_message_input: String, #[serde(skip)] pub login_window_open: bool, #[serde(skip)] @@ -117,12 +117,12 @@ impl Default for RealmApp { saved_token: None, saved_auth_address: None, active_servers: None, - value: 2.7, + text_message_input: String::new(), login_window_open: false, login_window_username: String::new(), login_window_code: String::new(), - login_window_server_domain: String::new(), + login_window_server_domain: "auth.realm.abunchofknowitalls.com".to_string(), login_window_server_port: "5052".to_string(), login_start_channel: broadcast::channel(256), login_ending_channel: broadcast::channel(256), @@ -132,7 +132,7 @@ impl Default for RealmApp { signup_window_open: false, server_window_open: false, - server_window_domain: String::new(), + server_window_domain: "realm.abunchofknowitalls.com".to_string(), server_window_port: "5051".to_string(), room_window_open: false, @@ -165,9 +165,12 @@ impl RealmApp { // Load previous app state (if any). // Note that you must enable the `persistence` feature for this to work. - // if let Some(storage) = cc.storage { - // return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); - // } + if !cfg!(debug_assertions) { + if let Some(storage) = cc.storage { + return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); + } + } + Default::default() } @@ -562,6 +565,9 @@ impl eframe::App for RealmApp { } Event::DeleteRoom(roomid) => { server.rooms.retain(|r| !r.roomid.eq(&roomid)); + if self.selected_roomid.eq(&roomid) { + self.selected_roomid.clear(); + } } } server.last_event_index = index; @@ -606,7 +612,7 @@ impl eframe::App for RealmApp { Err(_) => break, } - sleep(Duration::from_millis(100)).await; + sleep(Duration::from_millis(75)).await; } }); } @@ -627,6 +633,8 @@ impl eframe::App for RealmApp { /// Called by the frame work to save state before shutdown. fn save(&mut self, storage: &mut dyn eframe::Storage) { - eframe::set_value(storage, eframe::APP_KEY, self); + if !cfg!(debug_assertions) { + eframe::set_value(storage, eframe::APP_KEY, self); + } } } \ No newline at end of file diff --git a/client/src/ui/gui.rs b/client/src/ui/gui.rs index 910dce3..d7a05b5 100644 --- a/client/src/ui/gui.rs +++ b/client/src/ui/gui.rs @@ -1,3 +1,4 @@ +use chrono::Utc; use egui::{Context, SelectableLabel}; use tarpc::context; use tarpc::tokio_serde::formats::Json; @@ -5,7 +6,7 @@ use realm_auth::types::RealmAuthClient; use realm_shared::types::ErrorCode::RPCError; use regex::Regex; use tracing::log::*; -use realm_server::types::{Room}; +use realm_server::types::{Message, MessageData, Room, User}; use realm_shared::stoken; use crate::app::RealmApp; use crate::types::CServer; @@ -57,18 +58,56 @@ pub fn top_panel(app: &mut RealmApp, ctx: &Context) { app.selected_roomid.clear(); app.selected_serverid.clear(); } - - if ui.button("Info").clicked() { - app.info_window_open = true; - } if ui.button("Quit").clicked() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); } - ui.add_space(16.0); + + ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| { + egui::widgets::global_theme_preference_buttons(ui); - egui::widgets::global_theme_preference_buttons(ui); + if ui.button("ℹ").clicked() { + app.info_window_open = true; + } + + if app.current_user.is_some() && ui.button("Delete Account").clicked() { + let address = app.current_user.clone().unwrap().auth_address; + let username = app.current_user.clone().unwrap().username; + let token = app.current_user.clone().unwrap().token; + let _handle = tokio::spawn(async move { + let mut transport = tarpc::serde_transport::tcp::connect(address, Json::default); + transport.config_mut().max_frame_length(usize::MAX); + + let result = transport.await; + let connection = match result { + Ok(connection) => connection, + Err(e) => { + tracing::error!("Failed to connect to server: {}", e); + return; + } + }; + + let client = RealmAuthClient::new(tarpc::client::Config::default(), connection).spawn(); + let result = client.delete_account(context::current(), username, token).await; + + match result { + Ok(_) => info!("Account deleted successfully!"), + Err(e) => error!("Error deleting account: {:?}", e), + } + }); + + app.current_user = None; + app.saved_username = None; + app.saved_token = None; + app.saved_auth_address = None; + + app.active_servers = None; + app.selected_roomid.clear(); + app.selected_serverid.clear(); + } + }); + }); }); } @@ -150,7 +189,7 @@ pub fn rooms(app: &mut RealmApp, ctx: &Context) { userid, roomid ).await; - + match result { Ok(r) => { match r { @@ -166,7 +205,7 @@ pub fn rooms(app: &mut RealmApp, ctx: &Context) { }); ui.separator(); - + if let Some(server) = current_server { for room in &server.rooms { if ui.add(SelectableLabel::new(room.roomid.eq(&app.selected_roomid), room.roomid.clone())).clicked() { @@ -183,7 +222,70 @@ pub fn rooms(app: &mut RealmApp, ctx: &Context) { pub fn messages(app: &mut RealmApp, ctx: &Context) { egui::CentralPanel::default().show(ctx, |ui| { - + ui.with_layout(egui::Layout::bottom_up(egui::Align::TOP), |ui| { + ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| { + if ui.button("").on_hover_text("Send a message").clicked() { + if let Some(active_servers) = &app.active_servers { + for server in active_servers.clone() { + if server.server_id.eq(&app.selected_serverid) { + let username = app.current_user.as_ref().unwrap().username.clone(); + let token = app.current_user.as_ref().unwrap().token.clone(); + let room = server.rooms.iter().find(|r| r.roomid.eq(&app.selected_roomid)).unwrap().clone(); + let text_message = app.text_message_input.clone(); + let _handle = tokio::spawn(async move { + let result = server.tarpc_conn.send_message( + context::current(), + stoken(&token, &server.server_id, &server.domain, server.port), + Message { + id: 0, + timestamp: Utc::now(), + user: server.tarpc_conn.get_user(context::current(), username.clone()).await.unwrap().unwrap(), + room, + data: MessageData::Text(text_message), + } + ).await; + }); + } + } + } + } + + ui.add( + egui::TextEdit::multiline(&mut app.text_message_input) + .desired_rows(1) + .desired_width(ui.available_width()) + .hint_text("Send a message...") + ); + }); + ui.with_layout(egui::Layout::top_down_justified(egui::Align::Min), |ui| { + egui::ScrollArea::vertical().show(ui, |ui| { + if let Some(active_servers) = &app.active_servers { + for server in active_servers { + let messages_to_display = server.messages + .iter() + .filter(|m| m.room.roomid.eq(&app.selected_roomid)) + .collect::>(); + + for message in messages_to_display { + match message.clone().data { + MessageData::Text(text) => { + ui.label(format!("{} - {}: {}", + message.timestamp.format("%Y-%m-%d %H:%M:%S"), + message.user.userid.split(':').collect::>()[0], + text)); + } + MessageData::Attachment(_) => {} + MessageData::Reply(_) => {} + MessageData::Edit(_) => {} + MessageData::Reaction(_) => {} + MessageData::Redaction(_) => {} + } + } + } + } + }); + }); + }); }); } @@ -211,7 +313,7 @@ pub fn modals(app: &mut RealmApp, ctx: &Context) { ui.label(format!("Current user: {:?}", app.current_user)); }); }); - + egui::Window::new("Signup") .open(&mut app.signup_window_open) .min_size((500.0, 200.0))