show non-fatal setup errors on home screen instead of in popup
This commit is contained in:
parent
12f0f187a6
commit
992d2a4d06
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "creddy",
|
"name": "creddy",
|
||||||
"version": "0.3.1",
|
"version": "0.3.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
2
src-tauri/Cargo.lock
generated
2
src-tauri/Cargo.lock
generated
@ -1035,7 +1035,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "creddy"
|
name = "creddy"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2",
|
"argon2",
|
||||||
"auto-launch",
|
"auto-launch",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "creddy"
|
name = "creddy"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
description = "A friendly AWS credentials manager"
|
description = "A friendly AWS credentials manager"
|
||||||
authors = ["Joseph Montanaro"]
|
authors = ["Joseph Montanaro"]
|
||||||
license = ""
|
license = ""
|
||||||
|
@ -43,6 +43,7 @@ pub fn run() -> tauri::Result<()> {
|
|||||||
ipc::get_config,
|
ipc::get_config,
|
||||||
ipc::save_config,
|
ipc::save_config,
|
||||||
ipc::launch_terminal,
|
ipc::launch_terminal,
|
||||||
|
ipc::get_setup_errors,
|
||||||
])
|
])
|
||||||
.setup(|app| rt::block_on(setup(app)))
|
.setup(|app| rt::block_on(setup(app)))
|
||||||
.build(tauri::generate_context!())?
|
.build(tauri::generate_context!())?
|
||||||
@ -77,14 +78,15 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
// get_or_create_db_path doesn't create the actual db file, just the directory
|
// get_or_create_db_path doesn't create the actual db file, just the directory
|
||||||
let is_first_launch = !config::get_or_create_db_path()?.exists();
|
let is_first_launch = !config::get_or_create_db_path()?.exists();
|
||||||
|
|
||||||
let pool = connect_db().await?;
|
let pool = connect_db().await?;
|
||||||
|
let mut setup_errors: Vec<String> = vec![];
|
||||||
|
|
||||||
let conf = match AppConfig::load(&pool).await {
|
let conf = match AppConfig::load(&pool).await {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(SetupError::ConfigParseError(_)) => {
|
Err(SetupError::ConfigParseError(_)) => {
|
||||||
Err("Could not load configuration from database. Reverting to defaults.")
|
setup_errors.push(
|
||||||
.error_popup("Setup error");
|
"Could not load configuration from database. Reverting to defaults.".into()
|
||||||
|
);
|
||||||
AppConfig::default()
|
AppConfig::default()
|
||||||
},
|
},
|
||||||
err => err?,
|
err => err?,
|
||||||
@ -94,7 +96,12 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
|
|||||||
let srv = Server::new(conf.listen_addr, conf.listen_port, app.handle()).await?;
|
let srv = Server::new(conf.listen_addr, conf.listen_port, app.handle()).await?;
|
||||||
|
|
||||||
config::set_auto_launch(conf.start_on_login)?;
|
config::set_auto_launch(conf.start_on_login)?;
|
||||||
config::register_hotkeys(&conf.hotkeys).error_popup("Setup error");
|
if let Err(_e) = config::set_auto_launch(conf.start_on_login) {
|
||||||
|
setup_errors.push("Error: Failed to manage autolaunch.".into());
|
||||||
|
}
|
||||||
|
if let Err(e) = config::register_hotkeys(&conf.hotkeys) {
|
||||||
|
setup_errors.push(format!("{e}"));
|
||||||
|
}
|
||||||
|
|
||||||
// if session is empty, this is probably the first launch, so don't autohide
|
// if session is empty, this is probably the first launch, so don't autohide
|
||||||
if !conf.start_minimized || is_first_launch {
|
if !conf.start_minimized || is_first_launch {
|
||||||
@ -103,7 +110,7 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
|
|||||||
.show()?;
|
.show()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = AppState::new(conf, session, srv, pool);
|
let state = AppState::new(conf, session, srv, pool, setup_errors);
|
||||||
app.manage(state);
|
app.manage(state);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use serde::{Serialize, Serializer, ser::SerializeMap};
|
|||||||
|
|
||||||
pub trait ErrorPopup {
|
pub trait ErrorPopup {
|
||||||
fn error_popup(self, title: &str);
|
fn error_popup(self, title: &str);
|
||||||
|
fn error_popup_nowait(self, title: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: std::fmt::Display> ErrorPopup for Result<(), E> {
|
impl<E: std::fmt::Display> ErrorPopup for Result<(), E> {
|
||||||
@ -35,6 +36,14 @@ impl<E: std::fmt::Display> ErrorPopup for Result<(), E> {
|
|||||||
rx.recv().unwrap();
|
rx.recv().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn error_popup_nowait(self, title: &str) {
|
||||||
|
if let Err(e) = self {
|
||||||
|
MessageDialogBuilder::new(title, format!("{e}"))
|
||||||
|
.kind(MessageDialogKind::Error)
|
||||||
|
.show(|_| {})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,3 +85,9 @@ pub async fn save_config(config: AppConfig, app_state: State<'_, AppState>) -> R
|
|||||||
pub async fn launch_terminal(base: bool) -> Result<(), LaunchTerminalError> {
|
pub async fn launch_terminal(base: bool) -> Result<(), LaunchTerminalError> {
|
||||||
terminal::launch(base).await
|
terminal::launch(base).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn get_setup_errors(app_state: State<'_, AppState>) -> Result<Vec<String>, ()> {
|
||||||
|
Ok(app_state.setup_errors.clone())
|
||||||
|
}
|
||||||
|
@ -30,12 +30,20 @@ pub struct AppState {
|
|||||||
pub waiting_requests: RwLock<HashMap<u64, RequestWaiter>>,
|
pub waiting_requests: RwLock<HashMap<u64, RequestWaiter>>,
|
||||||
pub pending_terminal_request: RwLock<bool>,
|
pub pending_terminal_request: RwLock<bool>,
|
||||||
pub bans: RwLock<std::collections::HashSet<Option<Client>>>,
|
pub bans: RwLock<std::collections::HashSet<Option<Client>>>,
|
||||||
|
// setup_errors is never modified and so doesn't need to be wrapped in RwLock
|
||||||
|
pub setup_errors: Vec<String>,
|
||||||
server: RwLock<Server>,
|
server: RwLock<Server>,
|
||||||
pool: sqlx::SqlitePool,
|
pool: sqlx::SqlitePool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
pub fn new(config: AppConfig, session: Session, server: Server, pool: SqlitePool) -> AppState {
|
pub fn new(
|
||||||
|
config: AppConfig,
|
||||||
|
session: Session,
|
||||||
|
server: Server,
|
||||||
|
pool: SqlitePool,
|
||||||
|
setup_errors: Vec<String>,
|
||||||
|
) -> AppState {
|
||||||
AppState {
|
AppState {
|
||||||
config: RwLock::new(config),
|
config: RwLock::new(config),
|
||||||
session: RwLock::new(session),
|
session: RwLock::new(session),
|
||||||
@ -43,6 +51,7 @@ impl AppState {
|
|||||||
waiting_requests: RwLock::new(HashMap::new()),
|
waiting_requests: RwLock::new(HashMap::new()),
|
||||||
pending_terminal_request: RwLock::new(false),
|
pending_terminal_request: RwLock::new(false),
|
||||||
bans: RwLock::new(HashSet::new()),
|
bans: RwLock::new(HashSet::new()),
|
||||||
|
setup_errors,
|
||||||
server: RwLock::new(server),
|
server: RwLock::new(server),
|
||||||
pool,
|
pool,
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "creddy",
|
"productName": "creddy",
|
||||||
"version": "0.3.1"
|
"version": "0.3.2"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
@ -28,7 +28,12 @@ listen('launch-terminal-request', async (tauriEvent) => {
|
|||||||
// else, session is unlocked, so do nothing
|
// else, session is unlocked, so do nothing
|
||||||
// (although we shouldn't even get the event in that case)
|
// (although we shouldn't even get the event in that case)
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
invoke('get_setup_errors')
|
||||||
|
.then(errs => {
|
||||||
|
$appState.setupErrors = errs.map(e => ({msg: e, show: true}));
|
||||||
|
});
|
||||||
|
|
||||||
acceptRequest();
|
acceptRequest();
|
||||||
</script>
|
</script>
|
||||||
|
@ -8,6 +8,7 @@ export let appState = writable({
|
|||||||
currentRequest: null,
|
currentRequest: null,
|
||||||
pendingRequests: queue(),
|
pendingRequests: queue(),
|
||||||
credentialStatus: 'locked',
|
credentialStatus: 'locked',
|
||||||
|
setupErrors: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,4 +51,17 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{/await}
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if $appState.setupErrors.some(e => e.show)}
|
||||||
|
<div class="toast">
|
||||||
|
{#each $appState.setupErrors as error}
|
||||||
|
{#if error.show}
|
||||||
|
<div class="alert alert-error shadow-lg">
|
||||||
|
{error.msg}
|
||||||
|
<button class="btn btn-sm btn-alert-error" on:click={() => error.show = false}>Ok</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
Loading…
x
Reference in New Issue
Block a user