spend: add remaining sequence to coins

This commit is contained in:
edouard 2022-11-30 10:20:31 +01:00
parent 6d92056b9d
commit f0758d28ab
4 changed files with 70 additions and 18 deletions

View File

@ -71,9 +71,12 @@ impl App {
.into(),
menu::Menu::Receive => ReceivePanel::default().into(),
menu::Menu::Spend => SpendPanel::new(self.config.clone(), &self.cache.spend_txs).into(),
menu::Menu::CreateSpendTx => {
CreateSpendPanel::new(self.config.clone(), &self.cache.coins).into()
}
menu::Menu::CreateSpendTx => CreateSpendPanel::new(
self.config.clone(),
&self.cache.coins,
self.daemon.config().main_descriptor.timelock_value(),
)
.into(),
};
self.state.load(self.daemon.clone())
}

View File

@ -104,13 +104,13 @@ pub struct CreateSpendPanel {
}
impl CreateSpendPanel {
pub fn new(config: Config, coins: &[Coin]) -> Self {
pub fn new(config: Config, coins: &[Coin], timelock: u32) -> Self {
Self {
draft: step::TransactionDraft::default(),
current: 0,
steps: vec![
Box::new(step::ChooseRecipients::default()),
Box::new(step::ChooseCoins::new(coins.to_vec())),
Box::new(step::ChooseCoins::new(coins.to_vec(), timelock)),
Box::new(step::ChooseFeerate::default()),
Box::new(step::SaveSpend::new(config)),
],

View File

@ -244,6 +244,7 @@ impl Step for ChooseFeerate {
#[derive(Default)]
pub struct ChooseCoins {
timelock: u32,
coins: Vec<(Coin, bool)>,
/// draft output amount must be superior to total input amount.
is_valid: bool,
@ -251,8 +252,9 @@ pub struct ChooseCoins {
}
impl ChooseCoins {
pub fn new(coins: Vec<Coin>) -> Self {
pub fn new(coins: Vec<Coin>, timelock: u32) -> Self {
Self {
timelock,
coins: coins
.into_iter()
.filter_map(|c| {
@ -315,8 +317,14 @@ impl Step for ChooseCoins {
.collect();
}
fn view<'a>(&'a self, _cache: &'a Cache) -> Element<'a, view::Message> {
view::spend::step::choose_coins_view(&self.coins, self.total_needed.as_ref(), self.is_valid)
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
view::spend::step::choose_coins_view(
cache,
self.timelock,
&self.coins,
self.total_needed.as_ref(),
self.is_valid,
)
}
}

View File

@ -7,11 +7,13 @@ use liana::miniscript::bitcoin::Amount;
use crate::{
app::{
cache::Cache,
error::Error,
view::{message::*, modal},
},
daemon::model::Coin,
ui::{
color,
component::{
badge, button, card, form,
text::{text, Text},
@ -126,6 +128,8 @@ pub fn choose_feerate_view<'a>(
}
pub fn choose_coins_view<'a>(
cache: &Cache,
timelock: u32,
coins: &[(Coin, bool)],
total_needed: Option<&Amount>,
is_valid: bool,
@ -136,14 +140,20 @@ pub fn choose_coins_view<'a>(
Column::new()
.push(text("Choose coins").bold().size(50))
.push(
Column::new().spacing(10).push(
coins
.iter()
.enumerate()
.fold(Column::new().spacing(10), |col, (i, (coin, selected))| {
col.push(coin_list_view(i, coin, *selected))
}),
),
Column::new()
.spacing(10)
.push(coins.iter().enumerate().fold(
Column::new().spacing(10),
|col, (i, (coin, selected))| {
col.push(coin_list_view(
i,
coin,
timelock,
cache.blockheight as u32,
*selected,
))
},
)),
)
.push_maybe(if is_valid {
Some(Container::new(
@ -164,7 +174,13 @@ pub fn choose_coins_view<'a>(
)
}
fn coin_list_view<'a>(i: usize, coin: &Coin, selected: bool) -> Element<'a, Message> {
fn coin_list_view<'a>(
i: usize,
coin: &Coin,
timelock: u32,
blockheight: u32,
selected: bool,
) -> Element<'a, Message> {
Container::new(
Button::new(
Row::new()
@ -176,7 +192,32 @@ fn coin_list_view<'a>(i: usize, coin: &Coin, selected: bool) -> Element<'a, Mess
icon::square_icon()
})
.push(badge::coin())
.push(text(format!("block: {}", coin.block_height.unwrap_or(0))).small())
.push_maybe(if let Some(b) = coin.block_height {
if blockheight > b as u32 + timelock {
Some(Container::new(
Row::new()
.spacing(5)
.push(text(" 0").small().style(color::ALERT))
.push(
icon::hourglass_done_icon().small().style(color::ALERT),
)
.align_items(Alignment::Center),
))
} else {
Some(Container::new(
Row::new()
.spacing(5)
.push(
text(format!(" {}", b as u32 + timelock - blockheight))
.small(),
)
.push(icon::hourglass_icon().small())
.align_items(Alignment::Center),
))
}
} else {
None
})
.spacing(10)
.align_items(Alignment::Center)
.width(Length::Fill),