tx: show qr code scanner to finalize at info modal
This commit is contained in:
parent
67691061e7
commit
e1257b6bcb
3 changed files with 83 additions and 19 deletions
|
@ -152,6 +152,17 @@ pub enum QrScanResult {
|
||||||
Text(ZeroingString)
|
Text(ZeroingString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl QrScanResult {
|
||||||
|
/// Get scan result value.
|
||||||
|
pub fn value(&self) -> String {
|
||||||
|
match self {
|
||||||
|
QrScanResult::Slatepack(text) => text,
|
||||||
|
QrScanResult::Address(text) => text,
|
||||||
|
QrScanResult::Text(text) => text
|
||||||
|
}.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// QR code scan state.
|
/// QR code scan state.
|
||||||
pub struct QrScanState {
|
pub struct QrScanState {
|
||||||
// Flag to check if image is processing to find QR code.
|
// Flag to check if image is processing to find QR code.
|
||||||
|
|
|
@ -18,7 +18,6 @@ use egui::{Id, Margin, RichText, ScrollArea};
|
||||||
use egui::scroll_area::ScrollBarVisibility;
|
use egui::scroll_area::ScrollBarVisibility;
|
||||||
use grin_core::core::{amount_from_hr_string, amount_to_hr_string};
|
use grin_core::core::{amount_from_hr_string, amount_to_hr_string};
|
||||||
use grin_wallet_libwallet::{Error, Slate, SlateState};
|
use grin_wallet_libwallet::{Error, Slate, SlateState};
|
||||||
use grin_wallet_libwallet::SlateState::Standard3;
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
|
@ -211,7 +210,7 @@ impl WalletMessages {
|
||||||
}
|
}
|
||||||
QR_SLATEPACK_MESSAGE_SCAN_MODAL => {
|
QR_SLATEPACK_MESSAGE_SCAN_MODAL => {
|
||||||
Modal::ui(ui.ctx(), |ui, modal| {
|
Modal::ui(ui.ctx(), |ui, modal| {
|
||||||
self.qr_message_sca_modal_ui(ui, modal, wallet, cb);
|
self.qr_message_scan_modal_ui(ui, modal, wallet, cb);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
QR_SLATEPACK_MESSAGE_MODAL => {
|
QR_SLATEPACK_MESSAGE_MODAL => {
|
||||||
|
@ -595,11 +594,11 @@ impl WalletMessages {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw QR code scanner [`Modal`] content.
|
/// Draw QR code scanner [`Modal`] content.
|
||||||
fn qr_message_sca_modal_ui(&mut self,
|
fn qr_message_scan_modal_ui(&mut self,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
modal: &Modal,
|
modal: &Modal,
|
||||||
wallet: &Wallet,
|
wallet: &Wallet,
|
||||||
cb: &dyn PlatformCallbacks) {
|
cb: &dyn PlatformCallbacks) {
|
||||||
if self.message_scan_error {
|
if self.message_scan_error {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
|
@ -646,7 +645,7 @@ impl WalletMessages {
|
||||||
} else {
|
} else {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
self.message_camera_content.ui(ui, cb);
|
self.message_camera_content.ui(ui, cb);
|
||||||
ui.add_space(6.0);
|
ui.add_space(8.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.vertical_centered_justified(|ui| {
|
ui.vertical_centered_justified(|ui| {
|
||||||
|
|
|
@ -26,7 +26,7 @@ use parking_lot::RwLock;
|
||||||
use crate::gui::Colors;
|
use crate::gui::Colors;
|
||||||
use crate::gui::icons::{ARROW_CIRCLE_DOWN, ARROW_CIRCLE_UP, ARROW_CLOCKWISE, BRIDGE, CALENDAR_CHECK, CHAT_CIRCLE_TEXT, CHECK, CHECK_CIRCLE, CLIPBOARD_TEXT, COPY, DOTS_THREE_CIRCLE, FILE_ARCHIVE, FILE_TEXT, GEAR_FINE, HASH_STRAIGHT, PROHIBIT, QR_CODE, SCAN, X_CIRCLE};
|
use crate::gui::icons::{ARROW_CIRCLE_DOWN, ARROW_CIRCLE_UP, ARROW_CLOCKWISE, BRIDGE, CALENDAR_CHECK, CHAT_CIRCLE_TEXT, CHECK, CHECK_CIRCLE, CLIPBOARD_TEXT, COPY, DOTS_THREE_CIRCLE, FILE_ARCHIVE, FILE_TEXT, GEAR_FINE, HASH_STRAIGHT, PROHIBIT, QR_CODE, SCAN, X_CIRCLE};
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::{Modal, QrCodeContent, Root, View};
|
use crate::gui::views::{CameraContent, Modal, QrCodeContent, Root, View};
|
||||||
use crate::gui::views::types::ModalPosition;
|
use crate::gui::views::types::ModalPosition;
|
||||||
use crate::gui::views::wallets::types::WalletTab;
|
use crate::gui::views::wallets::types::WalletTab;
|
||||||
use crate::gui::views::wallets::wallet::types::{GRIN, SLATEPACK_MESSAGE_HINT, WalletTabType};
|
use crate::gui::views::wallets::wallet::types::{GRIN, SLATEPACK_MESSAGE_HINT, WalletTabType};
|
||||||
|
@ -54,8 +54,12 @@ pub struct WalletTransactions {
|
||||||
tx_info_final_result: Arc<RwLock<Option<Result<Slate, Error>>>>,
|
tx_info_final_result: Arc<RwLock<Option<Result<Slate, Error>>>>,
|
||||||
/// Flag to check if QR code is showing at [`Modal`].
|
/// Flag to check if QR code is showing at [`Modal`].
|
||||||
tx_info_show_qr: bool,
|
tx_info_show_qr: bool,
|
||||||
/// QR code address image [`Modal`] content.
|
/// QR code Slatepack message image [`Modal`] content.
|
||||||
tx_info_qr_code_content: QrCodeContent,
|
tx_info_qr_code_content: QrCodeContent,
|
||||||
|
/// Flag to check if QR code scanner is showing at [`Modal`].
|
||||||
|
tx_info_show_scanner: bool,
|
||||||
|
/// QR code scanner [`Modal`] content.
|
||||||
|
tx_info_scanner_content: CameraContent,
|
||||||
|
|
||||||
/// Transaction identifier to use at confirmation [`Modal`].
|
/// Transaction identifier to use at confirmation [`Modal`].
|
||||||
confirm_cancel_tx_id: Option<u32>,
|
confirm_cancel_tx_id: Option<u32>,
|
||||||
|
@ -77,6 +81,8 @@ impl Default for WalletTransactions {
|
||||||
tx_info_final_result: Arc::new(RwLock::new(None)),
|
tx_info_final_result: Arc::new(RwLock::new(None)),
|
||||||
tx_info_show_qr: false,
|
tx_info_show_qr: false,
|
||||||
tx_info_qr_code_content: QrCodeContent::new("".to_string()),
|
tx_info_qr_code_content: QrCodeContent::new("".to_string()),
|
||||||
|
tx_info_show_scanner: false,
|
||||||
|
tx_info_scanner_content: CameraContent::default(),
|
||||||
confirm_cancel_tx_id: None,
|
confirm_cancel_tx_id: None,
|
||||||
manual_sync: None,
|
manual_sync: None,
|
||||||
}
|
}
|
||||||
|
@ -534,7 +540,7 @@ impl WalletTransactions {
|
||||||
}
|
}
|
||||||
let tx = txs.get(0).unwrap();
|
let tx = txs.get(0).unwrap();
|
||||||
|
|
||||||
if !self.tx_info_show_qr {
|
if !self.tx_info_show_qr && !self.tx_info_show_scanner {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|
||||||
// Show transaction amount status and time.
|
// Show transaction amount status and time.
|
||||||
|
@ -562,9 +568,10 @@ impl WalletTransactions {
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
if !self.tx_info_finalizing {
|
if !self.tx_info_finalizing {
|
||||||
|
// Setup spacing between buttons.
|
||||||
|
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
||||||
|
|
||||||
if self.tx_info_show_qr {
|
if self.tx_info_show_qr {
|
||||||
// Setup spacing between buttons.
|
|
||||||
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
|
||||||
// Show buttons to close modal or come back to text content.
|
// Show buttons to close modal or come back to text content.
|
||||||
ui.columns(2, |cols| {
|
ui.columns(2, |cols| {
|
||||||
cols[0].vertical_centered_justified(|ui| {
|
cols[0].vertical_centered_justified(|ui| {
|
||||||
|
@ -581,6 +588,24 @@ impl WalletTransactions {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} else if self.tx_info_show_scanner {
|
||||||
|
// Show buttons to close modal or close scanner.
|
||||||
|
ui.columns(2, |cols| {
|
||||||
|
cols[0].vertical_centered_justified(|ui| {
|
||||||
|
View::button(ui, t!("close"), Colors::WHITE, || {
|
||||||
|
cb.stop_camera();
|
||||||
|
self.tx_info_show_scanner = false;
|
||||||
|
modal.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
cols[1].vertical_centered_justified(|ui| {
|
||||||
|
View::button(ui, t!("back"), Colors::WHITE, || {
|
||||||
|
cb.stop_camera();
|
||||||
|
self.tx_info_show_scanner = false;
|
||||||
|
modal.enable_closing();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Show button to close modal.
|
// Show button to close modal.
|
||||||
ui.vertical_centered_justified(|ui| {
|
ui.vertical_centered_justified(|ui| {
|
||||||
|
@ -691,6 +716,25 @@ impl WalletTransactions {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw QR code scanner content if requested.
|
||||||
|
if self.tx_info_show_scanner {
|
||||||
|
if let Some(result) = self.tx_info_scanner_content.qr_scan_result() {
|
||||||
|
cb.stop_camera();
|
||||||
|
self.tx_info_scanner_content.clear_state();
|
||||||
|
|
||||||
|
// Setup value to finalization input field.
|
||||||
|
self.tx_info_finalize_edit = result.value();
|
||||||
|
self.on_finalization_input_change(tx, wallet, modal, );
|
||||||
|
|
||||||
|
modal.enable_closing();
|
||||||
|
self.tx_info_show_scanner = false;
|
||||||
|
} else {
|
||||||
|
self.tx_info_scanner_content.ui(ui, cb);
|
||||||
|
ui.add_space(2.0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let slate = self.tx_info_slate.clone().unwrap();
|
let slate = self.tx_info_slate.clone().unwrap();
|
||||||
let amount = amount_to_hr_string(tx.amount, true);
|
let amount = amount_to_hr_string(tx.amount, true);
|
||||||
|
|
||||||
|
@ -785,14 +829,17 @@ impl WalletTransactions {
|
||||||
|
|
||||||
// Callback on finalization message input change.
|
// Callback on finalization message input change.
|
||||||
if message_before != self.tx_info_finalize_edit {
|
if message_before != self.tx_info_finalize_edit {
|
||||||
self.on_finalization_input_change(tx, wallet, modal);
|
self.on_finalization_input_change(tx, wallet, modal, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
columns[1].vertical_centered_justified(|ui| {
|
columns[1].vertical_centered_justified(|ui| {
|
||||||
// Draw button to scan Slatepack message QR code.
|
// Draw button to scan Slatepack message QR code.
|
||||||
let qr_text = format!("{} {}", SCAN, t!("scan"));
|
let qr_text = format!("{} {}", SCAN, t!("scan"));
|
||||||
View::button(ui, qr_text, Colors::BUTTON, || {
|
View::button(ui, qr_text, Colors::BUTTON, || {
|
||||||
//TODO: scan qr.
|
cb.hide_keyboard();
|
||||||
|
modal.disable_closing();
|
||||||
|
cb.start_camera();
|
||||||
|
self.tx_info_show_scanner = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -807,6 +854,7 @@ impl WalletTransactions {
|
||||||
if tx.can_finalize {
|
if tx.can_finalize {
|
||||||
self.tx_info_finalize = true;
|
self.tx_info_finalize = true;
|
||||||
} else {
|
} else {
|
||||||
|
cb.hide_keyboard();
|
||||||
modal.close();
|
modal.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -815,6 +863,7 @@ impl WalletTransactions {
|
||||||
// Draw button to show Slatepack message as QR code.
|
// Draw button to show Slatepack message as QR code.
|
||||||
let qr_text = format!("{} {}", QR_CODE, t!("qr_code"));
|
let qr_text = format!("{} {}", QR_CODE, t!("qr_code"));
|
||||||
View::button(ui, qr_text, Colors::BUTTON, || {
|
View::button(ui, qr_text, Colors::BUTTON, || {
|
||||||
|
cb.hide_keyboard();
|
||||||
self.tx_info_show_qr = true;
|
self.tx_info_show_qr = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -823,24 +872,29 @@ impl WalletTransactions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse Slatepack message on transaction finalization input change.
|
/// Parse Slatepack message on transaction finalization input change.
|
||||||
fn on_finalization_input_change(&mut self, tx: &WalletTransaction, w: &Wallet, modal: &Modal) {
|
fn on_finalization_input_change(&mut self,
|
||||||
|
tx: &WalletTransaction,
|
||||||
|
wallet: &Wallet,
|
||||||
|
modal: &Modal,
|
||||||
|
cb: &dyn PlatformCallbacks) {
|
||||||
let message = &self.tx_info_finalize_edit;
|
let message = &self.tx_info_finalize_edit;
|
||||||
if message.is_empty() {
|
if message.is_empty() {
|
||||||
self.tx_info_finalize_error = false;
|
self.tx_info_finalize_error = false;
|
||||||
} else {
|
} else {
|
||||||
// Parse input message to finalize.
|
// Parse input message to finalize.
|
||||||
if let Ok(slate) = w.parse_slatepack(message) {
|
if let Ok(slate) = wallet.parse_slatepack(message) {
|
||||||
let send = slate.state == SlateState::Standard2 &&
|
let send = slate.state == SlateState::Standard2 &&
|
||||||
tx.data.tx_type == TxLogEntryType::TxSent;
|
tx.data.tx_type == TxLogEntryType::TxSent;
|
||||||
let receive = slate.state == SlateState::Invoice2 &&
|
let receive = slate.state == SlateState::Invoice2 &&
|
||||||
tx.data.tx_type == TxLogEntryType::TxReceived;
|
tx.data.tx_type == TxLogEntryType::TxReceived;
|
||||||
if Some(slate.id) == tx.data.tx_slate_id && (send || receive) {
|
if Some(slate.id) == tx.data.tx_slate_id && (send || receive) {
|
||||||
let message = message.clone();
|
let message = message.clone();
|
||||||
let wallet = w.clone();
|
let wallet = wallet.clone();
|
||||||
let final_res = self.tx_info_final_result.clone();
|
let final_res = self.tx_info_final_result.clone();
|
||||||
|
// Finalize transaction at separate thread.
|
||||||
|
cb.hide_keyboard();
|
||||||
self.tx_info_finalizing = true;
|
self.tx_info_finalizing = true;
|
||||||
modal.disable_closing();
|
modal.disable_closing();
|
||||||
// Finalize transaction at separate thread.
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let res = wallet.finalize(&message, wallet.can_use_dandelion());
|
let res = wallet.finalize(&message, wallet.can_use_dandelion());
|
||||||
let mut w_res = final_res.write();
|
let mut w_res = final_res.write();
|
||||||
|
|
Loading…
Reference in a new issue