#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release #![allow(rustdoc::missing_crate_level_docs)] // it's an example mod ctx; mod daos; mod migrations; mod screens; use std::sync::Arc; use std::sync::Mutex; use ctx::ClientCTX; use eframe::egui; use mls_rs::client_builder::BaseConfig; use mls_rs::client_builder::WithCryptoProvider; use mls_rs::client_builder::WithGroupStateStorage; use mls_rs::client_builder::WithIdentityProvider; use mls_rs::client_builder::WithKeyPackageRepo; use mls_rs::client_builder::WithPskStore; use mls_rs::identity::basic::BasicIdentityProvider; use mls_rs_crypto_openssl::OpensslCryptoProvider; use screens::Screens; use tracing::level_filters::LevelFilter; use tracing_subscriber::EnvFilter; use tracing_subscriber::FmtSubscriber; pub type CliMlsConfig = WithIdentityProvider< BasicIdentityProvider, WithGroupStateStorage< daos::MlsCliGroupStateStorage, WithPskStore< daos::MlsCliPreSharedKeyStorage, WithKeyPackageRepo< daos::MlsCliKeyPackageStorage, WithCryptoProvider, >, >, >, >; pub type MlsClient = mls_rs::Client; pub type MlsGroup = mls_rs::Group; fn main() -> eframe::Result { // env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). FmtSubscriber::builder() .with_env_filter( EnvFilter::builder() .with_default_directive(LevelFilter::INFO.into()) .from_env_lossy(), ) .with_writer(std::io::stderr) .init(); let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default().with_title("My little chat"), centered: true, vsync: true, ..Default::default() }; let machine_id = machine_uid::get().expect("Cannot determine machine uid"); let project_dir = directories::ProjectDirs::from("com", "le-memese", "mlc") .expect("Cannot find local project directory"); let data_dir = project_dir.data_local_dir(); tracing::info!("Data dir: {}", data_dir.display()); tracing::info!("Machine id: {}", machine_id); std::fs::create_dir_all(&data_dir).expect("Cannot create app data dir"); let mut sqlite_conn = rusqlite::Connection::open(data_dir.join("data.sqlite3")).expect(&format!( "Can't open database file at {}", data_dir.join("data").display() )); { sqlite_conn .pragma_update_and_check(None, "journal_mode", "WAL", |_| Ok(())) .expect("Cannot set WAL mode on the database"); migrations::MIGRATIONS .to_latest(&mut sqlite_conn) .expect("Cannot run migrations"); } let mut ctx = ClientCTX::new(Arc::new(Mutex::new(sqlite_conn))); ctx.machine_id = machine_id; let app = MyApp::new(ctx); eframe::run_native( "My egui App", options, Box::new(|cc| { // This gives us image support: egui_extras::install_image_loaders(&cc.egui_ctx); Ok(Box::new(app)) }), ) } struct MyApp { login: screens::LoginScreen, chats: screens::ChatsScreen, register: screens::RegisterScreen, ctx: ctx::ClientCTX, } impl MyApp { fn new(ctx: ClientCTX) -> Self { Self { login: screens::LoginScreen::default(), chats: screens::ChatsScreen::default(), register: screens::RegisterScreen::default(), ctx, } } } impl eframe::App for MyApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| match &self.ctx.current_screen { Screens::Login => self.login.update(&mut self.ctx, ui), Screens::Chats => self.chats.update(ctx, &mut self.ctx, ui), Screens::Register => self.register.update(&mut self.ctx, ui), }); } }