diff --git a/gui/Cargo.lock b/gui/Cargo.lock index cfdc1be0..a59766a9 100644 --- a/gui/Cargo.lock +++ b/gui/Cargo.lock @@ -1887,6 +1887,8 @@ dependencies = [ name = "liana_ui" version = "0.1.0" dependencies = [ + "bitcoin", + "chrono", "iced", "iced_lazy", "iced_native", diff --git a/gui/src/app/view/coins.rs b/gui/src/app/view/coins.rs index 83bfe0c6..4e0ccf55 100644 --- a/gui/src/app/view/coins.rs +++ b/gui/src/app/view/coins.rs @@ -2,17 +2,14 @@ use iced::{Alignment, Length}; use liana_ui::{ color, - component::{badge, separation, text::*}, + component::{amount::*, badge, separation, text::*}, icon, theme, util::Collection, widget::*, }; use crate::{ - app::{ - cache::Cache, - view::{message::Message, util::*}, - }, + app::{cache::Cache, view::message::Message}, daemon::model::{remaining_sequence, Coin}, }; diff --git a/gui/src/app/view/home.rs b/gui/src/app/view/home.rs index 438e5966..c8bad9f3 100644 --- a/gui/src/app/view/home.rs +++ b/gui/src/app/view/home.rs @@ -5,16 +5,13 @@ use iced::{alignment, Alignment, Length}; use liana::miniscript::bitcoin; use liana_ui::{ color, - component::{badge, text::*}, + component::{amount::*, badge, text::*}, icon, theme, util::Collection, widget::*, }; -use crate::{ - app::view::{message::Message, util::*}, - daemon::model::HistoryTransaction, -}; +use crate::{app::view::message::Message, daemon::model::HistoryTransaction}; pub const HISTORY_EVENT_PAGE_SIZE: u64 = 20; diff --git a/gui/src/app/view/mod.rs b/gui/src/app/view/mod.rs index f4c99cd4..4210afb7 100644 --- a/gui/src/app/view/mod.rs +++ b/gui/src/app/view/mod.rs @@ -1,5 +1,4 @@ mod message; -mod util; mod warning; pub mod coins; diff --git a/gui/src/app/view/psbts.rs b/gui/src/app/view/psbts.rs index ea97d11b..b7c6ea6c 100644 --- a/gui/src/app/view/psbts.rs +++ b/gui/src/app/view/psbts.rs @@ -2,14 +2,14 @@ use iced::{widget::Space, Alignment, Length}; use liana_ui::{ color, - component::{badge, button, card, form, text::*}, + component::{amount::*, badge, button, card, form, text::*}, icon, theme, util::Collection, widget::*, }; use crate::{ - app::{error::Error, menu::Menu, view::util::*}, + app::{error::Error, menu::Menu}, daemon::model::{SpendStatus, SpendTx}, }; diff --git a/gui/src/app/view/recovery.rs b/gui/src/app/view/recovery.rs index 3129a70b..07f24879 100644 --- a/gui/src/app/view/recovery.rs +++ b/gui/src/app/view/recovery.rs @@ -11,15 +11,12 @@ use liana::miniscript::bitcoin::{ }; use liana_ui::{ - component::{button, form, text::*}, + component::{amount::*, button, form, text::*}, icon, theme, widget::*, }; -use crate::app::view::{ - message::{CreateSpendMessage, Message}, - util::amount, -}; +use crate::app::view::message::{CreateSpendMessage, Message}; #[allow(clippy::too_many_arguments)] pub fn recovery<'a>( diff --git a/gui/src/app/view/spend/detail.rs b/gui/src/app/view/spend/detail.rs index 72e09685..08f49839 100644 --- a/gui/src/app/view/spend/detail.rs +++ b/gui/src/app/view/spend/detail.rs @@ -16,6 +16,7 @@ use liana::{ use liana_ui::{ color, component::{ + amount::*, badge, button, card, collapse::Collapse, form, hw, separation, @@ -29,7 +30,7 @@ use liana_ui::{ use crate::{ app::{ error::Error, - view::{hw::hw_list_view, message::*, util::*, warning::warn}, + view::{hw::hw_list_view, message::*, warning::warn}, }, daemon::model::{Coin, SpendStatus, SpendTx}, hw::HardwareWallet, diff --git a/gui/src/app/view/spend/step.rs b/gui/src/app/view/spend/step.rs index 50905f98..cd4288ac 100644 --- a/gui/src/app/view/spend/step.rs +++ b/gui/src/app/view/spend/step.rs @@ -5,6 +5,7 @@ use liana::miniscript::bitcoin::Amount; use liana_ui::{ color, component::{ + amount::*, badge, button, form, text::{text, Text}, }, @@ -17,7 +18,7 @@ use crate::{ app::{ cache::Cache, error::Error, - view::{message::*, modal, util::amount}, + view::{message::*, modal}, }, daemon::model::{remaining_sequence, Coin}, }; diff --git a/gui/src/app/view/transactions.rs b/gui/src/app/view/transactions.rs index adac858c..b5a110dd 100644 --- a/gui/src/app/view/transactions.rs +++ b/gui/src/app/view/transactions.rs @@ -3,17 +3,14 @@ use chrono::NaiveDateTime; use iced::{alignment, Alignment, Length}; use liana_ui::{ - component::{badge, card, text::*}, + component::{amount::*, badge, card, text::*}, icon, theme, util::Collection, widget::*, }; use crate::{ - app::{ - cache::Cache, - view::{message::Message, util::*}, - }, + app::{cache::Cache, view::message::Message}, daemon::model::HistoryTransaction, }; diff --git a/gui/src/daemon/model.rs b/gui/src/daemon/model.rs index a0b5e174..2737a4b0 100644 --- a/gui/src/daemon/model.rs +++ b/gui/src/daemon/model.rs @@ -180,4 +180,8 @@ impl HistoryTransaction { pub fn is_external(&self) -> bool { self.coins.is_empty() } + + pub fn is_self_send(&self) -> bool { + !self.coins.is_empty() && self.outgoing_amount == Amount::from_sat(0) + } } diff --git a/gui/ui/Cargo.toml b/gui/ui/Cargo.toml index 227e7220..cf064395 100644 --- a/gui/ui/Cargo.toml +++ b/gui/ui/Cargo.toml @@ -9,3 +9,5 @@ edition = "2021" iced = { version = "0.7", features = ["svg", "image"] } iced_native = "0.8" iced_lazy = { version = "0.4"} +bitcoin = "0.29" +chrono = "0.4" diff --git a/gui/ui/examples/design-system/Cargo.toml b/gui/ui/examples/design-system/Cargo.toml index 7ea4e589..fc397025 100644 --- a/gui/ui/examples/design-system/Cargo.toml +++ b/gui/ui/examples/design-system/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" iced = "0.7" iced_native = "0.8" web-sys = "0.3.61" +chrono = "0.4" liana_ui = { path = "../.." } [workspace] diff --git a/gui/ui/examples/design-system/src/main.rs b/gui/ui/examples/design-system/src/main.rs index f30d19ec..27b9d10a 100644 --- a/gui/ui/examples/design-system/src/main.rs +++ b/gui/ui/examples/design-system/src/main.rs @@ -45,6 +45,7 @@ impl Application for DesignSystem { Box::new(section::Typography {}), Box::new(section::Buttons {}), Box::new(section::HardwareWallets {}), + Box::new(section::Events {}), ], current: 0, }; @@ -123,12 +124,14 @@ impl Application for DesignSystem { .height(Length::Fill); container(row![ - sidebar.width(Length::Units(200)), - Space::with_width(Length::Units(150)), - scrollable(column![ + sidebar.width(Length::FillPortion(2)), + Space::with_width(Length::FillPortion(1)), + container(scrollable(column![ Space::with_height(Length::Units(150)), container(self.sections[self.current].view()).width(Length::Fill) - ]), + ])) + .width(Length::FillPortion(8)), + Space::with_width(Length::FillPortion(1)), ]) .width(Length::Fill) .height(Length::Fill) diff --git a/gui/ui/examples/design-system/src/section.rs b/gui/ui/examples/design-system/src/section.rs index 00c1a247..fee21969 100644 --- a/gui/ui/examples/design-system/src/section.rs +++ b/gui/ui/examples/design-system/src/section.rs @@ -5,7 +5,7 @@ use iced::{ }; use liana_ui::{ color, - component::{hw, separation, text::*}, + component::{amount::Amount, event, hw, separation, text::*}, theme, widget::Element, }; @@ -253,3 +253,33 @@ impl Section for HardwareWallets { .into() } } + +pub struct Events {} + +impl Section for Events { + fn title(&self) -> &'static str { + "Events " + } + fn view(&self) -> Element { + column![ + h1(self.title()), + column![ + event::unconfirmed_outgoing_event(&Amount::from_sat(32934234), Message::Ignore), + event::confirmed_outgoing_event( + chrono::NaiveDate::from_ymd_opt(2023, 04, 19).unwrap(), + &Amount::from_sat(32934234), + Message::Ignore + ), + event::unconfirmed_incoming_event(&Amount::from_sat(32934234), Message::Ignore), + event::confirmed_incoming_event( + chrono::NaiveDate::from_ymd_opt(2023, 04, 19).unwrap(), + &Amount::from_sat(32934234), + Message::Ignore + ) + ] + .spacing(20) + ] + .spacing(100) + .into() + } +} diff --git a/gui/src/app/view/util.rs b/gui/ui/src/component/amount.rs similarity index 87% rename from gui/src/app/view/util.rs rename to gui/ui/src/component/amount.rs index b9b997d6..824abd93 100644 --- a/gui/src/app/view/util.rs +++ b/gui/ui/src/component/amount.rs @@ -1,12 +1,12 @@ -use liana::miniscript::bitcoin::Amount; +pub use bitcoin::Amount; -use liana_ui::{color, component::text::*, util::Collection, widget::*}; +use crate::{color, component::text::*, util::Collection, widget::*}; -pub fn amount<'a, T: 'a>(a: &Amount) -> impl Into> { +pub fn amount<'a, T: 'a>(a: &Amount) -> Row<'a, T> { amount_with_size(a, P1_SIZE) } -pub fn amount_with_size<'a, T: 'a>(a: &Amount, size: u16) -> impl Into> { +pub fn amount_with_size<'a, T: 'a>(a: &Amount, size: u16) -> Row<'a, T> { let spacing = if size > P1_SIZE { 10 } else { 5 }; let sats = format!("{:.8}", a.to_btc()); assert!(sats.len() >= 9); diff --git a/gui/ui/src/component/event.rs b/gui/ui/src/component/event.rs new file mode 100644 index 00000000..80644877 --- /dev/null +++ b/gui/ui/src/component/event.rs @@ -0,0 +1,106 @@ +use crate::{ + component::{amount, badge, text}, + theme, + widget::*, +}; +use bitcoin::Amount; +use iced::{ + widget::{button, row}, + Alignment, Length, +}; + +pub fn unconfirmed_outgoing_event<'a, T: Clone + 'a>(amount: &Amount, msg: T) -> Container<'a, T> { + Container::new( + button( + row!( + row!(badge::spend(), badge::unconfirmed()) + .spacing(10) + .align_items(Alignment::Center) + .width(Length::Fill), + row!(text::p1_regular("-"), amount::amount(amount)) + .spacing(5) + .align_items(Alignment::Center), + ) + .align_items(Alignment::Center) + .padding(10) + .spacing(20), + ) + .on_press(msg) + .style(theme::Button::TransparentBorder), + ) + .style(theme::Container::Card(theme::Card::Simple)) +} + +pub fn confirmed_outgoing_event<'a, T: Clone + 'a>( + date: chrono::NaiveDate, + amount: &Amount, + msg: T, +) -> Container<'a, T> { + Container::new( + button( + row!( + row!(badge::spend(), text::p2_regular(date.to_string())) + .spacing(10) + .align_items(Alignment::Center) + .width(Length::Fill), + row!(text::p1_regular("-"), amount::amount(amount)) + .spacing(5) + .align_items(Alignment::Center), + ) + .align_items(Alignment::Center) + .padding(10) + .spacing(20), + ) + .on_press(msg) + .style(theme::Button::TransparentBorder), + ) + .style(theme::Container::Card(theme::Card::Simple)) +} + +pub fn unconfirmed_incoming_event<'a, T: Clone + 'a>(amount: &Amount, msg: T) -> Container<'a, T> { + Container::new( + button( + row!( + row!(badge::receive(), badge::unconfirmed()) + .spacing(10) + .align_items(Alignment::Center) + .width(Length::Fill), + row!(text::p1_regular("+"), amount::amount(amount)) + .spacing(5) + .align_items(Alignment::Center), + ) + .align_items(Alignment::Center) + .padding(10) + .spacing(20), + ) + .on_press(msg) + .style(theme::Button::TransparentBorder), + ) + .style(theme::Container::Card(theme::Card::Simple)) +} + +pub fn confirmed_incoming_event<'a, T: Clone + 'a>( + date: chrono::NaiveDate, + amount: &Amount, + msg: T, +) -> Container<'a, T> { + Container::new( + button( + row!( + row!(badge::receive(), text::p2_regular(date.to_string())) + .spacing(10) + .align_items(Alignment::Center) + .width(Length::Fill), + row!(text::p1_regular("+"), amount::amount(amount)) + .spacing(5) + .align_items(Alignment::Center), + ) + .align_items(Alignment::Center) + .padding(10) + .spacing(20), + ) + .on_press(msg) + .style(theme::Button::TransparentBorder), + ) + .style(theme::Container::Card(theme::Card::Simple)) +} diff --git a/gui/ui/src/component/mod.rs b/gui/ui/src/component/mod.rs index 7ac5ff42..c3252391 100644 --- a/gui/ui/src/component/mod.rs +++ b/gui/ui/src/component/mod.rs @@ -1,7 +1,9 @@ +pub mod amount; pub mod badge; pub mod button; pub mod card; pub mod collapse; +pub mod event; pub mod form; pub mod hw; pub mod modal;