diff --git a/gui/src/app/cache.rs b/gui/src/app/cache.rs index 05944514..1a26bc67 100644 --- a/gui/src/app/cache.rs +++ b/gui/src/app/cache.rs @@ -2,7 +2,7 @@ use crate::daemon::model::Coin; use liana::miniscript::bitcoin::Network; use std::path::PathBuf; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Cache { pub datadir_path: PathBuf, pub network: Network, diff --git a/gui/src/app/message.rs b/gui/src/app/message.rs index 78ac4ced..dd466946 100644 --- a/gui/src/app/message.rs +++ b/gui/src/app/message.rs @@ -20,6 +20,7 @@ use crate::{ pub enum Message { Tick, UpdateCache(Result), + UpdatePanelCache(/* is current panel */ bool, Result), View(view::Message), LoadDaemonConfig(Box), DaemonConfigLoaded(Result<(), Error>), diff --git a/gui/src/app/mod.rs b/gui/src/app/mod.rs index 43415384..7e75873a 100644 --- a/gui/src/app/mod.rs +++ b/gui/src/app/mod.rs @@ -63,7 +63,7 @@ impl Panels { ) -> Panels { Self { current: Menu::Home, - home: Home::new(wallet.clone(), &cache.coins), + home: Home::new(wallet.clone(), &cache.coins, cache.blockheight), coins: CoinsPanel::new(&cache.coins, wallet.main_descriptor.first_timelock_value()), transactions: TransactionsPanel::new(wallet.clone()), psbts: PsbtsPanel::new(wallet.clone()), @@ -279,7 +279,24 @@ impl App { } Message::UpdateCache(res) => { match res { - Ok(cache) => self.cache = cache, + Ok(cache) => { + self.cache.clone_from(&cache); + let current = &self.panels.current; + let daemon = self.daemon.clone(); + // These are the panels to update with the cache. + let mut panels = [(&mut self.panels.home, Menu::Home)]; + let commands: Vec<_> = panels + .iter_mut() + .map(|(panel, menu)| { + panel.update( + daemon.clone(), + &cache, + Message::UpdatePanelCache(current == menu, Ok(cache.clone())), + ) + }) + .collect(); + return Command::batch(commands); + } Err(e) => tracing::error!("Failed to update cache: {}", e), } Command::none() diff --git a/gui/src/app/state/mod.rs b/gui/src/app/state/mod.rs index ca70cf82..88cdc75c 100644 --- a/gui/src/app/state/mod.rs +++ b/gui/src/app/state/mod.rs @@ -68,6 +68,7 @@ pub fn redirect(menu: Menu) -> Command { pub struct Home { wallet: Arc, + blockheight: i32, balance: Amount, unconfirmed_balance: Amount, remaining_sequence: Option, @@ -82,7 +83,7 @@ pub struct Home { } impl Home { - pub fn new(wallet: Arc, coins: &[Coin]) -> Self { + pub fn new(wallet: Arc, coins: &[Coin], blockheight: i32) -> Self { let (balance, unconfirmed_balance) = coins.iter().fold( (Amount::from_sat(0), Amount::from_sat(0)), |(balance, unconfirmed_balance), coin| { @@ -95,8 +96,10 @@ impl Home { } }, ); + Self { wallet, + blockheight, balance, unconfirmed_balance, remaining_sequence: None, @@ -110,6 +113,10 @@ impl Home { processing: false, } } + + fn wallet_is_syncing(&self) -> bool { + self.blockheight <= 0 + } } impl State for Home { @@ -217,6 +224,14 @@ impl State for Home { self.pending_events = events; } }, + Message::UpdatePanelCache(is_current, Ok(cache)) => { + let wallet_was_syncing = self.wallet_is_syncing(); + self.blockheight = cache.blockheight; + // If this is the current panel, reload it if wallet is no longer syncing. + if is_current && wallet_was_syncing && !self.wallet_is_syncing() { + return self.reload(daemon, self.wallet.clone()); + } + } Message::View(view::Message::Label(_, _)) | Message::LabelsUpdated(_) => { match self.labels_edited.update( daemon, @@ -293,6 +308,10 @@ impl State for Home { daemon: Arc, wallet: Arc, ) -> Command { + // Wait for wallet to finish syncing before reloading data. + if self.wallet_is_syncing() { + return Command::none(); + } self.selected_event = None; self.wallet = wallet; let daemon1 = daemon.clone();