Skip to content

Commit

Permalink
show receive generating / success states
Browse files Browse the repository at this point in the history
  • Loading branch information
futurepaul committed May 15, 2024
1 parent a97c61f commit c9fa5e0
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 69 deletions.
62 changes: 18 additions & 44 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use bitcoin::Address;
use core::run_core;
use fedimint_core::api::InviteCode;
use fedimint_core::Amount;
use fedimint_ln_common::lightning_invoice::Bolt11Invoice;
use iced::widget::qr_code::Data;
use routes::Route;
use std::str::FromStr;
use std::sync::Arc;

use bridge::{CoreUIMsg, SendSuccessMsg};
use bridge::{CoreUIMsg, ReceiveSuccessMsg, SendSuccessMsg};
use iced::subscription::Subscription;
use iced::widget::row;
use iced::Element;
Expand Down Expand Up @@ -53,7 +52,7 @@ enum SendStatus {
Sending,
}

#[derive(Default, Debug, Clone)]
#[derive(Default, Debug, Clone, PartialEq)]
enum ReceiveStatus {
#[default]
Idle,
Expand All @@ -75,8 +74,8 @@ pub enum Message {
UIHandlerLoaded(Arc<bridge::UIHandle>),
// Local state changes
Navigate(Route),
TransferAmountChanged(String),
ReceiveAmountChanged(String),
ReceiveStateReset,
SendDestInputChanged(String),
SendAmountInputChanged(String),
SendStateReset,
Expand All @@ -98,11 +97,11 @@ pub enum Message {

// 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.
#[derive(Default, Debug)]
pub struct HarborWallet {
ui_handle: Option<Arc<bridge::UIHandle>>,
balance: Amount,
balance_sats: u64,
active_route: Route,
transfer_amount_str: String,
send_status: SendStatus,
send_failure_reason: Option<String>,
send_success_msg: Option<SendSuccessMsg>,
Expand All @@ -112,6 +111,7 @@ pub struct HarborWallet {
unlock_status: UnlockStatus,
unlock_failure_reason: Option<String>,
receive_failure_reason: Option<String>,
receive_success_msg: Option<ReceiveSuccessMsg>,
receive_status: ReceiveStatus,
receive_amount_str: String,
receive_invoice: Option<Bolt11Invoice>,
Expand All @@ -122,39 +122,7 @@ pub struct HarborWallet {
donate_amount_str: String,
}

impl Default for HarborWallet {
fn default() -> Self {
Self::new()
}
}

impl HarborWallet {
fn new() -> Self {
Self {
ui_handle: None,
balance: Amount::ZERO,
active_route: Route::Unlock,
transfer_amount_str: String::new(),
receive_amount_str: String::new(),
send_dest_input_str: String::new(),
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(),
receive_failure_reason: None,
receive_status: ReceiveStatus::Idle,
receive_invoice: None,
receive_address: None,
receive_qr_data: None,
mint_invite_code_str: String::new(),
add_federation_failure_reason: None,
donate_amount_str: String::new(),
}
}

fn subscription(&self) -> Subscription<Message> {
run_core()
}
Expand Down Expand Up @@ -233,10 +201,6 @@ impl HarborWallet {
self.active_route = route;
Command::none()
}
Message::TransferAmountChanged(amount) => {
self.transfer_amount_str = amount;
Command::none()
}
Message::ReceiveAmountChanged(amount) => {
self.receive_amount_str = amount;
Command::none()
Expand Down Expand Up @@ -269,6 +233,16 @@ impl HarborWallet {
self.send_status = SendStatus::Idle;
Command::none()
}
Message::ReceiveStateReset => {
self.receive_failure_reason = None;
self.receive_amount_str = String::new();
self.receive_invoice = None;
self.receive_success_msg = None;
self.receive_address = None;
self.receive_qr_data = None;
self.receive_status = ReceiveStatus::Idle;
Command::none()
}
// Async commands we fire from the UI to core
Message::Noop => Command::none(),
Message::Send(invoice_str) => match self.send_status {
Expand Down Expand Up @@ -378,7 +352,7 @@ impl HarborWallet {
}
CoreUIMsg::ReceiveSuccess(params) => {
info!("Receive success: {params:?}");
self.receive_status = ReceiveStatus::Idle;
self.receive_success_msg = Some(params);
Command::none()
}
CoreUIMsg::ReceiveFailed(reason) => {
Expand All @@ -387,7 +361,7 @@ impl HarborWallet {
Command::none()
}
CoreUIMsg::BalanceUpdated(balance) => {
self.balance = balance;
self.balance_sats = balance.sats_round_down();
Command::none()
}
CoreUIMsg::ReceiveGenerating => {
Expand Down
2 changes: 1 addition & 1 deletion src/routes/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{HarborWallet, Message};
use super::Route;

pub fn home(harbor: &HarborWallet) -> Element<Message> {
let balance = text(format!("{} sats", harbor.balance.sats_round_down())).size(64);
let balance = text(format!("{} sats", harbor.balance_sats)).size(64);
let send_button =
h_button("Send", SvgIcon::UpRight, false).on_press(Message::Navigate(Route::Send));
let receive_button =
Expand Down
40 changes: 33 additions & 7 deletions src/routes/receive.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use iced::widget::container::Style;
use iced::widget::{column, container, qr_code, scrollable, text};
use iced::{Border, Element, Padding};
use iced::{Border, Element, Font, Padding};
use iced::{Color, Length};

use crate::components::{h_button, h_header, h_input, SvgIcon};
use crate::{HarborWallet, Message};
use crate::{HarborWallet, Message, ReceiveStatus};

pub fn receive(harbor: &HarborWallet) -> Element<Message> {
let receive_string = harbor
Expand All @@ -13,9 +13,26 @@ pub fn receive(harbor: &HarborWallet) -> Element<Message> {
.map(|i| i.to_string())
.or_else(|| harbor.receive_address.as_ref().map(|a| a.to_string()));

let column = if let Some(string) = receive_string {
let success_message = harbor.receive_success_msg.as_ref().map(|r| {
text(format!("Success: {r:?}"))
.size(32)
.color(Color::from_rgb(0., 255., 0.))
});

let column = if let Some(success_message) = success_message {
let header = h_header("Success!", "You did a good job!");
let reset_button =
h_button("Start over", SvgIcon::Squirrel, false).on_press(Message::ReceiveStateReset);
column![header, success_message, reset_button]
} else if let Some(string) = receive_string {
let header = h_header("Receive", "Scan this QR or copy the string.");

let string = if harbor.receive_invoice.is_some() {
format!("lightning:{string}")
} else {
format!("bitcoin:{string}")
};

let data = harbor.receive_qr_data.as_ref().unwrap();
let qr_code = qr_code(data).style(|_theme| iced::widget::qr_code::Style {
background: Color::WHITE,
Expand All @@ -30,14 +47,20 @@ pub fn receive(harbor: &HarborWallet) -> Element<Message> {
..Style::default()
});

let first_ten_chars = string.chars().take(10).collect::<String>();
let first_20_chars = string.chars().take(20).collect::<String>();

column![
header,
qr_container,
text(format!("{first_ten_chars}...")).size(16),
text(format!("{first_20_chars}...")).size(16).font(Font {
family: iced::font::Family::Monospace,
weight: iced::font::Weight::Normal,
stretch: iced::font::Stretch::Normal,
style: iced::font::Style::Normal,
}),
h_button("Copy to clipboard", SvgIcon::Copy, false)
.on_press(Message::CopyToClipboard(string)),
h_button("Start over", SvgIcon::Squirrel, false).on_press(Message::ReceiveStateReset),
]
} else {
let header = h_header("Receive", "Receive on-chain or via lightning.");
Expand All @@ -53,10 +76,13 @@ pub fn receive(harbor: &HarborWallet) -> Element<Message> {
Some("sats"),
);

let generate_button = h_button("Generate Invoice", SvgIcon::DownLeft, false)
// TODO how to separate lighting and onchain?
let generating = harbor.receive_status == ReceiveStatus::Generating;

let generate_button = h_button("Generate Invoice", SvgIcon::DownLeft, generating)
.on_press(Message::GenerateInvoice);

let generate_address_button = h_button("Generate Address", SvgIcon::Squirrel, false)
let generate_address_button = h_button("Generate Address", SvgIcon::Squirrel, generating)
.on_press(Message::GenerateAddress);

column![
Expand Down
29 changes: 12 additions & 17 deletions src/routes/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
use iced::widget::{column, container, scrollable, text_input};
use iced::Length;
use iced::{Alignment, Element};
use iced::widget::{column, container, scrollable};
use iced::Element;
use iced::{Length, Padding};

use crate::components::h_header;
use crate::{HarborWallet, Message};

pub fn transfer(harbor: &HarborWallet) -> Element<Message> {
container(
scrollable(
column![
"Let's transfer some ecash!",
text_input("how much?", &harbor.transfer_amount_str)
.on_input(Message::TransferAmountChanged,)
]
.spacing(32)
.align_items(Alignment::Center)
.width(Length::Fill),
)
.height(Length::Fill),
)
pub fn transfer(_harbor: &HarborWallet) -> Element<Message> {
container(scrollable(
column![h_header("Transfer", "Coming soon!")]
.spacing(48)
.width(Length::Fill)
.max_width(512)
.padding(Padding::new(48.)),
))
.into()
}

0 comments on commit c9fa5e0

Please sign in to comment.