move qr code to modal

This commit is contained in:
pythcoiner 2024-02-24 07:16:27 +01:00 committed by pythcoiner
parent b22f22f0bc
commit e38c5f1232
3 changed files with 91 additions and 35 deletions

View File

@ -27,6 +27,12 @@ use crate::daemon::{
Daemon, Daemon,
}; };
pub enum Modal {
VerifyAddress(VerifyAddressModal),
ShowQrCode(ShowQrCodeModal),
None,
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Addresses { pub struct Addresses {
list: Vec<Address>, list: Vec<Address>,
@ -57,8 +63,7 @@ pub struct ReceivePanel {
wallet: Arc<Wallet>, wallet: Arc<Wallet>,
addresses: Addresses, addresses: Addresses,
labels_edited: LabelsEdited, labels_edited: LabelsEdited,
qr_code: Option<qr_code::State>, modal: Modal,
modal: Option<VerifyAddressModal>,
warning: Option<Error>, warning: Option<Error>,
} }
@ -69,8 +74,7 @@ impl ReceivePanel {
wallet, wallet,
addresses: Addresses::default(), addresses: Addresses::default(),
labels_edited: LabelsEdited::default(), labels_edited: LabelsEdited::default(),
qr_code: None, modal: Modal::None,
modal: None,
warning: None, warning: None,
} }
} }
@ -84,22 +88,24 @@ impl State for ReceivePanel {
self.warning.as_ref(), self.warning.as_ref(),
view::receive::receive( view::receive::receive(
&self.addresses.list, &self.addresses.list,
self.qr_code.as_ref(),
&self.addresses.labels, &self.addresses.labels,
self.labels_edited.cache(), self.labels_edited.cache(),
), ),
); );
if let Some(m) = &self.modal {
modal::Modal::new(content, m.view()) match &self.modal {
Modal::VerifyAddress(m) => modal::Modal::new(content, m.view())
.on_blur(Some(view::Message::Close)) .on_blur(Some(view::Message::Close))
.into() .into(),
} else { Modal::ShowQrCode(m) => modal::Modal::new(content, m.view())
content .on_blur(Some(view::Message::Close))
.into(),
Modal::None => content,
} }
} }
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
if let Some(modal) = &self.modal { if let Modal::VerifyAddress(modal) = &self.modal {
modal.subscription() modal.subscription()
} else { } else {
Subscription::none() Subscription::none()
@ -130,11 +136,6 @@ impl State for ReceivePanel {
match res { match res {
Ok((address, derivation_index)) => { Ok((address, derivation_index)) => {
self.warning = None; self.warning = None;
self.qr_code = qr_code::State::new(format!(
"bitcoin:{}?index={}",
address, derivation_index
))
.ok();
self.addresses.list.push(address); self.addresses.list.push(address);
self.addresses.derivation_indexes.push(derivation_index); self.addresses.derivation_indexes.push(derivation_index);
} }
@ -143,11 +144,11 @@ impl State for ReceivePanel {
Command::none() Command::none()
} }
Message::View(view::Message::Close) => { Message::View(view::Message::Close) => {
self.modal = None; self.modal = Modal::None;
Command::none() Command::none()
} }
Message::View(view::Message::Select(i)) => { Message::View(view::Message::Select(i)) => {
self.modal = Some(VerifyAddressModal::new( self.modal = Modal::VerifyAddress(VerifyAddressModal::new(
self.data_dir.clone(), self.data_dir.clone(),
self.wallet.clone(), self.wallet.clone(),
cache.network, cache.network,
@ -172,11 +173,21 @@ impl State for ReceivePanel {
Message::ReceiveAddress, Message::ReceiveAddress,
) )
} }
_ => self Message::View(view::Message::ShowQrCode(i)) => {
.modal if let Some(address) = self.addresses.list.get(i) {
.as_mut() if let Some(modal) = ShowQrCodeModal::new(address, i) {
.map(|m| m.update(daemon, cache, message)) self.modal = Modal::ShowQrCode(modal);
.unwrap_or_else(Command::none), }
}
Command::none()
}
_ => {
if let Modal::VerifyAddress(ref mut m) = self.modal {
m.update(daemon, cache, message)
} else {
Command::none()
}
}
} }
} }
@ -290,6 +301,26 @@ impl VerifyAddressModal {
} }
} }
pub struct ShowQrCodeModal {
qr_code: qr_code::State,
address: String,
}
impl ShowQrCodeModal {
pub fn new(address: &Address, i: usize) -> Option<Self> {
qr_code::State::new(format!("bitcoin:{}?index={}", address, i))
.ok()
.map(|qr_code| Self {
qr_code,
address: address.to_string(),
})
}
fn view(&self) -> Element<view::Message> {
view::receive::qr_modal(&self.qr_code, &self.address)
}
}
async fn verify_address( async fn verify_address(
hw: std::sync::Arc<dyn async_hwi::HWI + Send + Sync>, hw: std::sync::Arc<dyn async_hwi::HWI + Send + Sync>,
index: ChildNumber, index: ChildNumber,

View File

@ -18,6 +18,7 @@ pub enum Message {
Previous, Previous,
SelectHardwareWallet(usize), SelectHardwareWallet(usize),
CreateRbf(CreateRbfMessage), CreateRbf(CreateRbfMessage),
ShowQrCode(usize),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -3,10 +3,11 @@ use std::collections::{HashMap, HashSet};
use iced::{ use iced::{
widget::{ widget::{
qr_code::{self, QRCode}, qr_code::{self, QRCode},
scrollable, Space, scrollable,
}, },
Alignment, Length, Alignment, Length,
}; };
use iced_native::widget::Space;
use liana::miniscript::bitcoin::{ use liana::miniscript::bitcoin::{
self, self,
@ -37,7 +38,6 @@ use super::message::Message;
pub fn receive<'a>( pub fn receive<'a>(
addresses: &'a [bitcoin::Address], addresses: &'a [bitcoin::Address],
qr: Option<&'a qr_code::State>,
labels: &'a HashMap<String, String>, labels: &'a HashMap<String, String>,
labels_editing: &'a HashMap<String, form::Value<String>>, labels_editing: &'a HashMap<String, form::Value<String>>,
) -> Element<'a, Message> { ) -> Element<'a, Message> {
@ -111,22 +111,23 @@ pub fn receive<'a>(
.align_items(Alignment::Center), .align_items(Alignment::Center),
) )
.push( .push(
button::primary(None, "Verify on hardware device") Row::new()
.on_press(Message::Select(i)), .push(
button::primary(None, "Verify on hardware device")
.on_press(Message::Select(i)),
)
.push(Space::with_width(Length::Fill))
.push(
button::primary(None, "Show QR Code")
.on_press(Message::ShowQrCode(i)),
),
) )
.spacing(10), .spacing(10),
) )
.padding(20), .padding(20),
) )
}, },
)) )),
.push(if let Some(qr) = qr {
Container::new(QRCode::new(qr).cell_size(5))
.padding(10)
.style(theme::Container::QrCode)
} else {
Container::new(Space::with_width(Length::Fill)).width(Length::Fixed(200.0))
}),
) )
.spacing(20) .spacing(20)
.into() .into()
@ -214,3 +215,26 @@ pub fn verify_address_modal<'a>(
.max_width(750) .max_width(750)
.into() .into()
} }
pub fn qr_modal<'a>(qr: &'a qr_code::State, address: &'a String) -> Element<'a, Message> {
Column::new()
.push(
Row::new()
.push(Space::with_width(Length::Fill))
.push(
Container::new(QRCode::new(qr).cell_size(8))
.padding(10)
.style(theme::Container::QrCode),
)
.push(Space::with_width(Length::Fill)),
)
.push(Space::with_height(Length::Fixed(15.0)))
.push(
Container::new(text(address).size(15))
.width(Length::Fill)
.center_x(),
)
.width(Length::Fill)
.max_width(400)
.into()
}