ui: slatepack message input and tx finalization scan and show qr code buttons

This commit is contained in:
ardocrat 2024-05-19 12:50:08 +03:00
parent 2ce458a8c4
commit 71fea20b90
2 changed files with 220 additions and 176 deletions

View file

@ -22,7 +22,7 @@ use log::error;
use parking_lot::RwLock;
use crate::gui::Colors;
use crate::gui::icons::{BROOM, CLIPBOARD_TEXT, COPY, DOWNLOAD_SIMPLE, PROHIBIT, UPLOAD_SIMPLE};
use crate::gui::icons::{BROOM, CLIPBOARD_TEXT, COPY, DOWNLOAD_SIMPLE, PROHIBIT, QR_CODE, SCAN, UPLOAD_SIMPLE};
use crate::gui::platform::PlatformCallbacks;
use crate::gui::views::{Modal, Root, View};
use crate::gui::views::types::{ModalPosition, TextEditOptions};
@ -362,8 +362,7 @@ impl WalletMessages {
}
// Draw buttons to clear/copy/paste.
let fields_empty = self.message_edit.is_empty() && self.response_edit.is_empty();
let columns_num = if fields_empty || self.message_loading { 1 } else { 2 };
let columns_num = if self.message_loading { 1 } else { 2 };
let mut show_dandelion = false;
ui.scope(|ui| {
// Setup spacing between buttons.
@ -373,6 +372,7 @@ impl WalletMessages {
let first_column_content = |ui: &mut egui::Ui| {
if self.message_slate.is_some() {
if self.response_edit.is_empty() {
// Draw button to clear message input.
let clear_text = format!("{} {}", BROOM, t!("clear"));
View::button(ui, clear_text, Colors::BUTTON, || {
self.message_edit.clear();
@ -381,6 +381,102 @@ impl WalletMessages {
self.message_slate = None;
});
} else {
let copy_text = format!("{} {}", COPY, t!("copy"));
View::button(ui, copy_text, Colors::BUTTON, || {
cb.copy_string_to_buffer(self.response_edit.clone());
self.message_edit.clear();
self.response_edit.clear();
self.message_slate = None;
});
}
} else {
if self.message_loading {
View::small_loading_spinner(ui);
// Check loading result.
self.check_message_loading_result(wallet);
} else {
// Draw button to paste text from clipboard.
let paste = format!("{} {}", CLIPBOARD_TEXT, t!("paste"));
View::button(ui, paste, Colors::BUTTON, || {
let buf = cb.get_string_from_buffer();
let previous = self.message_edit.clone();
self.message_edit = buf.clone().trim().to_string();
// Parse Slatepack message resetting message error.
if buf != previous {
self.parse_message(wallet);
}
});
}
}
};
if columns_num == 1 {
columns[0].vertical_centered(first_column_content);
} else {
columns[0].vertical_centered_justified(first_column_content);
columns[1].vertical_centered_justified(|ui| {
if self.message_slate.is_some() {
if !self.response_edit.is_empty() {
// Draw button to show Slatepack message as QR code.
let qr_text = format!("{} {}", QR_CODE, t!("qr_code"));
View::button(ui, qr_text, Colors::BUTTON, || {
//TODO: show qr.
});
} else {
show_dandelion = true;
View::button(ui, t!("wallets.finalize"), Colors::GOLD, || {
let slate = self.message_slate.clone().unwrap();
let dandelion = self.dandelion;
let message_edit = self.message_edit.clone();
let wallet = wallet.clone();
let result = self.final_post_result.clone();
// Finalize or post transaction at separate thread.
self.message_loading = true;
self.message_slate = None;
thread::spawn(move || {
let res = if slate.state == SlateState::Invoice3 ||
slate.state == SlateState::Standard3 {
wallet.post(&slate, dandelion)
} else {
match wallet.finalize(&message_edit, dandelion) {
Ok(_) => {
Ok(())
}
Err(e) => {
Err(e)
}
}
};
let mut w_res = result.write();
*w_res = Some(res);
});
});
}
} else {
// Draw button to scan Slatepack message QR code.
let scan_text = format!("{} {}", SCAN, t!("scan"));
View::button(ui, scan_text, Colors::BUTTON, || {
//TODO: scan code
});
}
});
}
});
ui.add_space(12.0);
// Draw clear button on message input or cancel and clear buttons on response.
if !self.message_loading {
if self.message_slate.is_none() && !self.message_edit.is_empty() {
// Draw button to clear message input.
let clear_text = format!("{} {}", BROOM, t!("clear"));
View::button(ui, clear_text, Colors::BUTTON, || {
self.message_edit.clear();
self.response_edit.clear();
self.message_error = None;
self.message_slate = None;
});
} else if !self.response_edit.is_empty() && self.message_slate.is_some() {
// Draw cancel button.
let cancel = format!("{} {}", PROHIBIT, t!("modal.cancel"));
View::colored_text_button(ui, cancel, Colors::RED, Colors::BUTTON, || {
let slate = self.message_slate.clone().unwrap();
@ -392,11 +488,22 @@ impl WalletMessages {
}
});
}
} else {
if self.message_loading {
View::small_loading_spinner(ui);
}
});
// Check receive pay result.
// Draw setup of ability to post transaction with Dandelion.
if show_dandelion {
let dandelion_before = self.dandelion;
View::checkbox(ui, dandelion_before, t!("wallets.use_dandelion"), || {
self.dandelion = !dandelion_before;
wallet.update_use_dandelion(self.dandelion);
});
}
}
/// Check Slatepack message request loading result.
fn check_message_loading_result(&mut self, wallet: &Wallet) {
// Check finalize post pay result.
let has_finalize_post_result = {
let r_res = self.final_post_result.read();
r_res.is_some()
@ -496,99 +603,6 @@ impl WalletMessages {
}
self.message_loading = false;
}
} else {
let paste = format!("{} {}", CLIPBOARD_TEXT, t!("paste"));
View::button(ui, paste, Colors::BUTTON, || {
let buf = cb.get_string_from_buffer();
let previous = self.message_edit.clone();
self.message_edit = buf.clone().trim().to_string();
// Parse Slatepack message resetting message error.
if buf != previous {
self.parse_message(wallet);
}
});
}
}
};
if columns_num == 1 {
columns[0].vertical_centered(first_column_content);
} else {
columns[0].vertical_centered_justified(first_column_content);
columns[1].vertical_centered_justified(|ui| {
if self.message_slate.is_some() {
if !self.response_edit.is_empty() {
let copy_text = format!("{} {}", COPY, t!("copy"));
View::button(ui, copy_text, Colors::BUTTON, || {
cb.copy_string_to_buffer(self.response_edit.clone());
self.message_edit.clear();
self.response_edit.clear();
self.message_slate = None;
});
} else {
show_dandelion = true;
View::button(ui, t!("wallets.finalize"), Colors::GOLD, || {
let slate = self.message_slate.clone().unwrap();
let dandelion = self.dandelion;
let message_edit = self.message_edit.clone();
let wallet = wallet.clone();
let result = self.final_post_result.clone();
// Finalize or post transaction at separate thread.
self.message_loading = true;
self.message_slate = None;
thread::spawn(move || {
let res = if slate.state == SlateState::Invoice3 ||
slate.state == SlateState::Standard3 {
wallet.post(&slate, dandelion)
} else {
match wallet.finalize(&message_edit, dandelion) {
Ok(_) => {
Ok(())
}
Err(e) => {
Err(e)
}
}
};
let mut w_res = result.write();
*w_res = Some(res);
});
});
}
} else {
let clear_text = format!("{} {}", BROOM, t!("clear"));
View::button(ui, clear_text, Colors::BUTTON, || {
self.message_error = None;
self.message_edit.clear();
self.response_edit.clear();
self.message_slate = None;
});
}
});
}
});
ui.add_space(12.0);
// Draw clear button on response.
if !self.response_edit.is_empty() && self.message_slate.is_some() {
let clear_text = format!("{} {}", BROOM, t!("clear"));
View::button(ui, clear_text, Colors::BUTTON, || {
self.message_error = None;
self.message_edit.clear();
self.response_edit.clear();
self.message_slate = None;
});
}
});
// Draw setup of ability to post transaction with Dandelion.
if show_dandelion {
let dandelion_before = self.dandelion;
View::checkbox(ui, dandelion_before, t!("wallets.use_dandelion"), || {
self.dandelion = !dandelion_before;
wallet.update_use_dandelion(self.dandelion);
});
}
}
/// Parse message input into [`Slate`] updating slate and response input.

