show rescan warning after restoring wallet from backup
This commit is contained in:
parent
05b848c5d2
commit
d812ad63a1
@ -7,9 +7,16 @@ pub enum Menu {
|
||||
Transactions,
|
||||
TransactionPreSelected(Txid),
|
||||
Settings,
|
||||
SettingsPreSelected(SettingsOption),
|
||||
Coins,
|
||||
CreateSpendTx,
|
||||
Recovery,
|
||||
RefreshCoins(Vec<OutPoint>),
|
||||
PsbtPreSelected(Txid),
|
||||
}
|
||||
|
||||
/// Pre-selectable settings options.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SettingsOption {
|
||||
Node,
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ use wallet::{sync_status, SyncStatus};
|
||||
use crate::{
|
||||
app::{cache::Cache, error::Error, menu::Menu, wallet::Wallet},
|
||||
daemon::{embedded::EmbeddedDaemon, Daemon, DaemonBackend},
|
||||
node::bitcoind::Bitcoind,
|
||||
node::{bitcoind::Bitcoind, NodeType},
|
||||
};
|
||||
|
||||
use self::state::SettingsState;
|
||||
@ -63,7 +63,15 @@ impl Panels {
|
||||
daemon_backend: DaemonBackend,
|
||||
internal_bitcoind: Option<&Bitcoind>,
|
||||
config: Arc<Config>,
|
||||
restored_from_backup: bool,
|
||||
) -> Panels {
|
||||
let show_rescan_warning = restored_from_backup
|
||||
&& daemon_backend.is_lianad()
|
||||
&& daemon_backend
|
||||
.node_type()
|
||||
.map(|nt| nt == NodeType::Bitcoind)
|
||||
// We don't know the node type for external lianad so assume it's bitcoind.
|
||||
.unwrap_or(true);
|
||||
Self {
|
||||
current: Menu::Home,
|
||||
home: Home::new(
|
||||
@ -77,6 +85,7 @@ impl Panels {
|
||||
cache.last_poll_at_startup,
|
||||
),
|
||||
cache.blockheight,
|
||||
show_rescan_warning,
|
||||
),
|
||||
coins: CoinsPanel::new(&cache.coins, wallet.main_descriptor.first_timelock_value()),
|
||||
transactions: TransactionsPanel::new(wallet.clone()),
|
||||
@ -106,7 +115,7 @@ impl Panels {
|
||||
Menu::PSBTs => &self.psbts,
|
||||
Menu::Transactions => &self.transactions,
|
||||
Menu::TransactionPreSelected(_) => &self.transactions,
|
||||
Menu::Settings => &self.settings,
|
||||
Menu::Settings | Menu::SettingsPreSelected(_) => &self.settings,
|
||||
Menu::Coins => &self.coins,
|
||||
Menu::CreateSpendTx => &self.create_spend,
|
||||
Menu::Recovery => &self.recovery,
|
||||
@ -122,7 +131,7 @@ impl Panels {
|
||||
Menu::PSBTs => &mut self.psbts,
|
||||
Menu::Transactions => &mut self.transactions,
|
||||
Menu::TransactionPreSelected(_) => &mut self.transactions,
|
||||
Menu::Settings => &mut self.settings,
|
||||
Menu::Settings | Menu::SettingsPreSelected(_) => &mut self.settings,
|
||||
Menu::Coins => &mut self.coins,
|
||||
Menu::CreateSpendTx => &mut self.create_spend,
|
||||
Menu::Recovery => &mut self.recovery,
|
||||
@ -150,6 +159,7 @@ impl App {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
data_dir: PathBuf,
|
||||
internal_bitcoind: Option<Bitcoind>,
|
||||
restored_from_backup: bool,
|
||||
) -> (App, Task<Message>) {
|
||||
let config = Arc::new(config);
|
||||
let mut panels = Panels::new(
|
||||
@ -159,6 +169,7 @@ impl App {
|
||||
daemon.backend(),
|
||||
internal_bitcoind.as_ref(),
|
||||
config.clone(),
|
||||
restored_from_backup,
|
||||
);
|
||||
let cmd = panels.home.reload(daemon.clone(), wallet.clone());
|
||||
(
|
||||
@ -205,6 +216,16 @@ impl App {
|
||||
return Task::none();
|
||||
};
|
||||
}
|
||||
menu::Menu::SettingsPreSelected(setting) => {
|
||||
self.panels.current = menu.clone();
|
||||
return self.panels.current_mut().update(
|
||||
self.daemon.clone(),
|
||||
&self.cache,
|
||||
Message::View(view::Message::Settings(match setting {
|
||||
&menu::SettingsOption::Node => view::SettingsMessage::EditBitcoindSettings,
|
||||
})),
|
||||
);
|
||||
}
|
||||
menu::Menu::RefreshCoins(preselected) => {
|
||||
self.panels.create_spend = CreateSpendPanel::new_self_send(
|
||||
self.wallet.clone(),
|
||||
|
||||
@ -135,6 +135,7 @@ pub struct Home {
|
||||
selected_event: Option<(HistoryTransaction, usize)>,
|
||||
labels_edited: LabelsEdited,
|
||||
warning: Option<Error>,
|
||||
show_rescan_warning: bool,
|
||||
}
|
||||
|
||||
impl Home {
|
||||
@ -143,6 +144,7 @@ impl Home {
|
||||
coins: &[Coin],
|
||||
sync_status: SyncStatus,
|
||||
tip_height: i32,
|
||||
show_rescan_warning: bool,
|
||||
) -> Self {
|
||||
let (balance, unconfirmed_balance, expiring_coins, remaining_seq) = coins_summary(
|
||||
coins,
|
||||
@ -163,6 +165,7 @@ impl Home {
|
||||
warning: None,
|
||||
is_last_page: false,
|
||||
processing: false,
|
||||
show_rescan_warning,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,6 +194,7 @@ impl State for Home {
|
||||
self.is_last_page,
|
||||
self.processing,
|
||||
&self.sync_status,
|
||||
self.show_rescan_warning,
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -276,6 +280,9 @@ impl State for Home {
|
||||
self.warning = Some(e);
|
||||
}
|
||||
},
|
||||
Message::View(view::Message::HideRescanWarning) => {
|
||||
self.show_rescan_warning = false;
|
||||
}
|
||||
Message::View(view::Message::SelectPayment(outpoint)) => {
|
||||
return Task::perform(
|
||||
async move {
|
||||
|
||||
@ -4,14 +4,16 @@ use std::{collections::HashMap, time::Duration, vec};
|
||||
use iced::{
|
||||
alignment,
|
||||
widget::{Container, Row, Space},
|
||||
Alignment, Length,
|
||||
Alignment::{self, Center},
|
||||
Length,
|
||||
};
|
||||
|
||||
use liana::miniscript::bitcoin;
|
||||
use liana_ui::{
|
||||
color,
|
||||
component::{amount::*, button, card, event, form, spinner, text::*},
|
||||
icon, theme,
|
||||
icon::{self, cross_icon},
|
||||
theme,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
@ -19,13 +21,46 @@ use crate::{
|
||||
app::{
|
||||
cache::Cache,
|
||||
error::Error,
|
||||
menu::Menu,
|
||||
menu::{self, Menu},
|
||||
view::{coins, dashboard, label, message::Message},
|
||||
wallet::SyncStatus,
|
||||
},
|
||||
daemon::model::{HistoryTransaction, Payment, PaymentKind, TransactionKind},
|
||||
};
|
||||
|
||||
const RESCAN_WARNING: &str = "As this wallet was restored from a backup, you may need to rescan the blockchain to see past transactions.";
|
||||
|
||||
fn rescan_warning<'a>() -> Element<'a, Message> {
|
||||
Container::new(
|
||||
Column::new()
|
||||
.spacing(10)
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(icon::warning_icon().style(theme::text::warning))
|
||||
.push(text(RESCAN_WARNING).style(theme::text::warning))
|
||||
.align_y(Center),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push(
|
||||
button::secondary(None, "Go to rescan").on_press(Message::Menu(
|
||||
Menu::SettingsPreSelected(menu::SettingsOption::Node),
|
||||
)),
|
||||
)
|
||||
.push(
|
||||
button::secondary(Some(cross_icon()), "Dismiss")
|
||||
.on_press(Message::HideRescanWarning),
|
||||
),
|
||||
),
|
||||
)
|
||||
.padding(25)
|
||||
.style(theme::card::border)
|
||||
.into()
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn home_view<'a>(
|
||||
balance: &'a bitcoin::Amount,
|
||||
@ -36,6 +71,7 @@ pub fn home_view<'a>(
|
||||
is_last_page: bool,
|
||||
processing: bool,
|
||||
sync_status: &SyncStatus,
|
||||
show_rescan_warning: bool,
|
||||
) -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.push(h3("Balance"))
|
||||
@ -99,6 +135,7 @@ pub fn home_view<'a>(
|
||||
},
|
||||
),
|
||||
)
|
||||
.push_maybe(show_rescan_warning.then_some(rescan_warning()))
|
||||
.push_maybe(if expiring_coins.is_empty() {
|
||||
remaining_sequence.map(|sequence| {
|
||||
Container::new(
|
||||
|
||||
@ -24,6 +24,7 @@ pub enum Message {
|
||||
CreateRbf(CreateRbfMessage),
|
||||
ShowQrCode(usize),
|
||||
ImportExport(ImportExportMessage),
|
||||
HideRescanWarning,
|
||||
}
|
||||
|
||||
impl Close for Message {
|
||||
|
||||
@ -76,6 +76,21 @@ impl DaemonBackend {
|
||||
pub fn is_embedded(&self) -> bool {
|
||||
matches!(self, DaemonBackend::EmbeddedLianad(_))
|
||||
}
|
||||
|
||||
pub fn is_lianad(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
DaemonBackend::EmbeddedLianad(_) | DaemonBackend::ExternalLianad
|
||||
)
|
||||
}
|
||||
|
||||
pub fn node_type(&self) -> Option<node::NodeType> {
|
||||
if let DaemonBackend::EmbeddedLianad(node_type) = self {
|
||||
*node_type
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -103,6 +103,7 @@ pub enum Message {
|
||||
),
|
||||
Error,
|
||||
>,
|
||||
/* restored_from_backup */ bool,
|
||||
),
|
||||
Started(StartedResult),
|
||||
Loaded(Result<(Arc<dyn Daemon + Sync + Send>, GetInfoResult), Error>),
|
||||
|
||||
@ -369,7 +369,9 @@ impl GUI {
|
||||
},
|
||||
|r| {
|
||||
let r = r.map_err(loader::Error::RestoreBackup);
|
||||
Message::Load(Box::new(loader::Message::App(r)))
|
||||
Message::Load(Box::new(loader::Message::App(
|
||||
r, /* restored_from_backup */ true,
|
||||
)))
|
||||
},
|
||||
)
|
||||
} else {
|
||||
@ -380,17 +382,29 @@ impl GUI {
|
||||
daemon,
|
||||
loader.datadir_path.clone(),
|
||||
bitcoind,
|
||||
false,
|
||||
);
|
||||
self.state = State::App(app);
|
||||
command.map(|msg| Message::Run(Box::new(msg)))
|
||||
}
|
||||
}
|
||||
loader::Message::App(Ok((cache, wallet, config, daemon, datadir, bitcoind))) => {
|
||||
let (app, command) = App::new(cache, wallet, config, daemon, datadir, bitcoind);
|
||||
loader::Message::App(
|
||||
Ok((cache, wallet, config, daemon, datadir, bitcoind)),
|
||||
restored_from_backup,
|
||||
) => {
|
||||
let (app, command) = App::new(
|
||||
cache,
|
||||
wallet,
|
||||
config,
|
||||
daemon,
|
||||
datadir,
|
||||
bitcoind,
|
||||
restored_from_backup,
|
||||
);
|
||||
self.state = State::App(app);
|
||||
command.map(|msg| Message::Run(Box::new(msg)))
|
||||
}
|
||||
loader::Message::App(Err(e)) => {
|
||||
loader::Message::App(Err(e), _) => {
|
||||
tracing::error!("Fail to import backup: {e}");
|
||||
Task::none()
|
||||
}
|
||||
@ -506,6 +520,7 @@ pub fn create_app_with_remote_backend(
|
||||
Arc::new(remote_backend),
|
||||
datadir,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user