diff --git a/gui/src/app/state/receive.rs b/gui/src/app/state/receive.rs
index e5dac8ce..cc0c9cf3 100644
--- a/gui/src/app/state/receive.rs
+++ b/gui/src/app/state/receive.rs
@@ -27,6 +27,12 @@ use crate::daemon::{
Daemon,
};
+pub enum Modal {
+ VerifyAddress(VerifyAddressModal),
+ ShowQrCode(ShowQrCodeModal),
+ None,
+}
+
#[derive(Debug, Default)]
pub struct Addresses {
list: Vec
,
@@ -57,8 +63,7 @@ pub struct ReceivePanel {
wallet: Arc,
addresses: Addresses,
labels_edited: LabelsEdited,
- qr_code: Option,
- modal: Option,
+ modal: Modal,
warning: Option,
}
@@ -69,8 +74,7 @@ impl ReceivePanel {
wallet,
addresses: Addresses::default(),
labels_edited: LabelsEdited::default(),
- qr_code: None,
- modal: None,
+ modal: Modal::None,
warning: None,
}
}
@@ -84,22 +88,24 @@ impl State for ReceivePanel {
self.warning.as_ref(),
view::receive::receive(
&self.addresses.list,
- self.qr_code.as_ref(),
&self.addresses.labels,
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))
- .into()
- } else {
- content
+ .into(),
+ Modal::ShowQrCode(m) => modal::Modal::new(content, m.view())
+ .on_blur(Some(view::Message::Close))
+ .into(),
+ Modal::None => content,
}
}
fn subscription(&self) -> Subscription {
- if let Some(modal) = &self.modal {
+ if let Modal::VerifyAddress(modal) = &self.modal {
modal.subscription()
} else {
Subscription::none()
@@ -130,11 +136,6 @@ impl State for ReceivePanel {
match res {
Ok((address, derivation_index)) => {
self.warning = None;
- self.qr_code = qr_code::State::new(format!(
- "bitcoin:{}?index={}",
- address, derivation_index
- ))
- .ok();
self.addresses.list.push(address);
self.addresses.derivation_indexes.push(derivation_index);
}
@@ -143,11 +144,11 @@ impl State for ReceivePanel {
Command::none()
}
Message::View(view::Message::Close) => {
- self.modal = None;
+ self.modal = Modal::None;
Command::none()
}
Message::View(view::Message::Select(i)) => {
- self.modal = Some(VerifyAddressModal::new(
+ self.modal = Modal::VerifyAddress(VerifyAddressModal::new(
self.data_dir.clone(),
self.wallet.clone(),
cache.network,
@@ -172,11 +173,21 @@ impl State for ReceivePanel {
Message::ReceiveAddress,
)
}
- _ => self
- .modal
- .as_mut()
- .map(|m| m.update(daemon, cache, message))
- .unwrap_or_else(Command::none),
+ Message::View(view::Message::ShowQrCode(i)) => {
+ if let Some(address) = self.addresses.list.get(i) {
+ if let Some(modal) = ShowQrCodeModal::new(address, i) {
+ self.modal = Modal::ShowQrCode(modal);
+ }
+ }
+ 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 {
+ 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::receive::qr_modal(&self.qr_code, &self.address)
+ }
+}
+
async fn verify_address(
hw: std::sync::Arc,
index: ChildNumber,
diff --git a/gui/src/app/view/message.rs b/gui/src/app/view/message.rs
index 36d9511a..2b7b0e87 100644
--- a/gui/src/app/view/message.rs
+++ b/gui/src/app/view/message.rs
@@ -18,6 +18,7 @@ pub enum Message {
Previous,
SelectHardwareWallet(usize),
CreateRbf(CreateRbfMessage),
+ ShowQrCode(usize),
}
#[derive(Debug, Clone)]
diff --git a/gui/src/app/view/receive.rs b/gui/src/app/view/receive.rs
index 508b145c..03a8e3c2 100644
--- a/gui/src/app/view/receive.rs
+++ b/gui/src/app/view/receive.rs
@@ -3,10 +3,11 @@ use std::collections::{HashMap, HashSet};
use iced::{
widget::{
qr_code::{self, QRCode},
- scrollable, Space,
+ scrollable,
},
Alignment, Length,
};
+use iced_native::widget::Space;
use liana::miniscript::bitcoin::{
self,
@@ -37,7 +38,6 @@ use super::message::Message;
pub fn receive<'a>(
addresses: &'a [bitcoin::Address],
- qr: Option<&'a qr_code::State>,
labels: &'a HashMap,
labels_editing: &'a HashMap>,
) -> Element<'a, Message> {
@@ -111,22 +111,23 @@ pub fn receive<'a>(
.align_items(Alignment::Center),
)
.push(
- button::primary(None, "Verify on hardware device")
- .on_press(Message::Select(i)),
+ Row::new()
+ .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),
)
.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)
.into()
@@ -214,3 +215,26 @@ pub fn verify_address_modal<'a>(
.max_width(750)
.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()
+}