View file

@ -14,7 +14,7 @@
use std::sync::Arc;
use std::thread;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::time::{SystemTime, UNIX_EPOCH};
use egui::{Align, Id, Layout, Margin, RichText, Rounding, ScrollArea};
use egui::scroll_area::ScrollBarVisibility;
use egui_pull_to_refresh::PullToRefresh;
@ -24,7 +24,7 @@ use grin_wallet_libwallet::{Error, Slate, SlateState, TxLogEntryType};
use parking_lot::RwLock;
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, 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::views::{Modal, Root, View};
use crate::gui::views::types::ModalPosition;
@ -309,8 +309,9 @@ impl WalletTransactions {
}
// Draw cancel button for tx that can be reposted and canceled.
let wallet_loaded = wallet.foreign_api_port().is_some();
if ((!can_show_info && !self.tx_info_finalizing) || can_show_info) &&
(tx.can_repost(data) || tx.can_cancel()) {
(tx.can_repost(data) || tx.can_cancel()) && wallet_loaded {
let cancel_rounding = if can_show_info {
Rounding::default()
} else {
@ -333,7 +334,8 @@ impl WalletTransactions {
}
// Draw finalization button for tx that can be finalized.
if ((!can_show_info && !self.tx_info_finalizing) || can_show_info) && tx.can_finalize {
if ((!can_show_info && !self.tx_info_finalizing) || can_show_info) && tx.can_finalize &&
wallet_loaded {
let (icon, color) = if !can_show_info && self.tx_info_finalize {
(FILE_TEXT, None)
} else {
@ -354,7 +356,7 @@ impl WalletTransactions {
}
// Draw button to repost transaction.
if ((!can_show_info && !self.tx_info_finalizing) || can_show_info) &&
if ((!can_show_info && !self.tx_info_finalizing) || can_show_info) && wallet_loaded &&
tx.can_repost(data) {
View::item_button(ui,
Rounding::default(),
@ -686,7 +688,7 @@ impl WalletTransactions {
});
ui.add_space(4.0);
ui.vertical_centered(|ui| {
// Setup message input value.
let message_edit = if self.tx_info_finalize {
&mut self.tx_info_finalize_edit
} else {
@ -695,6 +697,7 @@ impl WalletTransactions {
let message_before = message_edit.clone();
// Draw Slatepack message text input or output.
ui.vertical_centered(|ui| {
let input_id = Id::from("tx_info_slatepack_message").with(slate.id).with(tx.data.id);
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(3.0);
@ -714,6 +717,8 @@ impl WalletTransactions {
.show(ui);
ui.add_space(6.0);
});
});
ui.add_space(2.0);
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(8.0);
@ -722,7 +727,13 @@ impl WalletTransactions {
if self.tx_info_finalizing {
return;
}
// Setup spacing between buttons.
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
if self.tx_info_finalize {
ui.columns(2, |columns| {
columns[0].vertical_centered_justified(|ui| {
// Draw paste button.
let paste_text = format!("{} {}", CLIPBOARD_TEXT, t!("paste"));
View::button(ui, paste_text, Colors::BUTTON, || {
@ -733,7 +744,18 @@ impl WalletTransactions {
if message_before != self.tx_info_finalize_edit {
self.on_finalization_input_change(tx, wallet, modal);
}
});
columns[1].vertical_centered_justified(|ui| {
// Draw button to scan Slatepack message QR code.
let qr_text = format!("{} {}", SCAN, t!("scan"));
View::button(ui, qr_text, Colors::BUTTON, || {
//TODO: scan qr.
});
});
});
} else {
ui.columns(2, |columns| {
columns[0].vertical_centered_justified(|ui| {
// Draw copy button.
let copy_text = format!("{} {}", COPY, t!("copy"));
View::button(ui, copy_text, Colors::BUTTON, || {
@ -745,8 +767,16 @@ impl WalletTransactions {
modal.close();
}
});
}
});
columns[1].vertical_centered_justified(|ui| {
// Draw button to show Slatepack message as QR code.
let qr_text = format!("{} {}", QR_CODE, t!("qr_code"));
View::button(ui, qr_text, Colors::BUTTON, || {
//TODO: show qr.
});
});
});
}
}
/// Parse Slatepack message on transaction finalization input change.