creddy/src-tauri/src/main.rs

144 lines
3.8 KiB
Rust
Raw Normal View History

2022-08-14 20:27:41 +00:00
#![cfg_attr(
2022-12-14 05:50:34 +00:00
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
2022-08-14 20:27:41 +00:00
)]
2023-04-28 21:33:04 +00:00
use std::error::Error;
2023-04-30 17:52:46 +00:00
use std::sync::mpsc::channel;
2022-08-14 20:27:41 +00:00
2023-04-30 17:52:46 +00:00
use once_cell::sync::OnceCell;
2023-04-28 21:33:04 +00:00
use sqlx::{
SqlitePool,
sqlite::SqlitePoolOptions,
sqlite::SqliteConnectOptions,
};
use tauri::{
App,
AppHandle,
Manager,
async_runtime as rt,
};
2023-04-30 17:52:46 +00:00
use tauri::api::dialog::{
MessageDialogBuilder,
MessageDialogKind,
};
mod config;
2022-11-29 00:16:33 +00:00
mod errors;
2022-12-04 05:47:09 +00:00
mod clientinfo;
2022-11-29 00:16:33 +00:00
mod ipc;
mod state;
mod server;
2022-12-21 22:49:01 +00:00
mod tray;
2022-08-14 20:27:41 +00:00
2023-04-28 21:33:04 +00:00
use config::AppConfig;
use server::Server;
use errors::*;
use state::AppState;
2022-08-14 20:27:41 +00:00
pub static APP: OnceCell<AppHandle> = OnceCell::new();
2022-12-14 05:50:34 +00:00
2023-04-28 21:33:04 +00:00
async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
APP.set(app.handle()).unwrap();
let conn_opts = SqliteConnectOptions::new()
2023-04-29 05:34:17 +00:00
.filename(config::get_or_create_db_path()?)
2023-04-28 21:33:04 +00:00
.create_if_missing(true);
let pool_opts = SqlitePoolOptions::new();
let pool: SqlitePool = pool_opts.connect_with(conn_opts).await?;
sqlx::migrate!().run(&pool).await?;
let conf = AppConfig::load(&pool).await?;
let session = AppState::load_creds(&pool).await?;
let srv = Server::new(conf.listen_addr, conf.listen_port, app.handle()).await?;
config::set_auto_launch(conf.start_on_login)?;
if !conf.start_minimized {
app.get_window("main")
.ok_or(RequestError::NoMainWindow)?
.show()?;
}
let state = AppState::new(conf, session, srv, pool);
app.manage(state);
Ok(())
}
2023-04-30 17:52:46 +00:00
fn run() -> tauri::Result<()> {
2022-12-14 05:50:34 +00:00
tauri::Builder::default()
2022-12-21 22:49:01 +00:00
.system_tray(tray::create())
.on_system_tray_event(tray::handle_event)
2022-12-14 05:50:34 +00:00
.invoke_handler(tauri::generate_handler![
ipc::unlock,
ipc::respond,
ipc::get_session_status,
ipc::save_credentials,
ipc::get_config,
2023-04-26 05:10:14 +00:00
ipc::save_config,
2022-12-14 05:50:34 +00:00
])
2023-04-28 21:33:04 +00:00
.setup(|app| rt::block_on(setup(app)))
2023-04-30 17:52:46 +00:00
.build(tauri::generate_context!())?
2022-12-21 22:49:01 +00:00
.run(|app, run_event| match run_event {
tauri::RunEvent::WindowEvent { label, event, .. } => match event {
tauri::WindowEvent::CloseRequested { api, .. } => {
let _ = app.get_window(&label).map(|w| w.hide());
api.prevent_close();
}
_ => ()
}
_ => ()
2023-04-30 17:52:46 +00:00
});
Ok(())
}
fn main() {
if let Err(e) = run() {
let (tx, rx) = channel();
MessageDialogBuilder::new(
"Creddy failed to start",
format!("{e}")
)
.kind(MessageDialogKind::Error)
.show(move |_| tx.send(true).unwrap());
rx.recv().unwrap();
}
}
macro_rules! get_state {
($prop:ident as $name:ident) => {
use tauri::Manager;
let app = crate::APP.get().unwrap(); // as long as the app is running, this is fine
let state = app.state::<crate::state::AppState>();
let $name = state.$prop.read().unwrap(); // only panics if another thread has already panicked
};
(config.$prop:ident as $name:ident) => {
use tauri::Manager;
let app = crate::APP.get().unwrap();
let state = app.state::<crate::state::AppState>();
let config = state.config.read().unwrap();
let $name = config.$prop;
};
(mut $prop:ident as $name:ident) => {
use tauri::Manager;
let app = crate::APP.get().unwrap();
let state = app.state::<crate::state::AppState>();
let $name = state.$prop.write().unwrap();
};
(mut config.$prop:ident as $name:ident) => {
use tauri::Manager;
let app = crate::APP.get().unwrap();
let state = app.state::<crate::state::AppState>();
let config = state.config.write().unwrap();
let $name = config.$prop;
}
}
pub(crate) use get_state;