diff --git a/src/lib.rs b/src/lib.rs index 405a69e..a747411 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,7 @@ extern crate relm; extern crate relm_derive; extern crate bitcoin_hwi as hwi; #[cfg(feature = "serde")] +#[macro_use] extern crate serde_crate as serde; extern crate glade as gladis; diff --git a/src/view/wallet/component.rs b/src/view/wallet/component.rs index b69208b..dc3d9b6 100644 --- a/src/view/wallet/component.rs +++ b/src/view/wallet/component.rs @@ -32,7 +32,7 @@ use wallet::lex_order::lex_order::LexOrder; use super::pay::beneficiary_row::Beneficiary; use super::pay::FeeRate; use super::{pay, ElectrumState, Msg, ViewModel, Widgets}; -use crate::view::{error_dlg, launch, settings, NotificationBoxExt}; +use crate::view::{error_dlg, file_open_dlg, launch, settings, NotificationBoxExt}; use crate::worker::{electrum, exchange, ElectrumWorker, ExchangeWorker}; pub struct Component { @@ -355,6 +355,16 @@ impl Update for Component { .as_ref() .map(|stream| stream.emit(launch::Msg::ShowPage(launch::Page::Import))); } + Msg::ExportHistory => { + if let Some(path) = file_open_dlg( + Some(self.widgets.as_root()), + "Export history", + "Comma-separated values", + "*.csv", + ) { + match self.model.export_history(path) {} + } + } Msg::Close => self.close(), Msg::About => { self.launcher_stream diff --git a/src/view/wallet/mod.rs b/src/view/wallet/mod.rs index b17fdc6..78f2d4a 100644 --- a/src/view/wallet/mod.rs +++ b/src/view/wallet/mod.rs @@ -34,6 +34,7 @@ pub enum Msg { Open, Close, About, + ExportHistory, Duplicate, Import, Launch(launch::Msg), diff --git a/src/view/wallet/view_model.rs b/src/view/wallet/view_model.rs index 4e4bc30..0af3919 100644 --- a/src/view/wallet/view_model.rs +++ b/src/view/wallet/view_model.rs @@ -10,11 +10,16 @@ // . use std::collections::BTreeSet; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; -use bpro::{file, DescriptorError, ElectrumServer, FileDocument, Signer, Wallet, WalletSettings}; +use bitcoin::Txid; +use bpro::{ + file, DescriptorError, ElectrumServer, FileDocument, HistoryEntry, Signer, Wallet, + WalletSettings, +}; use wallet::descriptors::DescriptorClass; use wallet::hd::UnhardenedIndex; +use crate::model::FormatDate; use super::pay::beneficiary_row::BeneficiaryModel; use crate::worker::exchange::{Exchange, Fiat}; @@ -92,4 +97,34 @@ impl ViewModel { None }) } + + pub fn export_history(&self, path: impl AsRef) { + #[derive(Serialize, Deserialize)] + #[serde(crate = serde_crate)] + struct Entry { + pub timestamp: String, + pub height: u32, + pub txid: Txid, + pub label: String, + pub amount: u64, + pub balance: u64, + pub fee: u64, + pub fee_rate: u64, + } + + impl From for Entry { + fn from(entry: HistoryEntry) -> Self { Entry { + timestamp: entry.onchain.format_date(), + height: entry.onchain.status.into_u32(), + txid: entry.onchain.txid, + label: entry.comment.map(|c| c.label).unwrap_or_default(), + amount: entry., + balance: 0, + fee: 0, + fee_rate: 0, + } } + } + + let history: Vec<_> = self.model.wallet().history().iter().collect(); + } } diff --git a/src/view/wallet/wallet.glade b/src/view/wallet/wallet.glade index 6d8c6aa..95471a9 100644 --- a/src/view/wallet/wallet.glade +++ b/src/view/wallet/wallet.glade @@ -363,6 +363,20 @@ True False + + + True + False + E_xport history + True + + + + + True + False + + True diff --git a/src/view/wallet/widget.rs b/src/view/wallet/widget.rs index 3b64fe4..6c7fc07 100644 --- a/src/view/wallet/widget.rs +++ b/src/view/wallet/widget.rs @@ -70,6 +70,7 @@ pub struct Widgets { new_btn: Button, open_btn: Button, settings_btn: Button, + export_history_mi: MenuItem, redefine_mi: MenuItem, import_mi: MenuItem, settings_mi: MenuItem, @@ -164,6 +165,12 @@ impl Widgets { Msg::Pay(pay::Msg::Show) ); connect!(relm, self.refresh_btn, connect_clicked(_), Msg::Refresh); + connect!( + relm, + self.export_history_mi, + connect_activate(_), + Msg::ExportHistory + ); connect!(relm, self.redefine_mi, connect_activate(_), Msg::Duplicate); connect!(relm, self.import_mi, connect_activate(_), Msg::Import); connect!(relm, self.settings_mi, connect_activate(_), Msg::Settings); @@ -513,14 +520,7 @@ impl Widgets { balance += item.balance(); let btc = format!("{:+.08}", item.balance() as f64 / 100_000_000.0); let btc_balance = format!("{:.08}", balance as f64 / 100_000_000.0); - let date = match item.onchain.status { - OnchainStatus::Blockchain(height) => item - .onchain - .date_time() - .map(|dt| dt.format("%F %H:%M").to_string()) - .unwrap_or_else(|| format!("{height}")), - OnchainStatus::Mempool => s!("mempool"), - }; + let date = item.onchain.format_date(); let txid = item.onchain.txid; let baid = Baid58::with("txid", txid.into_inner()); let mut sort = item.onchain.status.into_u32();