From f5c2d0fda0f589fc41c94cdb4312eb12cbf46990 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Wed, 15 May 2024 14:45:34 -0500 Subject: [PATCH] show pending and success for sends --- src/main.rs | 79 ++++++++++++++++++++++++++-------------------- src/routes/send.rs | 45 ++++++++++++++------------ 2 files changed, 69 insertions(+), 55 deletions(-) diff --git a/src/main.rs b/src/main.rs index bebc17e..4b08fd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use routes::Route; use std::str::FromStr; use std::sync::Arc; -use bridge::CoreUIMsg; +use bridge::{CoreUIMsg, SendSuccessMsg}; use iced::subscription::Subscription; use iced::widget::row; use iced::Element; @@ -46,38 +46,7 @@ pub fn main() -> iced::Result { .run() } -// This is the UI state. It should only contain data that is directly rendered by the UI -// More complicated state should be in Core, and bridged to the UI in a UI-friendly format. -pub struct HarborWallet { - ui_handle: Option>, - balance: Amount, - active_route: Route, - transfer_amount_str: String, - send_status: SendStatus, - send_failure_reason: Option, - send_dest_input_str: String, - send_amount_input_str: String, - password_input_str: String, - unlock_status: UnlockStatus, - unlock_failure_reason: Option, - receive_failure_reason: Option, - receive_status: ReceiveStatus, - receive_amount_str: String, - receive_invoice: Option, - receive_address: Option
, - receive_qr_data: Option, - mint_invite_code_str: String, - add_federation_failure_reason: Option, - donate_amount_str: String, -} - -impl Default for HarborWallet { - fn default() -> Self { - Self::new() - } -} - -#[derive(Default, Debug, Clone)] +#[derive(Default, Debug, Clone, PartialEq)] enum SendStatus { #[default] Idle, @@ -110,6 +79,7 @@ pub enum Message { ReceiveAmountChanged(String), SendDestInputChanged(String), SendAmountInputChanged(String), + SendStateReset, PasswordInputChanged(String), MintInviteCodeInputChanged(String), DonateAmountChanged(String), @@ -126,6 +96,38 @@ pub enum Message { CoreMessage(CoreUIMsg), } +// This is the UI state. It should only contain data that is directly rendered by the UI +// More complicated state should be in Core, and bridged to the UI in a UI-friendly format. +pub struct HarborWallet { + ui_handle: Option>, + balance: Amount, + active_route: Route, + transfer_amount_str: String, + send_status: SendStatus, + send_failure_reason: Option, + send_success_msg: Option, + send_dest_input_str: String, + send_amount_input_str: String, + password_input_str: String, + unlock_status: UnlockStatus, + unlock_failure_reason: Option, + receive_failure_reason: Option, + receive_status: ReceiveStatus, + receive_amount_str: String, + receive_invoice: Option, + receive_address: Option
, + receive_qr_data: Option, + mint_invite_code_str: String, + add_federation_failure_reason: Option, + donate_amount_str: String, +} + +impl Default for HarborWallet { + fn default() -> Self { + Self::new() + } +} + impl HarborWallet { fn new() -> Self { Self { @@ -138,6 +140,7 @@ impl HarborWallet { send_amount_input_str: String::new(), send_status: SendStatus::Idle, send_failure_reason: None, + send_success_msg: None, unlock_status: UnlockStatus::Locked, unlock_failure_reason: None, password_input_str: String::new(), @@ -258,6 +261,14 @@ impl HarborWallet { self.donate_amount_str = input; Command::none() } + Message::SendStateReset => { + self.send_failure_reason = None; + self.send_success_msg = None; + self.send_dest_input_str = String::new(); + self.send_amount_input_str = String::new(); + self.send_status = SendStatus::Idle; + Command::none() + } // Async commands we fire from the UI to core Message::Noop => Command::none(), Message::Send(invoice_str) => match self.send_status { @@ -357,7 +368,7 @@ impl HarborWallet { } CoreUIMsg::SendSuccess(params) => { info!("Send success: {params:?}"); - self.send_status = SendStatus::Idle; + self.send_success_msg = Some(params); Command::none() } CoreUIMsg::SendFailure(reason) => { diff --git a/src/routes/send.rs b/src/routes/send.rs index 1ce40ce..f7b97b4 100644 --- a/src/routes/send.rs +++ b/src/routes/send.rs @@ -1,22 +1,12 @@ -use iced::widget::text::Style; use iced::widget::{column, container, scrollable, text}; use iced::{Color, Length}; -use iced::{Element, Padding, Theme}; +use iced::{Element, Padding}; -use crate::components::{h_button, h_input, lighten, SvgIcon}; -use crate::{HarborWallet, Message}; +use crate::components::{h_button, h_header, h_input, SvgIcon}; +use crate::{HarborWallet, Message, SendStatus}; pub fn send(harbor: &HarborWallet) -> Element { - let header = column![ - text("Send").size(32), - text("Send to an on-chain address or lighting invoice.") - .size(18) - .style(|theme: &Theme| { - let gray = lighten(theme.palette().background, 0.5); - Style { color: Some(gray) } - }) - ] - .spacing(8); + let header = h_header("Send", "Send to an on-chain address or lightning invoice."); let amount_input = h_input( "Amount", @@ -40,20 +30,33 @@ pub fn send(harbor: &HarborWallet) -> Element { None, ); - let send_button = h_button("Send", SvgIcon::UpRight, false) - .on_press(Message::Send(harbor.send_dest_input_str.clone())); - - let body = column![header, amount_input, dest_input, send_button].spacing(48); + let send_button = h_button( + "Send", + SvgIcon::UpRight, + harbor.send_status == SendStatus::Sending, + ) + .on_press(Message::Send(harbor.send_dest_input_str.clone())); let failure_message = harbor .send_failure_reason .as_ref() - .map(|r| text(r).size(50).color(Color::from_rgb(255., 0., 0.))); + .map(|r| text(r).size(32).color(Color::from_rgb(255., 0., 0.))); + + let success_message = harbor.send_success_msg.as_ref().map(|r| { + text(format!("Success: {r:?}")) + .size(32) + .color(Color::from_rgb(0., 255., 0.)) + }); let column = if let Some(failure_message) = failure_message { - column![body, failure_message] + let dangit_button = + h_button("Dangit", SvgIcon::Squirrel, false).on_press(Message::SendStateReset); + column![header, failure_message, dangit_button] + } else if let Some(success_message) = success_message { + let nice_button = h_button("Nice", SvgIcon::Heart, false).on_press(Message::SendStateReset); + column![header, success_message, nice_button] } else { - column![body] + column![header, amount_input, dest_input, send_button] }; container(scrollable(