Logging in and Signing up on the client done
Tons of bug fixes too
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
use tokio::sync::broadcast;
|
||||
use tokio::sync::broadcast::{Receiver, Sender};
|
||||
use tracing::log::info;
|
||||
use realm_shared::types::ErrorCode;
|
||||
use crate::types::ClientUser;
|
||||
use crate::ui::panels;
|
||||
|
||||
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
||||
@@ -9,9 +14,32 @@ pub struct TemplateApp {
|
||||
pub selected: bool,
|
||||
pub selected_serverid: Option<String>,
|
||||
pub selected_roomid: Option<String>,
|
||||
|
||||
pub current_user: Option<ClientUser>,
|
||||
|
||||
#[serde(skip)] // This how you opt-out of serialization of a field
|
||||
#[serde(skip)]
|
||||
pub value: f32,
|
||||
#[serde(skip)]
|
||||
pub login_window_open: bool,
|
||||
#[serde(skip)]
|
||||
pub login_window_username: String,
|
||||
#[serde(skip)]
|
||||
pub login_window_code: String,
|
||||
#[serde(skip)]
|
||||
pub login_window_server_address: String,
|
||||
#[serde(skip)]
|
||||
pub login_window_email: String,
|
||||
|
||||
#[serde(skip)]
|
||||
pub login_ready_for_code_input: bool,
|
||||
|
||||
#[serde(skip)]
|
||||
pub signup_window_open: bool,
|
||||
|
||||
#[serde(skip)]
|
||||
pub login_start_channel: (Sender<Result<(), ErrorCode>>, Receiver<Result<(), ErrorCode>>),
|
||||
#[serde(skip)]
|
||||
pub login_ending_channel: (Sender<Result<String, ErrorCode>>, Receiver<Result<String, ErrorCode>>),
|
||||
}
|
||||
|
||||
impl Default for TemplateApp {
|
||||
@@ -22,7 +50,19 @@ impl Default for TemplateApp {
|
||||
selected: false,
|
||||
selected_serverid: None,
|
||||
selected_roomid: None,
|
||||
current_user: None,
|
||||
value: 2.7,
|
||||
|
||||
login_window_open: false,
|
||||
login_window_username: String::new(),
|
||||
login_window_code: String::new(),
|
||||
login_window_server_address: String::new(),
|
||||
login_start_channel: broadcast::channel(10),
|
||||
login_ending_channel: broadcast::channel(10),
|
||||
login_ready_for_code_input: false,
|
||||
login_window_email: String::new(),
|
||||
|
||||
signup_window_open: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,8 +89,26 @@ impl eframe::App for TemplateApp {
|
||||
// Put your widgets into a `SidePanel`, `TopBottomPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
// For inspiration and more examples, go to https://emilk.github.io/egui
|
||||
|
||||
while let Ok(result) = self.login_start_channel.1.try_recv() {
|
||||
match result {
|
||||
Ok(_) => self.login_ready_for_code_input = true,
|
||||
Err(e) => tracing::error!("Error in login/account creation flow: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
while let Ok(result) = self.login_ending_channel.1.try_recv() {
|
||||
match result {
|
||||
Ok(token) => {
|
||||
info!("Login successful! Token: {token}");
|
||||
self.login_ready_for_code_input = false;
|
||||
|
||||
},
|
||||
Err(e) => tracing::error!("Error in login flow: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
// File -> Quit
|
||||
panels::top_panel(ctx);
|
||||
panels::top_panel(self, ctx);
|
||||
|
||||
panels::servers(self, ctx);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
fn main() -> eframe::Result {
|
||||
#[tokio::main]
|
||||
async fn main() -> eframe::Result {
|
||||
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
|
||||
|
||||
let native_options = eframe::NativeOptions {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct ClientUser {
|
||||
pub id: i64,
|
||||
pub username: String,
|
||||
pub email: String,
|
||||
pub avatar: String,
|
||||
pub servers: Vec<String>,
|
||||
pub token: String,
|
||||
}
|
||||
@@ -1,25 +1,180 @@
|
||||
use egui::{Context, SelectableLabel};
|
||||
use tarpc::context;
|
||||
use tarpc::tokio_serde::formats::Json;
|
||||
use realm_auth::types::RealmAuthClient;
|
||||
use realm_shared::types::ErrorCode::RPCError;
|
||||
use regex::Regex;
|
||||
use crate::app::TemplateApp;
|
||||
|
||||
pub fn top_panel(ctx: &Context) {
|
||||
pub fn top_panel(app: &mut TemplateApp, ctx: &Context) {
|
||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||
// The top panel is often a good place for a menu bar:
|
||||
|
||||
egui::menu::bar(ui, |ui| {
|
||||
// NOTE: no File->Quit on web pages!
|
||||
let is_web = cfg!(target_arch = "wasm32");
|
||||
if !is_web {
|
||||
ui.menu_button("File", |ui| {
|
||||
if ui.button("Quit").clicked() {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
}
|
||||
});
|
||||
ui.add_space(16.0);
|
||||
}
|
||||
ui.menu_button("File", |ui| {
|
||||
if ui.button("Sign Up").clicked() {
|
||||
app.signup_window_open = true;
|
||||
}
|
||||
|
||||
if ui.button("Login").clicked() {
|
||||
app.login_window_open = true;
|
||||
}
|
||||
|
||||
if ui.button("Logout").clicked() {
|
||||
// TODO: Logout
|
||||
}
|
||||
|
||||
if ui.button("Quit").clicked() {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
}
|
||||
});
|
||||
ui.add_space(16.0);
|
||||
|
||||
egui::widgets::global_dark_light_mode_buttons(ui);
|
||||
});
|
||||
});
|
||||
|
||||
egui::Window::new("Signup")
|
||||
.open(&mut app.signup_window_open)
|
||||
.min_size((500.0, 200.0))
|
||||
.show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Server Address: ");
|
||||
ui.text_edit_singleline(&mut app.login_window_server_address);
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Username: ");
|
||||
ui.text_edit_singleline(&mut app.login_window_username);
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Email: ");
|
||||
ui.text_edit_singleline(&mut app.login_window_email);
|
||||
});
|
||||
|
||||
if ui.button("Create Account").clicked() {
|
||||
let login_window_server_address = app.login_window_server_address.clone();
|
||||
let login_window_username = app.login_window_username.clone();
|
||||
let login_window_email = app.login_window_email.clone();
|
||||
let send_channel = app.login_start_channel.0.clone();
|
||||
|
||||
let _handle = tokio::spawn(async move {
|
||||
let mut transport = tarpc::serde_transport::tcp::connect(login_window_server_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.create_account_flow(context::current(), login_window_username, login_window_email).await;
|
||||
|
||||
match result {
|
||||
Ok(r) => send_channel.send(r).unwrap(),
|
||||
Err(_) => send_channel.send(Err(RPCError)).unwrap(),
|
||||
};
|
||||
});
|
||||
|
||||
ui.close_menu()
|
||||
}
|
||||
});
|
||||
|
||||
egui::Window::new("Login")
|
||||
.open(&mut app.login_window_open)
|
||||
.min_size((500.0, 200.0))
|
||||
.show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Server Address: ");
|
||||
ui.text_edit_singleline(&mut app.login_window_server_address);
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Username: ");
|
||||
ui.text_edit_singleline(&mut app.login_window_username);
|
||||
});
|
||||
|
||||
if ui.button("Send Login Code").clicked() {
|
||||
let login_window_server_address = app.login_window_server_address.clone();
|
||||
let login_window_username = app.login_window_username.clone();
|
||||
let send_channel = app.login_start_channel.0.clone();
|
||||
|
||||
let _handle = tokio::spawn(async move {
|
||||
let mut transport = tarpc::serde_transport::tcp::connect(login_window_server_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.create_login_flow(context::current(), Some(login_window_username), None).await;
|
||||
|
||||
match result {
|
||||
Ok(r) => send_channel.send(r).unwrap(),
|
||||
Err(_) => send_channel.send(Err(RPCError)).unwrap(),
|
||||
};
|
||||
});
|
||||
|
||||
ui.close_menu()
|
||||
}
|
||||
});
|
||||
|
||||
egui::Window::new("Auth Code")
|
||||
.open(&mut app.login_ready_for_code_input)
|
||||
.min_size((500.0, 200.0))
|
||||
.show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Code: ");
|
||||
if ui.text_edit_singleline(&mut app.login_window_code).changed() {
|
||||
let re = Regex::new(r"[^0-9]+").unwrap();
|
||||
app.login_window_code = re.replace_all(&app.login_window_code, "").to_string();
|
||||
}
|
||||
});
|
||||
|
||||
if ui.button("Login").clicked() {
|
||||
let login_window_server_address = app.login_window_server_address.clone();
|
||||
let login_window_code = app.login_window_code.clone();
|
||||
let login_window_username = app.login_window_username.clone();
|
||||
let send_channel = app.login_ending_channel.0.clone();
|
||||
|
||||
let _handle = tokio::spawn(async move {
|
||||
let mut transport = tarpc::serde_transport::tcp::connect(login_window_server_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.finish_login_flow(context::current(), login_window_username, login_window_code.parse::<u32>().unwrap()).await;
|
||||
|
||||
match result {
|
||||
Ok(r) => {
|
||||
send_channel.send(r).unwrap();
|
||||
}
|
||||
Err(e) => {
|
||||
send_channel.send(Err(RPCError)).unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.close_menu()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn servers(app: &mut TemplateApp, ctx: &Context) {
|
||||
|
||||
Reference in New Issue
Block a user