gui(home): indicate existing wallet is syncing

If opening an existing wallet that uses a local backend, indicate
that it is checking for new transactions until the first poll
completes.

A remote backend is always synced after the initial scan.
This commit is contained in:
Michael Mallan 2024-10-19 11:12:35 +01:00
parent f7314aa26e
commit ec7556ee12
No known key found for this signature in database
GPG Key ID: 5177CDCEDB0EABEB
3 changed files with 64 additions and 13 deletions

View File

@ -67,6 +67,7 @@ impl Panels {
wallet.clone(),
&cache.coins,
cache.blockheight,
cache.last_poll_timestamp,
daemon_backend.clone(),
),
coins: CoinsPanel::new(&cache.coins, wallet.main_descriptor.first_timelock_value()),

View File

@ -69,8 +69,17 @@ pub fn redirect(menu: Menu) -> Command<Message> {
})
}
fn wallet_is_syncing(daemon_backend: DaemonBackend, blockheight: i32) -> bool {
fn wallet_is_syncing(
daemon_backend: DaemonBackend,
blockheight: i32,
last_poll: Option<u32>,
last_poll_at_startup: Option<u32>,
) -> bool {
match daemon_backend {
// If remote, the wallet is always synced except before the first scan
// after creation.
DaemonBackend::RemoteBackend => blockheight <= 0,
// If blockheight <= 0, then this is a newly created wallet.
// If user imported descriptor and is using a local bitcoind, a rescan
// will need to be performed in order to see past transactions and so the
// syncing status could be misleading as it could suggest the rescan is
@ -79,14 +88,29 @@ fn wallet_is_syncing(daemon_backend: DaemonBackend, blockheight: i32) -> bool {
// treat it the same as bitcoind to be sure we don't mislead the user.
DaemonBackend::EmbeddedLianad(Some(NodeType::Bitcoind))
| DaemonBackend::EmbeddedLianad(None)
| DaemonBackend::ExternalLianad => false,
_ => blockheight <= 0,
| DaemonBackend::ExternalLianad
if blockheight <= 0 =>
{
false
}
// If external daemon, we cannot be sure it will return last poll
// as it depends on the version, so assume it won't unless the
// last poll at startup is set.
// TODO: should we check the daemon version at GUI startup?
DaemonBackend::ExternalLianad if last_poll_at_startup.is_none() => false,
// For an existing wallet with any local node type, the first poll
// completing means the wallet has caught up with the tip.
// For a new wallet with a non-bitcoind local node, the first poll
// completing also means that the initial rescan has completed.
_ => last_poll <= last_poll_at_startup,
}
}
pub struct Home {
wallet: Arc<Wallet>,
wallet_is_syncing: bool,
blockheight: i32,
last_poll_at_startup: Option<u32>,
balance: Amount,
unconfirmed_balance: Amount,
remaining_sequence: Option<u32>,
@ -105,6 +129,7 @@ impl Home {
wallet: Arc<Wallet>,
coins: &[Coin],
blockheight: i32,
last_poll: Option<u32>,
daemon_backend: DaemonBackend,
) -> Self {
let (balance, unconfirmed_balance) = coins.iter().fold(
@ -120,11 +145,14 @@ impl Home {
},
);
let wallet_is_syncing = wallet_is_syncing(daemon_backend, blockheight);
let wallet_is_syncing =
wallet_is_syncing(daemon_backend, blockheight, last_poll, last_poll);
Self {
wallet,
wallet_is_syncing,
last_poll_at_startup: last_poll,
blockheight,
balance,
unconfirmed_balance,
remaining_sequence: None,
@ -138,6 +166,15 @@ impl Home {
processing: false,
}
}
fn wallet_is_syncing(&self, daemon_backend: DaemonBackend, last_poll: Option<u32>) -> bool {
wallet_is_syncing(
daemon_backend,
self.blockheight,
last_poll,
self.last_poll_at_startup,
)
}
}
impl State for Home {
@ -170,6 +207,7 @@ impl State for Home {
self.is_last_page,
self.processing,
self.wallet_is_syncing,
self.blockheight,
),
)
}
@ -248,7 +286,9 @@ impl State for Home {
},
Message::UpdatePanelCache(is_current, Ok(cache)) => {
let wallet_was_syncing = self.wallet_is_syncing;
self.wallet_is_syncing = wallet_is_syncing(daemon.backend(), cache.blockheight);
self.blockheight = cache.blockheight;
self.wallet_is_syncing =
self.wallet_is_syncing(daemon.backend(), cache.last_poll_timestamp);
// 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());

View File

@ -36,6 +36,7 @@ pub fn home_view<'a>(
is_last_page: bool,
processing: bool,
wallet_is_syncing: bool,
blockheight: i32,
) -> Element<'a, Message> {
Column::new()
.push(h3("Balance"))
@ -58,14 +59,23 @@ pub fn home_view<'a>(
))
})
.push_maybe(if wallet_is_syncing {
Some(Row::new().push(text("Syncing").style(color::GREY_2)).push(
spinner::typing_text_carousel(
"...",
true,
Duration::from_millis(2000),
|content| text(content).style(color::GREY_2),
),
))
Some(
Row::new()
.push(
text(if blockheight <= 0 {
"Syncing"
} else {
"Checking for new transactions"
})
.style(color::GREY_2),
)
.push(spinner::typing_text_carousel(
"...",
true,
Duration::from_millis(2000),
|content| text(content).style(color::GREY_2),
)),
)
} else {
None
})