feat(tauri): Initialize Context in background (#59)

This PR does the following:
- The Context (including Bitcoin wallet, Monero wallet, ...) is initialized in the background. This allows the window to be displayed instantly upon startup.
- Host sends events to Guest about progress of Context initialization. Those events are used to display an alert in the navigation bar.
- If a Tauri command is invoked which requires the Context to be available, an error will be returned
- As soon as the Context becomes available the `Guest` requests the history and Bitcoin balance
- Re-enables Material UI animations
This commit is contained in:
binarybaron 2024-09-03 12:28:30 +02:00 committed by GitHub
parent 792fbbf746
commit e4141c763b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 369 additions and 191 deletions

View file

@ -17,7 +17,9 @@ use std::fmt;
use std::future::Future;
use std::path::PathBuf;
use std::sync::{Arc, Mutex as SyncMutex, Once};
use tauri_bindings::TauriHandle;
use tauri_bindings::{
TauriContextInitializationProgress, TauriContextStatusEvent, TauriEmitter, TauriHandle,
};
use tokio::sync::{broadcast, broadcast::Sender, Mutex as TokioMutex, RwLock};
use tokio::task::JoinHandle;
use tracing::level_filters::LevelFilter;
@ -292,6 +294,13 @@ impl ContextBuilder {
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read seed in file")?;
// We initialize the Bitcoin wallet below
// To display the progress to the user, we emit events to the Tauri frontend
self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::OpeningBitcoinWallet,
));
let bitcoin_wallet = {
if let Some(bitcoin) = self.bitcoin {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) =
@ -311,6 +320,13 @@ impl ContextBuilder {
}
};
// We initialize the Monero wallet below
// To display the progress to the user, we emit events to the Tauri frontend
self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::OpeningMoneroWallet,
));
let (monero_wallet, monero_rpc_process) = {
if let Some(monero) = self.monero {
let monero_daemon_address = monero.apply_defaults(self.is_testnet);
@ -322,10 +338,19 @@ impl ContextBuilder {
}
};
// We initialize the Database below
// To display the progress to the user, we emit events to the Tauri frontend
self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::OpeningDatabase,
));
let db = open_db(data_dir.join("sqlite")).await?;
let tor_socks5_port = self.tor.map_or(9050, |tor| tor.tor_socks5_port);
let context = Context {
db: open_db(data_dir.join("sqlite")).await?,
db,
bitcoin_wallet,
monero_wallet,
monero_rpc_process,

View file

@ -2,10 +2,12 @@ use crate::{monero, network::quote::BidQuote};
use anyhow::Result;
use bitcoin::Txid;
use serde::Serialize;
use strum::Display;
use typeshare::typeshare;
use uuid::Uuid;
static SWAP_PROGRESS_EVENT_NAME: &str = "swap-progress-update";
static CONTEXT_INIT_PROGRESS_EVENT_NAME: &str = "context-init-progress-update";
#[derive(Debug, Clone)]
pub struct TauriHandle(
@ -41,6 +43,10 @@ pub trait TauriEmitter {
TauriSwapProgressEventWrapper { swap_id, event },
);
}
fn emit_context_init_progress_event(&self, event: TauriContextStatusEvent) {
let _ = self.emit_tauri_event(CONTEXT_INIT_PROGRESS_EVENT_NAME, event);
}
}
impl TauriEmitter for TauriHandle {
@ -58,6 +64,23 @@ impl TauriEmitter for Option<TauriHandle> {
}
}
#[typeshare]
#[derive(Display, Clone, Serialize)]
pub enum TauriContextInitializationProgress {
OpeningBitcoinWallet,
OpeningMoneroWallet,
OpeningDatabase,
}
#[typeshare]
#[derive(Display, Clone, Serialize)]
#[serde(tag = "type", content = "content")]
pub enum TauriContextStatusEvent {
Initializing(TauriContextInitializationProgress),
Available,
Failed,
}
#[derive(Serialize, Clone)]
#[typeshare]
pub struct TauriSwapProgressEventWrapper {