Add receive panel

This commit is contained in:
edouard 2022-09-01 16:48:07 +02:00
parent 1026d2b487
commit 928294b32e
7 changed files with 113 additions and 7 deletions

View File

@ -1,5 +1,6 @@
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Menu { pub enum Menu {
Home, Home,
Receive,
Settings, Settings,
} }

View File

@ -10,4 +10,5 @@ pub enum Message {
LoadDaemonConfig(Box<DaemonConfig>), LoadDaemonConfig(Box<DaemonConfig>),
DaemonConfigLoaded(Result<(), Error>), DaemonConfigLoaded(Result<(), Error>),
BlockHeight(Result<i32, Error>), BlockHeight(Result<i32, Error>),
ReceiveAddress(Result<bitcoin::Address, Error>),
} }

View File

@ -21,7 +21,7 @@ pub use minisafe::config::Config as DaemonConfig;
pub use config::Config; pub use config::Config;
pub use message::Message; pub use message::Message;
use state::{Home, State}; use state::{Home, ReceivePanel, State};
use crate::{ use crate::{
app::{cache::Cache, error::Error, menu::Menu}, app::{cache::Cache, error::Error, menu::Menu},
@ -63,6 +63,7 @@ impl App {
.into() .into()
} }
menu::Menu::Home => Home {}.into(), menu::Menu::Home => Home {}.into(),
menu::Menu::Receive => ReceivePanel::default().into(),
}; };
self.state.load(self.daemon.clone()) self.state.load(self.daemon.clone())
} }

View File

@ -3,9 +3,9 @@ mod settings;
use std::sync::Arc; use std::sync::Arc;
use iced::pure::{column, Element}; use iced::pure::{column, Element};
use iced::{Command, Subscription}; use iced::{widget::qr_code, Command, Subscription};
use super::{cache::Cache, menu::Menu, message::Message, view}; use super::{cache::Cache, error::Error, menu::Menu, message::Message, view};
pub use settings::SettingsState; pub use settings::SettingsState;
@ -15,7 +15,7 @@ pub trait State {
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message>; fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message>;
fn update( fn update(
&mut self, &mut self,
daemon: Arc<dyn Daemon + Send + Sync>, daemon: Arc<dyn Daemon + Sync + Send>,
cache: &Cache, cache: &Cache,
message: Message, message: Message,
) -> Command<Message>; ) -> Command<Message>;
@ -35,7 +35,7 @@ impl State for Home {
} }
fn update( fn update(
&mut self, &mut self,
_daemon: Arc<dyn Daemon + Send + Sync>, _daemon: Arc<dyn Daemon + Sync + Send>,
_cache: &Cache, _cache: &Cache,
_message: Message, _message: Message,
) -> Command<Message> { ) -> Command<Message> {
@ -48,3 +48,61 @@ impl From<Home> for Box<dyn State> {
Box::new(s) Box::new(s)
} }
} }
#[derive(Default)]
pub struct ReceivePanel {
address: Option<bitcoin::Address>,
qr_code: Option<qr_code::State>,
warning: Option<Error>,
}
impl State for ReceivePanel {
fn view<'a>(&'a self, _cache: &'a Cache) -> Element<'a, view::Message> {
if let Some(address) = &self.address {
view::dashboard(
&Menu::Receive,
self.warning.as_ref(),
view::receive::receive(address, self.qr_code.as_ref().unwrap()),
)
} else {
view::dashboard(&Menu::Receive, self.warning.as_ref(), column())
}
}
fn update(
&mut self,
_daemon: Arc<dyn Daemon + Sync + Send>,
_cache: &Cache,
message: Message,
) -> Command<Message> {
if let Message::ReceiveAddress(res) = message {
match res {
Ok(address) => {
self.warning = None;
self.qr_code = Some(qr_code::State::new(&address.to_qr_uri()).unwrap());
self.address = Some(address);
}
Err(e) => self.warning = Some(e),
}
};
Command::none()
}
fn load(&self, daemon: Arc<dyn Daemon + Sync + Send>) -> Command<Message> {
let daemon = daemon.clone();
Command::perform(
async move {
daemon
.get_new_address()
.map(|res| res.address)
.map_err(|e| e.into())
},
Message::ReceiveAddress,
)
}
}
impl From<ReceivePanel> for Box<dyn State> {
fn from(s: ReceivePanel) -> Box<dyn State> {
Box::new(s)
}
}

View File

@ -1,6 +1,7 @@
mod message; mod message;
mod warning; mod warning;
pub mod receive;
pub mod settings; pub mod settings;
pub use message::*; pub use message::*;
@ -14,7 +15,7 @@ use iced::{
use crate::ui::{ use crate::ui::{
color, color,
component::{button, separation, text::*}, component::{button, separation, text::*},
icon::{home_icon, settings_icon}, icon::{home_icon, receive_icon, settings_icon},
}; };
use crate::app::{error::Error, menu::Menu}; use crate::app::{error::Error, menu::Menu};
@ -29,6 +30,17 @@ pub fn sidebar(menu: &Menu) -> widget::Container<Message> {
.on_press(Message::Menu(Menu::Home)) .on_press(Message::Menu(Menu::Home))
.width(iced::Length::Units(200)) .width(iced::Length::Units(200))
}; };
let receive_button = if *menu == Menu::Receive {
button::primary(Some(receive_icon()), "Receive")
.on_press(Message::Reload)
.width(iced::Length::Units(200))
} else {
button::transparent(Some(receive_icon()), "Receive")
.on_press(Message::Menu(Menu::Receive))
.width(iced::Length::Units(200))
};
let settings_button = if *menu == Menu::Settings { let settings_button = if *menu == Menu::Settings {
button::primary(Some(settings_icon()), "Settings") button::primary(Some(settings_icon()), "Settings")
.on_press(Message::Menu(Menu::Settings)) .on_press(Message::Menu(Menu::Settings))
@ -51,6 +63,7 @@ pub fn sidebar(menu: &Menu) -> widget::Container<Message> {
.spacing(10), .spacing(10),
) )
.push(home_button) .push(home_button)
.push(receive_button)
.spacing(20) .spacing(20)
.height(Length::Fill), .height(Length::Fill),
) )

View File

@ -0,0 +1,32 @@
use iced::{
pure::{column, row, widget::Button, Element},
widget::qr_code::{self, QRCode},
Alignment,
};
use crate::ui::{
component::{button, card, text::*},
icon,
};
use super::message::Message;
pub fn receive<'a>(address: &'a bitcoin::Address, qr: &'a qr_code::State) -> Element<'a, Message> {
card::simple(
column()
.push(QRCode::new(qr).cell_size(10))
.push(
row()
.push(text(&address.to_string()).small())
.push(
Button::new(icon::clipboard_icon())
.on_press(Message::Clipboard(address.to_string()))
.style(button::Style::TransparentBorder),
)
.align_items(Alignment::Center),
)
.align_items(Alignment::Center)
.spacing(20),
)
.into()
}

View File

@ -50,7 +50,7 @@ pub fn connected_device_icon() -> Text {
icon('\u{F350}') icon('\u{F350}')
} }
pub fn deposit_icon() -> Text { pub fn receive_icon() -> Text {
icon('\u{F123}') icon('\u{F123}')
} }