ui: text input qr scan support, transport address, bridge scan

This commit is contained in:
ardocrat 2024-05-21 13:31:46 +03:00
parent 8073fdbef2
commit 8973a8c95a
17 changed files with 228 additions and 108 deletions

View file

@ -280,7 +280,7 @@ impl ConnectionsContent {
self.first_modal_launch = false;
url_edit_opts.focus = true;
}
View::text_edit(ui, cb, &mut self.ext_node_url_edit, url_edit_opts);
View::text_edit(ui, cb, &mut self.ext_node_url_edit, &mut url_edit_opts);
ui.add_space(8.0);
ui.label(RichText::new(t!("wallets.node_secret"))
@ -290,8 +290,8 @@ impl ConnectionsContent {
// Draw node API secret text edit.
let secret_edit_id = Id::from(modal.id).with(self.ext_conn_id_edit).with("node_secret");
let secret_edit_opts = TextEditOptions::new(secret_edit_id).paste().no_focus();
View::text_edit(ui, cb, &mut self.ext_node_secret_edit, secret_edit_opts);
let mut secret_edit_opts = TextEditOptions::new(secret_edit_id).paste().no_focus();
View::text_edit(ui, cb, &mut self.ext_node_secret_edit, &mut secret_edit_opts);
// Show error when specified URL is not valid.
if self.ext_node_url_error {

View file

@ -165,8 +165,8 @@ impl DandelionSetup {
ui.add_space(8.0);
// Draw epoch text edit.
let epoch_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.epoch_edit, epoch_edit_opts);
let mut epoch_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.epoch_edit, &mut epoch_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.epoch_edit.parse::<u16>().is_err() {
@ -242,8 +242,8 @@ impl DandelionSetup {
ui.add_space(8.0);
// Draw embargo text edit.
let embargo_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.embargo_edit, embargo_edit_opts);
let mut embargo_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.embargo_edit, &mut embargo_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.embargo_edit.parse::<u16>().is_err() {
@ -319,8 +319,8 @@ impl DandelionSetup {
ui.add_space(8.0);
// Draw aggregation period text edit.
let aggregation_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.aggregation_edit, aggregation_edit_opts);
let mut aggregation_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.aggregation_edit, &mut aggregation_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.aggregation_edit.parse::<u16>().is_err() {
@ -396,8 +396,8 @@ impl DandelionSetup {
ui.add_space(8.0);
// Draw stem phase probability text edit.
let stem_prob_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.stem_prob_edit, stem_prob_edit_opts);
let mut stem_prob_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.stem_prob_edit, &mut stem_prob_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.stem_prob_edit.parse::<u8>().is_err() {

View file

@ -287,8 +287,8 @@ impl NodeSetup {
ui.add_space(6.0);
// Draw API port text edit.
let api_port_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.api_port_edit, api_port_edit_opts);
let mut api_port_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.api_port_edit, &mut api_port_edit_opts);
// Show error when specified port is unavailable or reminder to restart enabled node.
if !self.api_port_available_edit {
@ -390,8 +390,8 @@ impl NodeSetup {
ui.add_space(8.0);
// Draw API secret token value text edit.
let secret_edit_opts = TextEditOptions::new(Id::from(modal.id)).copy().paste();
View::text_edit(ui, cb, &mut self.secret_edit, secret_edit_opts);
let mut secret_edit_opts = TextEditOptions::new(Id::from(modal.id)).copy().paste();
View::text_edit(ui, cb, &mut self.secret_edit, &mut secret_edit_opts);
ui.add_space(6.0);
// Show reminder to restart enabled node.
@ -476,8 +476,8 @@ impl NodeSetup {
ui.add_space(8.0);
// Draw ftl value text edit.
let ftl_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.ftl_edit, ftl_edit_opts);
let mut ftl_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.ftl_edit, &mut ftl_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.ftl_edit.parse::<u64>().is_err() {

View file

@ -280,8 +280,8 @@ impl P2PSetup {
ui.add_space(8.0);
// Draw p2p port text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.port_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.port_edit, &mut text_edit_opts);
// Show error when specified port is unavailable.
if !self.port_available_edit {
@ -421,8 +421,8 @@ impl P2PSetup {
ui.add_space(8.0);
// Draw peer address text edit.
let peer_text_edit_opts = TextEditOptions::new(Id::from(modal.id)).paste();
View::text_edit(ui, cb, &mut self.peer_edit, peer_text_edit_opts);
let mut peer_text_edit_opts = TextEditOptions::new(Id::from(modal.id)).paste();
View::text_edit(ui, cb, &mut self.peer_edit, &mut peer_text_edit_opts);
// Show error when specified address is incorrect.
if !self.is_correct_address_edit {
@ -535,8 +535,8 @@ impl P2PSetup {
ui.add_space(8.0);
// Draw ban window text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.ban_window_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.ban_window_edit, &mut text_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.ban_window_edit.parse::<i64>().is_err() {
@ -613,8 +613,8 @@ impl P2PSetup {
ui.add_space(8.0);
// Draw maximum number of inbound peers text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.max_inbound_count, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.max_inbound_count, &mut text_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.max_inbound_count.parse::<u32>().is_err() {
@ -691,8 +691,8 @@ impl P2PSetup {
ui.add_space(8.0);
// Draw maximum number of outbound peers text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.max_outbound_count, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.max_outbound_count, &mut text_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.max_outbound_count.parse::<u32>().is_err() {

View file

@ -169,8 +169,8 @@ impl PoolSetup {
ui.add_space(8.0);
// Draw fee base text edit.
let fee_base_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.fee_base_edit, fee_base_edit_opts);
let mut fee_base_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.fee_base_edit, &mut fee_base_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.fee_base_edit.parse::<u64>().is_err() {
@ -246,8 +246,8 @@ impl PoolSetup {
ui.add_space(8.0);
// Draw reorg period text edit.
let reorg_period_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.reorg_period_edit, reorg_period_edit_opts);
let mut reorg_period_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.reorg_period_edit, &mut reorg_period_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.reorg_period_edit.parse::<u32>().is_err() {
@ -323,8 +323,8 @@ impl PoolSetup {
ui.add_space(8.0);
// Draw pool size text edit.
let pool_size_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.pool_size_edit, pool_size_edit_opts);
let mut pool_size_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.pool_size_edit, &mut pool_size_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.pool_size_edit.parse::<usize>().is_err() {
@ -400,8 +400,8 @@ impl PoolSetup {
ui.add_space(8.0);
// Draw stempool size text edit.
let stem_pool_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.stempool_size_edit, stem_pool_edit_opts);
let mut stem_pool_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.stempool_size_edit, &mut stem_pool_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.stempool_size_edit.parse::<usize>().is_err() {
@ -477,8 +477,8 @@ impl PoolSetup {
ui.add_space(8.0);
// Draw tx weight text edit.
let mac_weight_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.max_weight_edit, mac_weight_edit_opts);
let mut mac_weight_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.max_weight_edit, &mut mac_weight_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.max_weight_edit.parse::<u64>().is_err() {

View file

@ -224,8 +224,8 @@ impl StratumSetup {
ui.add_space(8.0);
// Draw stratum port text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.stratum_port_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.stratum_port_edit, &mut text_edit_opts);
// Show error when specified port is unavailable.
if !self.stratum_port_available_edit {
@ -319,8 +319,8 @@ impl StratumSetup {
ui.add_space(8.0);
// Draw attempt time text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.attempt_time_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.attempt_time_edit, &mut text_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.attempt_time_edit.parse::<u32>().is_err() {
@ -397,8 +397,8 @@ impl StratumSetup {
ui.add_space(8.0);
// Draw share difficulty text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.min_share_diff_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.min_share_diff_edit, &mut text_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.min_share_diff_edit.parse::<u64>().is_err() {

View file

@ -77,18 +77,20 @@ pub trait ModalContainer {
pub struct TextEditOptions {
/// View identifier.
pub id: egui::Id,
/// Flag to check if horizontal centering is needed.
/// Check if horizontal centering is needed.
pub h_center: bool,
/// Flag to check if initial focus on field is needed.
/// Check if initial focus on field is needed.
pub focus: bool,
/// Flag to hide letters and draw button to show/hide letters.
/// Hide letters and draw button to show/hide letters.
pub password: bool,
/// Flag to show copy button.
/// Show copy button.
pub copy: bool,
/// Flag to show paste button.
/// Show paste button.
pub paste: bool,
/// Flag to show button to scan QR code into text.
pub scan_qr: bool
/// Show button to scan QR code into text.
pub scan_qr: bool,
/// Callback when scan button was pressed.
pub scan_pressed: bool,
}
impl TextEditOptions {
@ -101,6 +103,7 @@ impl TextEditOptions {
copy: false,
paste: false,
scan_qr: false,
scan_pressed: false,
}
}
@ -137,6 +140,7 @@ impl TextEditOptions {
/// Show button to scan QR code to text.
pub fn scan_qr(mut self) -> Self {
self.scan_qr = true;
self.scan_pressed = false;
self
}
}

View file

@ -17,7 +17,7 @@ use std::sync::Arc;
use parking_lot::RwLock;
use lazy_static::lazy_static;
use egui::{Align, Button, CursorIcon, Id, Layout, lerp, PointerState, Rect, Response, Rgba, RichText, Sense, Spinner, TextBuffer, TextStyle, Widget};
use egui::{Align, Button, CursorIcon, Layout, lerp, PointerState, Rect, Response, Rgba, RichText, Sense, Spinner, TextBuffer, TextStyle, Widget};
use egui::epaint::{Color32, FontId, RectShape, Rounding, Stroke};
use egui::epaint::text::TextWrapping;
use egui::os::OperatingSystem;
@ -321,7 +321,7 @@ impl View {
pub fn text_edit(ui: &mut egui::Ui,
cb: &dyn PlatformCallbacks,
value: &mut String,
options: TextEditOptions) {
options: &mut TextEditOptions) {
let mut layout_rect = ui.available_rect_before_wrap();
layout_rect.set_height(Self::TEXT_EDIT_HEIGHT);
ui.allocate_ui_with_layout(layout_rect.size(), Layout::right_to_left(Align::Center), |ui| {
@ -371,7 +371,8 @@ impl View {
if options.scan_qr {
let scan_icon = SCAN.to_string();
View::button(ui, scan_icon, Colors::WHITE, || {
//TODO: open scanner
cb.start_camera();
options.scan_pressed = true;
});
ui.add_space(8.0);
}
@ -412,7 +413,7 @@ impl View {
}
/// Apply soft keyboard input data to provided String.
pub fn on_soft_input(ui: &mut egui::Ui, id: Id, value: &mut String) {
pub fn on_soft_input(ui: &mut egui::Ui, id: egui::Id, value: &mut String) {
let os = OperatingSystem::from_target_os();
if os == OperatingSystem::Android {
let mut w_input = LAST_SOFT_KEYBOARD_INPUT.write();

View file

@ -527,8 +527,8 @@ impl WalletsContent {
ui.add_space(8.0);
// Show password input.
let pass_edit_opts = TextEditOptions::new(Id::from(modal.id)).password();
View::text_edit(ui, cb, &mut self.pass_edit, pass_edit_opts);
let mut pass_edit_opts = TextEditOptions::new(Id::from(modal.id)).password();
View::text_edit(ui, cb, &mut self.pass_edit, &mut pass_edit_opts);
// Show information when password is empty.
if self.pass_edit.is_empty() {

View file

@ -409,7 +409,7 @@ impl WalletCreation {
self.modal_just_opened = false;
name_edit_opts.focus = true;
}
View::text_edit(ui, cb, &mut self.name_edit, name_edit_opts);
View::text_edit(ui, cb, &mut self.name_edit, &mut name_edit_opts);
ui.add_space(8.0);
ui.label(RichText::new(t!("wallets.pass"))
@ -418,10 +418,10 @@ impl WalletCreation {
ui.add_space(8.0);
// Draw wallet password text edit.
let pass_text_edit_opts = TextEditOptions::new(Id::from(modal.id).with("pass"))
let mut pass_text_edit_opts = TextEditOptions::new(Id::from(modal.id).with("pass"))
.password()
.no_focus();
View::text_edit(ui, cb, &mut self.pass_edit, pass_text_edit_opts);
View::text_edit(ui, cb, &mut self.pass_edit, &mut pass_text_edit_opts);
ui.add_space(12.0);
});

View file

@ -277,8 +277,10 @@ impl MnemonicSetup {
ui.add_space(8.0);
// Draw word value text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id).with(self.word_num_edit));
View::text_edit(ui, cb, &mut self.word_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(
Id::from(modal.id).with(self.word_num_edit)
);
View::text_edit(ui, cb, &mut self.word_edit, &mut text_edit_opts);
// Show error when specified word is not valid.
if !self.valid_word_edit {

View file

@ -181,8 +181,8 @@ impl CommonSetup {
// Show wallet name text edit.
let name_edit_id = Id::from(modal.id).with(wallet.get_config().id);
let name_edit_opts = TextEditOptions::new(name_edit_id);
View::text_edit(ui, cb, &mut self.name_edit, name_edit_opts);
let mut name_edit_opts = TextEditOptions::new(name_edit_id);
View::text_edit(ui, cb, &mut self.name_edit, &mut name_edit_opts);
ui.add_space(12.0);
});
@ -242,7 +242,7 @@ impl CommonSetup {
self.first_edit_pass_opening = false;
pass_edit_opts.focus = true;
}
View::text_edit(ui, cb, &mut self.old_pass_edit, pass_edit_opts);
View::text_edit(ui, cb, &mut self.old_pass_edit, &mut pass_edit_opts);
ui.add_space(8.0);
ui.label(RichText::new(t!("wallets.new_pass"))
@ -252,8 +252,10 @@ impl CommonSetup {
// Draw new password text edit.
let new_pass_edit_id = Id::from(modal.id).with(wallet_id).with("new_pass");
let new_pass_edit_opts = TextEditOptions::new(new_pass_edit_id).password().no_focus();
View::text_edit(ui, cb, &mut self.new_pass_edit, new_pass_edit_opts);
let mut new_pass_edit_opts = TextEditOptions::new(new_pass_edit_id)
.password()
.no_focus();
View::text_edit(ui, cb, &mut self.new_pass_edit, &mut new_pass_edit_opts);
// Show information when password is empty.
if self.old_pass_edit.is_empty() || self.new_pass_edit.is_empty() {
@ -330,8 +332,8 @@ impl CommonSetup {
ui.add_space(8.0);
// Minimum amount of confirmations text edit.
let text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.min_confirmations_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(Id::from(modal.id)).h_center();
View::text_edit(ui, cb, &mut self.min_confirmations_edit, &mut text_edit_opts);
// Show error when specified value is not valid or reminder to restart enabled node.
if self.min_confirmations_edit.parse::<u64>().is_err() {

View file

@ -333,7 +333,7 @@ impl ConnectionSetup {
self.first_modal_launch = false;
url_edit_opts.focus = true;
}
View::text_edit(ui, cb, &mut self.ext_node_url_edit, url_edit_opts);
View::text_edit(ui, cb, &mut self.ext_node_url_edit, &mut url_edit_opts);
ui.add_space(8.0);
ui.label(RichText::new(t!("wallets.node_secret"))
@ -343,8 +343,8 @@ impl ConnectionSetup {
// Draw node API secret text edit.
let secret_edit_id = Id::from(modal.id).with("node_secret_edit");
let secret_edit_opts = TextEditOptions::new(secret_edit_id).paste().no_focus();
View::text_edit(ui, cb, &mut self.ext_node_secret_edit, secret_edit_opts);
let mut secret_edit_opts = TextEditOptions::new(secret_edit_id).paste().no_focus();
View::text_edit(ui, cb, &mut self.ext_node_secret_edit, &mut secret_edit_opts);
// Show error when specified URL is not valid.
if self.ext_node_url_error {

View file

@ -204,8 +204,8 @@ impl RecoverySetup {
// Draw current wallet password text edit.
let pass_edit_id = Id::from(modal.id).with(wallet.get_config().id);
let pass_edit_opts = TextEditOptions::new(pass_edit_id).password();
View::text_edit(ui, cb, &mut self.pass_edit, pass_edit_opts);
let mut pass_edit_opts = TextEditOptions::new(pass_edit_id).password();
View::text_edit(ui, cb, &mut self.pass_edit, &mut pass_edit_opts);
// Show information when password is empty or wrong.
if self.pass_edit.is_empty() {

View file

@ -265,8 +265,8 @@ impl WalletContent {
// Draw account name edit.
let text_edit_id = Id::from(modal.id).with(wallet.get_config().id);
let text_edit_opts = TextEditOptions::new(text_edit_id);
View::text_edit(ui, cb, &mut self.account_label_edit, text_edit_opts);
let mut text_edit_opts = TextEditOptions::new(text_edit_id);
View::text_edit(ui, cb, &mut self.account_label_edit, &mut text_edit_opts);
// Show error occurred during account creation..
if self.account_creation_error {

View file

@ -364,9 +364,9 @@ impl WalletMessages {
// Draw request amount text input.
let amount_edit_id = Id::from(modal.id).with(wallet.get_config().id);
let amount_edit_opts = TextEditOptions::new(amount_edit_id).h_center();
let mut amount_edit_opts = TextEditOptions::new(amount_edit_id).h_center();
let amount_edit_before = self.request_amount_edit.clone();
View::text_edit(ui, cb, &mut self.request_amount_edit, amount_edit_opts);
View::text_edit(ui, cb, &mut self.request_amount_edit, &mut amount_edit_opts);
// Check value if input was changed.
if amount_edit_before != self.request_amount_edit {

View file

@ -26,7 +26,7 @@ use grin_wallet_libwallet::SlatepackAddress;
use crate::gui::Colors;
use crate::gui::icons::{CHECK_CIRCLE, COPY, DOTS_THREE_CIRCLE, EXPORT, GEAR_SIX, GLOBE_SIMPLE, POWER, QR_CODE, SHIELD_CHECKERED, SHIELD_SLASH, WARNING_CIRCLE, X_CIRCLE};
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, TextEditOptions};
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
use crate::gui::views::wallets::wallet::WalletContent;
@ -48,11 +48,15 @@ pub struct WalletTransport {
address_edit: String,
/// Flag to check if entered address is incorrect at [`Modal`].
address_error: bool,
/// Flag to check if QR code scanner is opened at address [`Modal`].
show_address_scan: bool,
/// Address QR code scanner [`Modal`] content.
address_scan_content: CameraContent,
/// Flag to check if [`Modal`] was just opened to focus on first field.
modal_just_opened: bool,
/// QR code address image [`Modal`] content.
qr_code_content: QrCodeContent,
qr_address_content: QrCodeContent,
/// Flag to check if Tor settings were changed.
tor_settings_changed: bool,
@ -60,6 +64,10 @@ pub struct WalletTransport {
bridge_bin_path_edit: String,
/// Tor bridge connection line edit text.
bridge_conn_line_edit: String,
/// Flag to check if QR code scanner is opened at bridge [`Modal`].
show_bridge_scan: bool,
/// Address QR code scanner [`Modal`] content.
bridge_qr_scan_content: CameraContent,
}
impl WalletTab for WalletTransport {
@ -134,11 +142,15 @@ impl WalletTransport {
amount_edit: "".to_string(),
address_edit: "".to_string(),
address_error: false,
show_address_scan: false,
address_scan_content: CameraContent::default(),
modal_just_opened: false,
qr_code_content: QrCodeContent::new(addr),
qr_address_content: QrCodeContent::new(addr),
tor_settings_changed: false,
bridge_bin_path_edit: bin_path,
bridge_conn_line_edit: conn_line,
show_bridge_scan: false,
bridge_qr_scan_content: CameraContent::default(),
}
}
@ -218,13 +230,7 @@ impl WalletTransport {
// Draw button to setup Tor transport.
let button_rounding = View::item_rounding(0, 2, true);
View::item_button(ui, button_rounding, GEAR_SIX, None, || {
self.tor_settings_changed = false;
// Show Tor settings modal.
Modal::new(TOR_SETTINGS_MODAL)
.position(ModalPosition::CenterTop)
.title(t!("transport.tor_settings"))
.closeable(false)
.show();
self.show_tor_settings_modal();
});
// Draw button to enable/disable Tor listener for current wallet.
@ -292,17 +298,67 @@ impl WalletTransport {
});
}
/// Draw tor transport settings [`Modal`] content.
/// Show Tor transport settings [`Modal`].
fn show_tor_settings_modal(&mut self) {
self.tor_settings_changed = false;
// Show Tor settings modal.
Modal::new(TOR_SETTINGS_MODAL)
.position(ModalPosition::CenterTop)
.title(t!("transport.tor_settings"))
.closeable(false)
.show();
}
/// Draw Tor transport settings [`Modal`] content.
fn tor_settings_modal_ui(&mut self,
ui: &mut egui::Ui,
wallet: &Wallet,
modal: &Modal,
cb: &dyn PlatformCallbacks) {
ui.add_space(6.0);
// Draw QR code scanner content if requested.
if self.show_bridge_scan {
let mut on_stop = |content: &mut CameraContent| {
cb.stop_camera();
content.clear_state();
modal.enable_closing();
self.show_bridge_scan = false;
};
if let Some(result) = self.bridge_qr_scan_content.qr_scan_result() {
self.bridge_conn_line_edit = result.value();
on_stop(&mut self.bridge_qr_scan_content);
cb.show_keyboard();
} else {
self.bridge_qr_scan_content.ui(ui, cb);
ui.add_space(12.0);
// 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 sending input.
ui.columns(2, |cols| {
cols[0].vertical_centered_justified(|ui| {
View::button(ui, t!("close"), Colors::WHITE, || {
on_stop(&mut self.bridge_qr_scan_content);
modal.close();
});
});
cols[1].vertical_centered_justified(|ui| {
View::button(ui, t!("back"), Colors::WHITE, || {
on_stop(&mut self.bridge_qr_scan_content);
});
});
});
ui.add_space(6.0);
}
return;
}
// Do not show bridges setup on Android.
let os = OperatingSystem::from_target_os();
let show_bridges = os != OperatingSystem::Android;
ui.add_space(6.0);
if show_bridges {
let bridge = TorConfig::get_bridge();
ui.vertical_centered(|ui| {
@ -360,7 +416,7 @@ impl WalletTransport {
let bin_edit_id = Id::from(modal.id)
.with(wallet.get_config().id)
.with("_bin_edit");
let bin_edit_opts = TextEditOptions::new(bin_edit_id)
let mut bin_edit_opts = TextEditOptions::new(bin_edit_id)
.paste()
.no_focus();
let bin_edit_before = self.bridge_bin_path_edit.clone();
@ -369,25 +425,32 @@ impl WalletTransport {
.size(17.0)
.color(Colors::INACTIVE_TEXT));
ui.add_space(6.0);
View::text_edit(ui, cb, &mut self.bridge_bin_path_edit, bin_edit_opts);
View::text_edit(ui, cb, &mut self.bridge_bin_path_edit, &mut bin_edit_opts);
ui.add_space(6.0);
});
// Draw connection line text edit.
let conn_edit_before = self.bridge_conn_line_edit.clone();
let conn_edit_id = Id::from(modal.id)
.with(wallet.get_config().id)
.with("_conn_edit");
let conn_edit_opts = TextEditOptions::new(conn_edit_id)
let mut conn_edit_opts = TextEditOptions::new(conn_edit_id)
.paste()
.scan_qr()
.no_focus();
let conn_edit_before = self.bridge_conn_line_edit.clone();
.no_focus()
.scan_qr();
ui.vertical_centered(|ui| {
ui.label(RichText::new(t!("transport.conn_line"))
.size(17.0)
.color(Colors::INACTIVE_TEXT));
ui.add_space(6.0);
View::text_edit(ui, cb, &mut self.bridge_conn_line_edit, conn_edit_opts);
View::text_edit(ui, cb, &mut self.bridge_conn_line_edit, &mut conn_edit_opts);
// Check if scan button was pressed.
if conn_edit_opts.scan_pressed {
cb.hide_keyboard();
modal.disable_closing();
conn_edit_opts.scan_pressed = false;
self.show_bridge_scan = true;
}
});
// Check if bin path or connection line text was changed to save bridge.
@ -481,7 +544,7 @@ impl WalletTransport {
};
View::item_button(ui, button_rounding, QR_CODE, None, || {
// Show QR code image address modal.
self.qr_code_content.clear_state();
self.qr_address_content.clear_state();
Modal::new(QR_ADDRESS_MODAL)
.position(ModalPosition::CenterTop)
.title(t!("network_mining.address"))
@ -525,8 +588,8 @@ impl WalletTransport {
ui.add_space(6.0);
// Draw QR code content.
let text = self.qr_code_content.text.clone();
self.qr_code_content.ui(ui, text.clone());
let text = self.qr_address_content.text.clone();
self.qr_address_content.ui(ui, text.clone());
ui.add_space(6.0);
// Show address.
@ -535,7 +598,7 @@ impl WalletTransport {
ui.vertical_centered_justified(|ui| {
View::button(ui, t!("close"), Colors::WHITE, || {
self.qr_code_content.clear_state();
self.qr_address_content.clear_state();
modal.close();
});
ui.add_space(6.0);
@ -567,7 +630,6 @@ impl WalletTransport {
/// Show [`Modal`] to send over Tor.
pub fn show_send_tor_modal(&mut self, cb: &dyn PlatformCallbacks, address: Option<String>) {
// Setup modal values.
{
let mut w_send_err = self.tor_send_error.write();
*w_send_err = false;
@ -616,6 +678,48 @@ impl WalletTransport {
let has_send_err = self.has_tor_send_error();
let sending = self.tor_sending();
if !has_send_err && !sending {
// Draw QR code scanner content if requested.
if self.show_address_scan {
let mut on_stop = |content: &mut CameraContent| {
cb.stop_camera();
content.clear_state();
modal.enable_closing();
self.show_address_scan = false;
};
if let Some(result) = self.address_scan_content.qr_scan_result() {
self.address_edit = result.value();
self.modal_just_opened = true;
on_stop(&mut self.address_scan_content);
cb.show_keyboard();
} else {
self.address_scan_content.ui(ui, cb);
ui.add_space(12.0);
// 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 sending input.
ui.columns(2, |cols| {
cols[0].vertical_centered_justified(|ui| {
View::button(ui, t!("close"), Colors::WHITE, || {
on_stop(&mut self.address_scan_content);
modal.close();
});
});
cols[1].vertical_centered_justified(|ui| {
View::button(ui, t!("back"), Colors::WHITE, || {
self.modal_just_opened = true;
on_stop(&mut self.address_scan_content);
cb.show_keyboard();
});
});
});
ui.add_space(6.0);
}
return;
}
ui.vertical_centered(|ui| {
let data = wallet.get_data().unwrap();
let amount = amount_to_hr_string(data.info.amount_currently_spendable, true);
@ -634,7 +738,7 @@ impl WalletTransport {
self.modal_just_opened = false;
amount_edit_opts.focus = true;
}
View::text_edit(ui, cb, &mut self.amount_edit, amount_edit_opts);
View::text_edit(ui, cb, &mut self.amount_edit, &mut amount_edit_opts);
ui.add_space(8.0);
// Check value if input was changed.
@ -682,16 +786,23 @@ impl WalletTransport {
.color(Colors::GRAY));
}
});
ui.add_space(8.0);
ui.add_space(6.0);
// Draw address text edit.
let addr_edit_before = self.address_edit.clone();
let address_edit_id = Id::from(modal.id).with("address").with(wallet.get_config().id);
let address_edit_opts = TextEditOptions::new(address_edit_id)
let mut address_edit_opts = TextEditOptions::new(address_edit_id)
.paste()
.scan_qr()
.no_focus();
View::text_edit(ui, cb, &mut self.address_edit, address_edit_opts);
.no_focus()
.scan_qr();
View::text_edit(ui, cb, &mut self.address_edit, &mut address_edit_opts);
// Check if scan button was pressed.
if address_edit_opts.scan_pressed {
cb.hide_keyboard();
modal.disable_closing();
address_edit_opts.scan_pressed = false;
self.show_address_scan = true;
}
ui.add_space(12.0);
// Check value if input was changed.