From ca096c71b52c5843b68dba0ceaeabe2755bf29a7 Mon Sep 17 00:00:00 2001 From: edouard Date: Mon, 9 Jan 2023 18:18:55 +0100 Subject: [PATCH] gui: display amount with sats in bold --- gui/src/app/view/coins.rs | 30 +++++------- gui/src/app/view/home.rs | 81 +++++++++++++++++--------------- gui/src/app/view/mod.rs | 1 + gui/src/app/view/spend/detail.rs | 28 ++++------- gui/src/app/view/spend/mod.rs | 6 +-- gui/src/app/view/spend/step.rs | 8 +--- gui/src/app/view/util.rs | 60 +++++++++++++++++++++++ gui/src/ui/component/text.rs | 4 +- 8 files changed, 131 insertions(+), 87 deletions(-) create mode 100644 gui/src/app/view/util.rs diff --git a/gui/src/app/view/coins.rs b/gui/src/app/view/coins.rs index 5d65ca87..a0031298 100644 --- a/gui/src/app/view/coins.rs +++ b/gui/src/app/view/coins.rs @@ -3,16 +3,18 @@ use iced::{ Alignment, Element, Length, }; -use crate::ui::{ - color, - component::{badge, button, card, separation, text::*}, - icon, - util::Collection, -}; - use crate::{ - app::{cache::Cache, view::message::Message}, + app::{ + cache::Cache, + view::{message::Message, util::*}, + }, daemon::model::{remaining_sequence, Coin}, + ui::{ + color, + component::{badge, button, card, separation, text::*}, + icon, + util::Collection, + }, }; pub fn coins_view<'a>( @@ -126,17 +128,7 @@ fn coin_list_view( .align_items(Alignment::Center) .width(Length::Fill), ) - .push( - Row::new() - .spacing(5) - .push( - text(format!("{:.8}", coin.amount.to_btc())) - .bold() - .width(Length::Shrink), - ) - .push(text("BTC")) - .align_items(Alignment::Center), - ) + .push(amount(&coin.amount)) .align_items(Alignment::Center) .spacing(20), ) diff --git a/gui/src/app/view/home.rs b/gui/src/app/view/home.rs index 3fb124ac..855ac40c 100644 --- a/gui/src/app/view/home.rs +++ b/gui/src/app/view/home.rs @@ -15,7 +15,10 @@ use crate::ui::{ use liana::miniscript::bitcoin; use crate::{ - app::{cache::Cache, view::message::Message}, + app::{ + cache::Cache, + view::{message::Message, util::*}, + }, daemon::model::HistoryTransaction, }; @@ -30,16 +33,23 @@ pub fn home_view<'a>( ) -> Element<'a, Message> { Column::new() .push(Column::new().padding(40)) - .push(text(format!("{} BTC", balance.to_btc())).bold().size(50)) + .push(amount_with_size(balance, 50)) .push_maybe(recovery_warning.map(|(a, c)| { Row::new() .spacing(15) .align_items(Alignment::Center) .push(icon::hourglass_icon().size(30).style(color::WARNING)) - .push(Container::new(text(format!( - "Recovery path will be soon available for {} coins ( {} )", - c, a - )))) + .push( + Row::new() + .spacing(5) + .push(text(format!( + "Recovery path will be soon available for {} coins", + c + ))) + .push(text("(")) + .push(amount(a)) + .push(text(")")), + ) .padding(10) })) .push_maybe(recovery_alert.map(|(a, c)| { @@ -47,10 +57,14 @@ pub fn home_view<'a>( .spacing(15) .align_items(Alignment::Center) .push(icon::hourglass_done_icon().style(color::ALERT)) - .push(Container::new(text(format!( - "Recovery path is available for {} coins ( {} )", - c, a - )))) + .push( + Row::new() + .spacing(5) + .push(text(format!("Recovery path is available for {} coins", c))) + .push(text("(")) + .push(amount(a)) + .push(text(")")), + ) .padding(10) })) .push( @@ -124,23 +138,19 @@ fn event_list_view<'a>(i: usize, event: &HistoryTransaction) -> Element<'a, Mess .align_items(Alignment::Center) .width(Length::Fill), ) - .push( + .push(if event.is_external() { Row::new() - .push( - text({ - if event.is_external() { - format!("+ {:.8}", event.incoming_amount.to_btc()) - } else { - format!("- {:.8}", event.outgoing_amount.to_btc()) - } - }) - .bold() - .width(Length::Shrink), - ) - .push(text("BTC")) .spacing(5) - .align_items(Alignment::Center), - ) + .push(text("+")) + .push(amount(&event.incoming_amount)) + .align_items(Alignment::Center) + } else { + Row::new() + .spacing(5) + .push(text("-")) + .push(amount(&event.outgoing_amount)) + .align_items(Alignment::Center) + }) .align_items(Alignment::Center) .spacing(20), ) @@ -164,22 +174,15 @@ pub fn event_view<'a>(cache: &Cache, event: &'a HistoryTransaction) -> Element<' .spacing(10) .align_items(Alignment::Center), ) - .push( - text({ - if event.is_external() { - format!("+ {} BTC", event.incoming_amount.to_btc()) - } else { - format!("- {} BTC", event.outgoing_amount.to_btc()) - } - }) - .bold() - .size(50) - .width(Length::Shrink), - ) + .push(if event.is_external() { + amount_with_size(&event.incoming_amount, 50) + } else { + amount_with_size(&event.outgoing_amount, 50) + }) .push_maybe( event .fee_amount - .map(|fee| Container::new(text(format!("Miner Fee: {} BTC", fee.to_btc())))), + .map(|fee| Row::new().push(text("Miner Fee: ")).push(amount(&fee))), ) .push(card::simple( Column::new() @@ -226,6 +229,6 @@ pub fn event_view<'a>(cache: &Cache, event: &'a HistoryTransaction) -> Element<' )) .align_items(Alignment::Center) .spacing(20) - .max_width(750) + .max_width(800) .into() } diff --git a/gui/src/app/view/mod.rs b/gui/src/app/view/mod.rs index 627faa5c..7baf0cec 100644 --- a/gui/src/app/view/mod.rs +++ b/gui/src/app/view/mod.rs @@ -1,4 +1,5 @@ mod message; +mod util; mod warning; pub mod coins; diff --git a/gui/src/app/view/spend/detail.rs b/gui/src/app/view/spend/detail.rs index 7457dc5c..643392d2 100644 --- a/gui/src/app/view/spend/detail.rs +++ b/gui/src/app/view/spend/detail.rs @@ -8,7 +8,7 @@ use liana::miniscript::bitcoin::{util::bip32::Fingerprint, Address, Amount, Netw use crate::{ app::{ error::Error, - view::{hw::hw_list_view, message::*, warning::warn}, + view::{hw::hw_list_view, message::*, util::*, warning::warn}, }, daemon::model::{Coin, SpendStatus, SpendTx}, hw::HardwareWallet, @@ -168,7 +168,7 @@ pub fn spend_modal<'a, T: Into>>( ) .push( Container::new(Scrollable::new( - Container::new(Container::new(content).max_width(750)) + Container::new(Container::new(content).max_width(800)) .width(Length::Fill) .center_x(), )) @@ -207,15 +207,12 @@ fn spend_header<'a>(tx: &SpendTx) -> Element<'a, Message> { .push( Column::new() .align_items(Alignment::Center) + .push(amount_with_size(&tx.spend_amount, 50)) .push( - text(format!("- {} BTC", tx.spend_amount.to_btc())) - .bold() - .size(50), - ) - .push(Container::new(text(format!( - "Miner Fee: {} BTC", - tx.fee_amount.to_btc() - )))), + Row::new() + .push(text("Miner fee: ")) + .push(amount(&tx.fee_amount)), + ), ) .into() } @@ -384,10 +381,7 @@ pub fn inputs_and_outputs_view<'a>( ), ), ) - .push( - text(format!("{} BTC", coin.amount.to_btc())) - .bold(), - ), + .push(amount(&coin.amount)), ) }) .into() @@ -468,11 +462,7 @@ pub fn inputs_and_outputs_view<'a>( ), ) .push( - text(format!( - "{} BTC", - Amount::from_sat(output.value).to_btc() - )) - .bold(), + amount(&Amount::from_sat(output.value)) ), ) .push_maybe( diff --git a/gui/src/app/view/spend/mod.rs b/gui/src/app/view/spend/mod.rs index 1c107f31..1c9c9e6e 100644 --- a/gui/src/app/view/spend/mod.rs +++ b/gui/src/app/view/spend/mod.rs @@ -7,7 +7,7 @@ use iced::{ }; use crate::{ - app::{error::Error, menu::Menu}, + app::{error::Error, menu::Menu, view::util::*}, daemon::model::{SpendStatus, SpendTx}, ui::{ color, @@ -130,8 +130,8 @@ fn spend_tx_list_view<'a>(i: usize, tx: &SpendTx) -> Element<'a, Message> { ) .push( Column::new() - .push(text(format!("{} BTC", tx.spend_amount.to_btc())).bold()) - .push(text(format!("fee: {}", tx.fee_amount.to_btc())).small()) + .push(amount(&tx.spend_amount)) + .push(text(format!("fee: {:8}", tx.fee_amount.to_btc())).small()) .width(Length::Shrink), ) .align_items(Alignment::Center) diff --git a/gui/src/app/view/spend/step.rs b/gui/src/app/view/spend/step.rs index ffc0b81c..439a8aa0 100644 --- a/gui/src/app/view/spend/step.rs +++ b/gui/src/app/view/spend/step.rs @@ -9,7 +9,7 @@ use crate::{ app::{ cache::Cache, error::Error, - view::{message::*, modal}, + view::{message::*, modal, util::amount}, }, daemon::model::{remaining_sequence, Coin}, ui::{ @@ -256,11 +256,7 @@ fn coin_list_view<'a>( .align_items(Alignment::Center) .width(Length::Fill), ) - .push( - text(format!("{} BTC", coin.amount.to_btc())) - .bold() - .width(Length::Shrink), - ) + .push(amount(&coin.amount)) .align_items(Alignment::Center) .spacing(20), ) diff --git a/gui/src/app/view/util.rs b/gui/src/app/view/util.rs new file mode 100644 index 00000000..7f2c9960 --- /dev/null +++ b/gui/src/app/view/util.rs @@ -0,0 +1,60 @@ +use iced::{widget::Row, Element}; +use liana::miniscript::bitcoin::Amount; + +use crate::ui::{color, component::text::*, util::Collection}; + +pub fn amount<'a, T: 'a>(a: &Amount) -> impl Into> { + amount_with_size(a, TEXT_REGULAR_SIZE) +} + +pub fn amount_with_size<'a, T: 'a>(a: &Amount, size: u16) -> impl Into> { + let spacing = if size > TEXT_REGULAR_SIZE { 10 } else { 5 }; + let sats = format!("{:.8}", a.to_btc()); + assert!(sats.len() >= 9); + let row = Row::new() + .spacing(spacing) + .push(split_digits(sats[0..sats.len() - 6].to_string(), size).into()) + .push(if a.to_sat() < 1_000_000 { + split_digits(sats[sats.len() - 6..sats.len() - 3].to_string(), size).into() + } else { + Row::new() + .push( + text(sats[sats.len() - 6..sats.len() - 3].to_string()) + .bold() + .size(size), + ) + .into() + }) + .push(if a.to_sat() < 1000 { + split_digits(sats[sats.len() - 3..sats.len()].to_string(), size).into() + } else { + Row::new() + .push( + text(sats[sats.len() - 3..sats.len()].to_string()) + .bold() + .size(size), + ) + .into() + }); + + Row::with_children(vec![row.into(), text("BTC").size(size).into()]) + .spacing(spacing) + .align_items(iced::Alignment::Center) +} + +fn split_digits<'a, T: 'a>(mut s: String, size: u16) -> impl Into> { + let prefixes = vec!["0.00", "0.0", "0.", "000", "00", "0"]; + for prefix in prefixes { + if s.starts_with(prefix) { + let right = s.split_off(prefix.len()); + return Row::new() + .push(text(s).size(size).style(color::DARK_GREY)) + .push_maybe(if right.is_empty() { + None + } else { + Some(text(right).bold().size(size)) + }); + } + } + Row::new().push(text(s).bold().size(size)) +} diff --git a/gui/src/ui/component/text.rs b/gui/src/ui/component/text.rs index 17b06570..6cc79a94 100644 --- a/gui/src/ui/component/text.rs +++ b/gui/src/ui/component/text.rs @@ -1,10 +1,12 @@ use crate::ui::font; use std::borrow::Cow; +pub const TEXT_REGULAR_SIZE: u16 = 25; + pub fn text<'a>(content: impl Into>) -> iced::widget::Text<'a> { iced::widget::Text::new(content) .font(font::REGULAR) - .size(25) + .size(TEXT_REGULAR_SIZE) } pub trait Text {