mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-20 05:38:55 +00:00
feat: software keyboard (without language switch)
This commit is contained in:
+16
-3
@@ -21,7 +21,7 @@ use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROWS_IN, ARROWS_OUT, CARET_DOWN, MOON, SUN, X};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Content, Modal, TitlePanel, View};
|
||||
use crate::gui::views::{Content, KeyboardContent, Modal, TitlePanel, View};
|
||||
use crate::wallet::ExternalConnection;
|
||||
|
||||
lazy_static! {
|
||||
@@ -33,8 +33,12 @@ lazy_static! {
|
||||
pub struct App<Platform> {
|
||||
/// Handles platform-specific functionality.
|
||||
pub platform: Platform,
|
||||
|
||||
/// Main content.
|
||||
content: Content,
|
||||
/// Keyboard content.
|
||||
keyboard_content: KeyboardContent,
|
||||
|
||||
/// Last window resize direction.
|
||||
resize_direction: Option<ResizeDirection>,
|
||||
/// Flag to check if it's first draw.
|
||||
@@ -46,6 +50,7 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
Self {
|
||||
platform,
|
||||
content: Content::default(),
|
||||
keyboard_content: KeyboardContent::default(),
|
||||
resize_direction: None,
|
||||
first_draw: true
|
||||
}
|
||||
@@ -73,7 +78,12 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
// Handle Esc keyboard key event and platform Back button key event.
|
||||
let back_pressed = BACK_BUTTON_PRESSED.load(Ordering::Relaxed);
|
||||
if back_pressed || ctx.input_mut(|i| i.consume_key(Modifiers::NONE, egui::Key::Escape)) {
|
||||
self.content.on_back(&self.platform);
|
||||
// Hide keyboard or pass event to content.
|
||||
if KeyboardContent::showing() {
|
||||
KeyboardContent::hide();
|
||||
} else {
|
||||
self.content.on_back(&self.platform);
|
||||
}
|
||||
if back_pressed {
|
||||
BACK_BUTTON_PRESSED.store(false, Ordering::Relaxed);
|
||||
}
|
||||
@@ -128,10 +138,13 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
self.content.ui(ui, &self.platform);
|
||||
}
|
||||
|
||||
// Show soft keyboard content.
|
||||
self.keyboard_content.ui(ctx);
|
||||
|
||||
// Provide incoming data to wallets.
|
||||
if let Some(data) = crate::consume_incoming_data() {
|
||||
if !data.is_empty() {
|
||||
self.content.wallets.on_data(ui, Some(data), &self.platform);
|
||||
self.content.wallets.on_data(ui, Some(data));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -70,20 +70,6 @@ impl PlatformCallbacks for Android {
|
||||
let _ = self.call_java_method("exit", "()V", &[]);
|
||||
}
|
||||
|
||||
fn show_keyboard(&self) {
|
||||
// Disable NDK soft input show call before fix for egui.
|
||||
// self.android_app.show_soft_input(false);
|
||||
|
||||
let _ = self.call_java_method("showKeyboard", "()V", &[]);
|
||||
}
|
||||
|
||||
fn hide_keyboard(&self) {
|
||||
// Disable NDK soft input hide call before fix for egui.
|
||||
// self.android_app.hide_soft_input(false);
|
||||
|
||||
let _ = self.call_java_method("hideKeyboard", "()V", &[]);
|
||||
}
|
||||
|
||||
fn copy_string_to_buffer(&self, data: String) {
|
||||
let vm = unsafe { jni::JavaVM::from_raw(self.android_app.vm_as_ptr() as _) }.unwrap();
|
||||
let env = vm.attach_current_thread().unwrap();
|
||||
|
||||
@@ -180,10 +180,6 @@ impl PlatformCallbacks for Desktop {
|
||||
}
|
||||
}
|
||||
|
||||
fn show_keyboard(&self) {}
|
||||
|
||||
fn hide_keyboard(&self) {}
|
||||
|
||||
fn copy_string_to_buffer(&self, data: String) {
|
||||
let mut clipboard = arboard::Clipboard::new().unwrap();
|
||||
clipboard.set_text(data).unwrap();
|
||||
|
||||
@@ -24,8 +24,6 @@ pub mod platform;
|
||||
pub trait PlatformCallbacks {
|
||||
fn set_context(&mut self, ctx: &egui::Context);
|
||||
fn exit(&self);
|
||||
fn show_keyboard(&self);
|
||||
fn hide_keyboard(&self);
|
||||
fn copy_string_to_buffer(&self, data: String);
|
||||
fn get_string_from_buffer(&self) -> String;
|
||||
fn start_camera(&self);
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
// Copyright 2025 The Grim Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use eframe::emath::Align;
|
||||
use eframe::epaint::{Margin, Shadow};
|
||||
use egui::{Align2, Button, Color32, CursorIcon, Layout, Rect, Response, RichText, Stroke, Vec2, Widget};
|
||||
use parking_lot::RwLock;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROW_FAT_UP, BACKSPACE, KEY_RETURN, TRANSLATE};
|
||||
use crate::gui::views::View;
|
||||
|
||||
lazy_static! {
|
||||
/// Last input from software keyboard.
|
||||
static ref LAST_INPUT: Arc<RwLock<Option<KeyboardInput>>> = Arc::new(RwLock::new(None));
|
||||
/// Flag to show software keyboard.
|
||||
static ref SHOW_KEYBOARD: AtomicBool = AtomicBool::new(false);
|
||||
/// Flag to show English layout at keyboard.
|
||||
static ref ENG_KEYBOARD: AtomicBool = AtomicBool::new(false);
|
||||
}
|
||||
|
||||
/// Software keyboard input.
|
||||
#[derive(Clone)]
|
||||
pub enum KeyboardInput {
|
||||
TEXT(String), CLEAR, ENTER
|
||||
}
|
||||
|
||||
/// Software keyboard content.
|
||||
pub struct KeyboardContent {
|
||||
/// Flag to check if uppercase text entering is enabled.
|
||||
uppercase: bool,
|
||||
/// Flag to show symbols layout.
|
||||
symbols: bool,
|
||||
}
|
||||
|
||||
impl Default for KeyboardContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
uppercase: false,
|
||||
symbols: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardContent {
|
||||
/// Maximum keyboard content width.
|
||||
const MAX_WIDTH: f32 = 600.0;
|
||||
/// Buttons content margin.
|
||||
const MARGIN: f32 = 5.0;
|
||||
|
||||
/// Draw keyboard content.
|
||||
pub fn ui(&mut self, ctx: &egui::Context) {
|
||||
if !KeyboardContent::showing() {
|
||||
return;
|
||||
}
|
||||
let width = ctx.screen_rect().width();
|
||||
let layer_id = egui::Window::new("soft_keyboard")
|
||||
.title_bar(false)
|
||||
.resizable(false)
|
||||
.collapsible(false)
|
||||
.min_width(width)
|
||||
.default_width(width)
|
||||
.anchor(Align2::CENTER_BOTTOM, Vec2::new(0.0, 0.0))
|
||||
.frame(egui::Frame {
|
||||
shadow: Shadow {
|
||||
offset: Default::default(),
|
||||
blur: 30.0,
|
||||
spread: 3.0,
|
||||
color: egui::Color32::from_black_alpha(32),
|
||||
},
|
||||
inner_margin: Margin {
|
||||
left: View::get_left_inset() + Self::MARGIN,
|
||||
right: View::get_right_inset() + Self::MARGIN,
|
||||
top: Self::MARGIN,
|
||||
bottom: View::get_bottom_inset() + Self::MARGIN,
|
||||
},
|
||||
fill: Colors::fill(),
|
||||
..Default::default()
|
||||
})
|
||||
.show(ctx, |ui| {
|
||||
ui.set_min_width(width);
|
||||
// Calculate content width.
|
||||
let side_insets = View::get_left_inset() + View::get_right_inset();
|
||||
let available_width = width - (side_insets + Self::MARGIN * 2.0);
|
||||
let w = f32::min(available_width, Self::MAX_WIDTH);
|
||||
View::max_width_ui(ui, w, |ui| {
|
||||
// Setup spacing between buttons.
|
||||
ui.style_mut().spacing.item_spacing = egui::vec2(Self::MARGIN, 0.0);
|
||||
// Setup vertical padding inside buttons.
|
||||
ui.style_mut().spacing.button_padding = egui::vec2(Self::MARGIN, 8.0);
|
||||
|
||||
let button_rect = if self.symbols {
|
||||
self.symbols_ui(ui)
|
||||
} else {
|
||||
self.text_ui(ui)
|
||||
};
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
// Draw bottom keyboard buttons.
|
||||
let bottom_size = {
|
||||
let mut r = button_rect.clone();
|
||||
r.set_width(ui.available_width());
|
||||
r.size()
|
||||
};
|
||||
let button_width = button_rect.width();
|
||||
ui.allocate_ui_with_layout(bottom_size, Layout::right_to_left(Align::Max), |ui| {
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width * 2.0 + Self::MARGIN);
|
||||
self.button_ui(KEY_RETURN,
|
||||
Colors::white_or_black(false),
|
||||
Some(Colors::green()),
|
||||
ui,
|
||||
|_| {
|
||||
Self::on_input(KeyboardInput::ENTER);
|
||||
});
|
||||
});
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width * 5.0 + 4.0 * Self::MARGIN);
|
||||
self.button_ui(" ", Colors::inactive_text(), None, ui, |l| {
|
||||
Self::on_input(KeyboardInput::TEXT(l));
|
||||
});
|
||||
});
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width);
|
||||
self.button_ui(TRANSLATE,
|
||||
Colors::text_button(),
|
||||
Some(Colors::fill_lite()),
|
||||
ui,
|
||||
|_| {
|
||||
let eng_keyboard = ENG_KEYBOARD.load(Ordering::Relaxed);
|
||||
ENG_KEYBOARD.store(!eng_keyboard, Ordering::Relaxed);
|
||||
});
|
||||
});
|
||||
ui.horizontal_centered(|ui| {
|
||||
let label = if self.symbols {
|
||||
"ABC"
|
||||
} else {
|
||||
"?/ツ"
|
||||
};
|
||||
let mut symbols = self.symbols;
|
||||
self.button_ui(label, Colors::text_button(), Some(Colors::fill_lite()), ui, |_| {
|
||||
symbols = !self.symbols;
|
||||
});
|
||||
self.symbols = symbols;
|
||||
});
|
||||
});
|
||||
});
|
||||
}).unwrap().response.layer_id;
|
||||
|
||||
// Always show keyboard above others windows.
|
||||
ctx.move_to_top(layer_id);
|
||||
}
|
||||
|
||||
/// Draw text content returning button [`Rect`].
|
||||
fn text_ui(&mut self, ui: &mut egui::Ui) -> Rect {
|
||||
let mut button_rect = ui.available_rect_before_wrap();
|
||||
let tl_0: Vec<&str> = vec!["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
|
||||
ui.columns(tl_0.len(), |columns| {
|
||||
for (index, s) in tl_0.iter().enumerate() {
|
||||
button_rect = self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
let tl_1: Vec<&str> = vec!["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"];
|
||||
ui.columns(tl_1.len(), |columns| {
|
||||
for (index, s) in tl_1.iter().enumerate() {
|
||||
self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
let tl_2: Vec<&str> = vec!["a", "s", "d", "f", "g", "h", "j", "k", "l", ":"];
|
||||
ui.columns(tl_2.len(), |columns| {
|
||||
for (index, s) in tl_2.iter().enumerate() {
|
||||
self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
let tl_3: Vec<&str> = vec![ARROW_FAT_UP, "z", "x", "c", "v", "b", "n", "m", ".", BACKSPACE];
|
||||
ui.columns(tl_3.len(), |columns| {
|
||||
for (index, s) in tl_3.iter().enumerate() {
|
||||
if index == 0 {
|
||||
// Check for shift input.
|
||||
let color = if self.uppercase {
|
||||
Colors::yellow_dark()
|
||||
} else {
|
||||
Colors::inactive_text()
|
||||
};
|
||||
let mut uppercase = self.uppercase;
|
||||
self.button_ui(s, color, Some(Colors::fill_lite()), &mut columns[index], |_| {
|
||||
uppercase = !uppercase;
|
||||
});
|
||||
self.uppercase = uppercase;
|
||||
} else if index == tl_3.len() - 1 {
|
||||
// Check for backspace input.
|
||||
self.button_ui(s,
|
||||
Colors::red(),
|
||||
Some(Colors::fill_lite()),
|
||||
&mut columns[index],
|
||||
|_| {
|
||||
Self::on_input(KeyboardInput::CLEAR);
|
||||
});
|
||||
} else {
|
||||
self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
}
|
||||
});
|
||||
button_rect
|
||||
}
|
||||
|
||||
/// Draw symbols content returning button [`Rect`].
|
||||
fn symbols_ui(&mut self, ui: &mut egui::Ui) -> Rect {
|
||||
let mut button_rect = ui.available_rect_before_wrap();
|
||||
let tl_0: Vec<&str> = vec!["[", "]", "{", "}", "#", "%", "^", "*", "+", "="];
|
||||
ui.columns(tl_0.len(), |columns| {
|
||||
for (index, s) in tl_0.iter().enumerate() {
|
||||
button_rect = self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
let tl_1: Vec<&str> = vec!["_", "\\", "|", "~", "<", ">", "`", "√", "π", "•"];
|
||||
ui.columns(tl_1.len(), |columns| {
|
||||
for (index, s) in tl_1.iter().enumerate() {
|
||||
self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
let tl_2: Vec<&str> = vec!["-", "/", ":", ";", "(", ")", "$", "&", "@", "\""];
|
||||
ui.columns(tl_2.len(), |columns| {
|
||||
for (index, s) in tl_2.iter().enumerate() {
|
||||
self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
|
||||
let tl_3: Vec<&str> = vec![".", ",", "?", "!", "€", "£", "¥", "¢", "ツ", BACKSPACE];
|
||||
ui.columns(tl_3.len(), |columns| {
|
||||
for (index, s) in tl_3.iter().enumerate() {
|
||||
if index == tl_3.len() - 1 {
|
||||
// Check for backspace input.
|
||||
self.button_ui(s,
|
||||
Colors::red(),
|
||||
Some(Colors::fill_lite()),
|
||||
&mut columns[index], |_| {
|
||||
Self::on_input(KeyboardInput::CLEAR);
|
||||
});
|
||||
} else {
|
||||
self.input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
button_rect
|
||||
}
|
||||
|
||||
/// Draw keyboard button.
|
||||
fn button_ui(&self,
|
||||
s: &str,
|
||||
color: Color32,
|
||||
bg: Option<Color32>,
|
||||
ui: &mut egui::Ui,
|
||||
mut cb: impl FnMut(String)) -> Response {
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
// Disable expansion on click/hover.
|
||||
ui.style_mut().visuals.widgets.hovered.expansion = 0.0;
|
||||
ui.style_mut().visuals.widgets.active.expansion = 0.0;
|
||||
// Setup fill colors.
|
||||
ui.visuals_mut().widgets.inactive.weak_bg_fill = Colors::white_or_black(false);
|
||||
ui.visuals_mut().widgets.hovered.weak_bg_fill = Colors::fill_lite();
|
||||
ui.visuals_mut().widgets.active.weak_bg_fill = Colors::fill();
|
||||
// Setup stroke colors.
|
||||
ui.visuals_mut().widgets.inactive.bg_stroke = View::item_stroke();
|
||||
ui.visuals_mut().widgets.hovered.bg_stroke = View::hover_stroke();
|
||||
ui.visuals_mut().widgets.active.bg_stroke = Stroke::NONE;
|
||||
|
||||
let label = if self.uppercase {
|
||||
s.to_uppercase()
|
||||
} else {
|
||||
s.to_string()
|
||||
};
|
||||
let mut button = Button::new(RichText::new(label.clone()).size(17.0).color(color));
|
||||
if let Some(bg) = bg {
|
||||
button = button.fill(bg);
|
||||
}
|
||||
let resp = button.ui(ui).on_hover_cursor(CursorIcon::PointingHand);
|
||||
if resp.clicked() {
|
||||
(cb)(label);
|
||||
}
|
||||
}).response
|
||||
}
|
||||
|
||||
/// Draw input button.
|
||||
fn input_button_ui(&mut self, s: &str, ui: &mut egui::Ui) -> Rect {
|
||||
let mut input = false;
|
||||
let rect = self.button_ui(s, Colors::text_button(), None, ui, |l| {
|
||||
input = true;
|
||||
Self::on_input(KeyboardInput::TEXT(l));
|
||||
}).rect;
|
||||
if input {
|
||||
self.uppercase = false;
|
||||
}
|
||||
rect
|
||||
}
|
||||
|
||||
/// Save keyboard action to consume later.
|
||||
fn on_input(action: KeyboardInput) {
|
||||
let mut w_input = LAST_INPUT.write();
|
||||
*w_input = Some(action);
|
||||
}
|
||||
|
||||
/// Check last keyboard input action.
|
||||
pub fn consume_action() -> Option<KeyboardInput> {
|
||||
let empty = {
|
||||
let r_input = LAST_INPUT.read();
|
||||
r_input.is_none()
|
||||
};
|
||||
if !empty {
|
||||
let mut w_input = LAST_INPUT.write();
|
||||
let res = w_input.clone();
|
||||
*w_input = None;
|
||||
return res;
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Check if keyboard is showing.
|
||||
pub fn showing() -> bool {
|
||||
SHOW_KEYBOARD.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Show keyboard.
|
||||
pub fn show() {
|
||||
SHOW_KEYBOARD.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Hide keyboard.
|
||||
pub fn hide() {
|
||||
SHOW_KEYBOARD.store(false, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
@@ -43,4 +43,7 @@ mod pull_to_refresh;
|
||||
pub use pull_to_refresh::*;
|
||||
|
||||
mod scan;
|
||||
pub use scan::*;
|
||||
pub use scan::*;
|
||||
|
||||
mod keyboard;
|
||||
pub use keyboard::*;
|
||||
@@ -21,7 +21,7 @@ use egui::epaint::{RectShape, Shadow};
|
||||
use egui::os::OperatingSystem;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::views::{Content, View};
|
||||
use crate::gui::views::{Content, KeyboardContent, View};
|
||||
use crate::gui::views::types::{ModalPosition, ModalState};
|
||||
|
||||
lazy_static! {
|
||||
@@ -70,10 +70,12 @@ impl Modal {
|
||||
w_state.modal.as_mut().unwrap().position = position;
|
||||
}
|
||||
|
||||
/// Mark [`Modal`] closed.
|
||||
/// Close [`Modal`] by clearing its state..
|
||||
pub fn close(&self) {
|
||||
let mut w_nav = MODAL_STATE.write();
|
||||
w_nav.modal = None;
|
||||
// Hide keyboard.
|
||||
KeyboardContent::hide();
|
||||
}
|
||||
|
||||
/// Setup possibility to close [`Modal`].
|
||||
|
||||
@@ -96,7 +96,7 @@ impl ConnectionsContent {
|
||||
// Show button to add new external node connection.
|
||||
let add_node_text = format!("{} {}", PLUS_CIRCLE, t!("wallets.add_node"));
|
||||
View::button(ui, add_node_text, Colors::white_or_black(false), || {
|
||||
self.show_add_ext_conn_modal(None, cb);
|
||||
self.show_add_ext_conn_modal(None);
|
||||
});
|
||||
|
||||
ui.add_space(4.0);
|
||||
@@ -114,7 +114,7 @@ impl ConnectionsContent {
|
||||
ConnectionsConfig::remove_ext_conn(conn.id);
|
||||
});
|
||||
View::item_button(ui, Rounding::default(), PENCIL, None, || {
|
||||
self.show_add_ext_conn_modal(Some(conn.clone()), cb);
|
||||
self.show_add_ext_conn_modal(Some(conn.clone()));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -234,15 +234,12 @@ impl ConnectionsContent {
|
||||
}
|
||||
|
||||
/// Show [`Modal`] to add external connection.
|
||||
pub fn show_add_ext_conn_modal(&mut self,
|
||||
conn: Option<ExternalConnection>,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
pub fn show_add_ext_conn_modal(&mut self, conn: Option<ExternalConnection>) {
|
||||
self.ext_conn_modal = ExternalConnectionModal::new(conn);
|
||||
// Show modal.
|
||||
Modal::new(ExternalConnectionModal::NETWORK_ID)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.add_node"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,6 @@ impl ExternalConnectionModal {
|
||||
self.ext_node_url_edit = "".to_string();
|
||||
self.ext_node_secret_edit = "".to_string();
|
||||
self.ext_node_url_error = false;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -146,7 +145,6 @@ impl ExternalConnectionModal {
|
||||
self.ext_node_url_edit = "".to_string();
|
||||
self.ext_node_secret_edit = "".to_string();
|
||||
self.ext_node_url_error = false;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -96,28 +96,28 @@ impl DandelionSetup {
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
// Show epoch duration setup.
|
||||
self.epoch_ui(ui, cb);
|
||||
self.epoch_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show embargo expiration time setup.
|
||||
self.embargo_ui(ui, cb);
|
||||
self.embargo_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show aggregation period setup.
|
||||
self.aggregation_ui(ui, cb);
|
||||
self.aggregation_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show Stem phase probability setup.
|
||||
self.stem_prob_ui(ui, cb);
|
||||
self.stem_prob_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -133,7 +133,7 @@ impl DandelionSetup {
|
||||
}
|
||||
|
||||
/// Draw epoch duration setup content.
|
||||
fn epoch_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn epoch_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.epoch_duration"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -149,7 +149,6 @@ impl DandelionSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -188,7 +187,6 @@ impl DandelionSetup {
|
||||
let on_save = || {
|
||||
if let Ok(epoch) = self.epoch_edit.parse::<u16>() {
|
||||
NodeConfig::save_dandelion_epoch(epoch);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -202,7 +200,6 @@ impl DandelionSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -215,7 +212,7 @@ impl DandelionSetup {
|
||||
}
|
||||
|
||||
/// Draw embargo expiration time setup content.
|
||||
fn embargo_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn embargo_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.embargo_timer"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -230,7 +227,6 @@ impl DandelionSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -269,7 +265,6 @@ impl DandelionSetup {
|
||||
let on_save = || {
|
||||
if let Ok(embargo) = self.embargo_edit.parse::<u16>() {
|
||||
NodeConfig::save_dandelion_embargo(embargo);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -283,7 +278,6 @@ impl DandelionSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -296,7 +290,7 @@ impl DandelionSetup {
|
||||
}
|
||||
|
||||
/// Draw aggregation period setup content.
|
||||
fn aggregation_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn aggregation_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.aggregation_period"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -312,7 +306,6 @@ impl DandelionSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -351,7 +344,6 @@ impl DandelionSetup {
|
||||
let on_save = || {
|
||||
if let Ok(embargo) = self.aggregation_edit.parse::<u16>() {
|
||||
NodeConfig::save_dandelion_aggregation(embargo);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -365,7 +357,6 @@ impl DandelionSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -378,7 +369,7 @@ impl DandelionSetup {
|
||||
}
|
||||
|
||||
/// Draw stem phase probability setup content.
|
||||
fn stem_prob_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn stem_prob_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.stem_probability"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -394,7 +385,6 @@ impl DandelionSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -433,7 +423,6 @@ impl DandelionSetup {
|
||||
let on_save = || {
|
||||
if let Ok(prob) = self.stem_prob_edit.parse::<u8>() {
|
||||
NodeConfig::save_stem_probability(prob);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -447,7 +436,6 @@ impl DandelionSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -185,12 +185,12 @@ impl NodeSetup {
|
||||
NodeConfig::save_api_address(selected_ip, &api_port);
|
||||
});
|
||||
// Show API port setup.
|
||||
self.api_port_setup_ui(ui, cb);
|
||||
self.api_port_setup_ui(ui);
|
||||
// Show API secret setup.
|
||||
self.secret_ui(API_SECRET_MODAL, ui, cb);
|
||||
self.secret_ui(API_SECRET_MODAL, ui);
|
||||
ui.add_space(12.0);
|
||||
// Show Foreign API secret setup.
|
||||
self.secret_ui(FOREIGN_API_SECRET_MODAL, ui, cb);
|
||||
self.secret_ui(FOREIGN_API_SECRET_MODAL, ui);
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
@@ -201,7 +201,7 @@ impl NodeSetup {
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
// Show FTL setup.
|
||||
self.ftl_ui(ui, cb);
|
||||
self.ftl_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -250,7 +250,7 @@ impl NodeSetup {
|
||||
}
|
||||
|
||||
/// Draw API port setup content.
|
||||
fn api_port_setup_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn api_port_setup_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.api_port")).size(16.0).color(Colors::gray()));
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -265,7 +265,6 @@ impl NodeSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -325,7 +324,6 @@ impl NodeSetup {
|
||||
}
|
||||
|
||||
self.is_api_port_available = true;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -338,7 +336,6 @@ impl NodeSetup {
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -351,7 +348,7 @@ impl NodeSetup {
|
||||
}
|
||||
|
||||
/// Draw API secret token setup content.
|
||||
fn secret_ui(&mut self, modal_id: &'static str, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn secret_ui(&mut self, modal_id: &'static str, ui: &mut egui::Ui) {
|
||||
let secret_title = match modal_id {
|
||||
API_SECRET_MODAL => t!("network_settings.api_secret"),
|
||||
_ => t!("network_settings.foreign_api_secret")
|
||||
@@ -381,7 +378,6 @@ impl NodeSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -428,7 +424,6 @@ impl NodeSetup {
|
||||
NodeConfig::save_foreign_api_secret(&secret);
|
||||
}
|
||||
};
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
};
|
||||
|
||||
@@ -440,7 +435,6 @@ impl NodeSetup {
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -453,7 +447,7 @@ impl NodeSetup {
|
||||
}
|
||||
|
||||
/// Draw FTL setup content.
|
||||
fn ftl_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn ftl_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.ftl"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -471,7 +465,6 @@ impl NodeSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
ui.label(RichText::new(t!("network_settings.ftl_description"))
|
||||
@@ -514,7 +507,6 @@ impl NodeSetup {
|
||||
let on_save = || {
|
||||
if let Ok(ftl) = self.ftl_edit.parse::<u64>() {
|
||||
NodeConfig::save_ftl(ftl);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -528,7 +520,6 @@ impl NodeSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -162,14 +162,14 @@ impl P2PSetup {
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
// Show p2p port setup.
|
||||
self.port_ui(ui, cb);
|
||||
self.port_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show seeding type setup.
|
||||
self.seeding_type_ui(ui, cb);
|
||||
self.seeding_type_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -180,7 +180,7 @@ impl P2PSetup {
|
||||
.color(Colors::gray()));
|
||||
ui.add_space(6.0);
|
||||
// Show allowed peers setup.
|
||||
self.peer_list_ui(ui, &PeerType::Allowed, cb);
|
||||
self.peer_list_ui(ui, &PeerType::Allowed);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -191,7 +191,7 @@ impl P2PSetup {
|
||||
.color(Colors::gray()));
|
||||
ui.add_space(6.0);
|
||||
// Show denied peers setup.
|
||||
self.peer_list_ui(ui, &PeerType::Denied, cb);
|
||||
self.peer_list_ui(ui, &PeerType::Denied);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -202,7 +202,7 @@ impl P2PSetup {
|
||||
.color(Colors::gray()));
|
||||
ui.add_space(6.0);
|
||||
// Show preferred peers setup.
|
||||
self.peer_list_ui(ui, &PeerType::Preferred, cb);
|
||||
self.peer_list_ui(ui, &PeerType::Preferred);
|
||||
|
||||
|
||||
ui.add_space(6.0);
|
||||
@@ -210,21 +210,21 @@ impl P2PSetup {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show ban window setup.
|
||||
self.ban_window_ui(ui, cb);
|
||||
self.ban_window_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show maximum inbound peers value setup.
|
||||
self.max_inbound_ui(ui, cb);
|
||||
self.max_inbound_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show maximum outbound peers value setup.
|
||||
self.max_outbound_ui(ui, cb);
|
||||
self.max_outbound_ui(ui);
|
||||
|
||||
if !Node::is_restarting() && !self.peers_reset {
|
||||
ui.add_space(6.0);
|
||||
@@ -238,7 +238,7 @@ impl P2PSetup {
|
||||
}
|
||||
|
||||
/// Draw p2p port setup content.
|
||||
fn port_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn port_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.p2p_port"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -257,7 +257,6 @@ impl P2PSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -312,7 +311,6 @@ impl P2PSetup {
|
||||
Node::restart();
|
||||
}
|
||||
self.is_port_available = true;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -326,7 +324,6 @@ impl P2PSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -340,7 +337,7 @@ impl P2PSetup {
|
||||
}
|
||||
|
||||
/// Draw peer list content based on provided [`PeerType`].
|
||||
fn peer_list_ui(&mut self, ui: &mut egui::Ui, peer_type: &PeerType, cb: &dyn PlatformCallbacks) {
|
||||
fn peer_list_ui(&mut self, ui: &mut egui::Ui, peer_type: &PeerType) {
|
||||
let peers = match peer_type {
|
||||
PeerType::DefaultSeed => {
|
||||
if AppConfig::chain_type() == ChainTypes::Testnet {
|
||||
@@ -409,7 +406,6 @@ impl P2PSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(modal_title)
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
}
|
||||
ui.add_space(6.0);
|
||||
@@ -462,7 +458,6 @@ impl P2PSetup {
|
||||
}
|
||||
|
||||
self.is_port_available = true;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -476,7 +471,6 @@ impl P2PSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -490,7 +484,7 @@ impl P2PSetup {
|
||||
}
|
||||
|
||||
/// Draw seeding type setup content.
|
||||
fn seeding_type_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn seeding_type_ui(&mut self, ui: &mut egui::Ui) {
|
||||
let title = Self::DNS_SEEDS_TITLE;
|
||||
ui.label(RichText::new(title).size(16.0).color(Colors::gray()));
|
||||
ui.add_space(2.0);
|
||||
@@ -506,11 +500,11 @@ impl P2PSetup {
|
||||
} else {
|
||||
PeerType::CustomSeed
|
||||
};
|
||||
self.peer_list_ui(ui, &peers_type, cb);
|
||||
self.peer_list_ui(ui, &peers_type);
|
||||
}
|
||||
|
||||
/// Draw ban window setup content.
|
||||
fn ban_window_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn ban_window_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.ban_window"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -528,7 +522,6 @@ impl P2PSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
ui.label(RichText::new(t!("network_settings.ban_window_desc"))
|
||||
@@ -572,7 +565,6 @@ impl P2PSetup {
|
||||
let on_save = || {
|
||||
if let Ok(ban_window) = self.ban_window_edit.parse::<i64>() {
|
||||
NodeConfig::save_p2p_ban_window(ban_window);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -586,7 +578,6 @@ impl P2PSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -599,7 +590,7 @@ impl P2PSetup {
|
||||
}
|
||||
|
||||
/// Draw maximum number of inbound peers setup content.
|
||||
fn max_inbound_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn max_inbound_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.max_inbound_count"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -617,7 +608,6 @@ impl P2PSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -656,7 +646,6 @@ impl P2PSetup {
|
||||
let on_save = || {
|
||||
if let Ok(max_inbound) = self.max_inbound_count.parse::<u32>() {
|
||||
NodeConfig::save_max_inbound_peers(max_inbound);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -670,7 +659,6 @@ impl P2PSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -683,7 +671,7 @@ impl P2PSetup {
|
||||
}
|
||||
|
||||
/// Draw maximum number of outbound peers setup content.
|
||||
fn max_outbound_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn max_outbound_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.max_outbound_count"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -700,7 +688,6 @@ impl P2PSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -739,7 +726,6 @@ impl P2PSetup {
|
||||
let on_save = || {
|
||||
if let Ok(max_outbound) = self.max_outbound_count.parse::<u32>() {
|
||||
NodeConfig::save_max_outbound_peers(max_outbound);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -753,7 +739,6 @@ impl P2PSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -104,40 +104,40 @@ impl PoolSetup {
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
// Show base fee setup.
|
||||
self.fee_base_ui(ui, cb);
|
||||
self.fee_base_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show reorg cache retention period setup.
|
||||
self.reorg_period_ui(ui, cb);
|
||||
self.reorg_period_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show pool size setup.
|
||||
self.pool_size_ui(ui, cb);
|
||||
self.pool_size_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show stem pool size setup.
|
||||
self.stem_size_ui(ui, cb);
|
||||
self.stem_size_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show max weight of transactions setup.
|
||||
self.max_weight_ui(ui, cb);
|
||||
self.max_weight_ui(ui);
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw fee base setup content.
|
||||
fn fee_base_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn fee_base_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.pool_fee"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -153,7 +153,6 @@ impl PoolSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -191,7 +190,6 @@ impl PoolSetup {
|
||||
let on_save = || {
|
||||
if let Ok(fee) = self.fee_base_edit.parse::<u64>() {
|
||||
NodeConfig::save_base_fee(fee);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -205,7 +203,6 @@ impl PoolSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -219,7 +216,7 @@ impl PoolSetup {
|
||||
}
|
||||
|
||||
/// Draw reorg cache retention period setup content.
|
||||
fn reorg_period_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn reorg_period_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.reorg_period"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -236,7 +233,6 @@ impl PoolSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -274,7 +270,6 @@ impl PoolSetup {
|
||||
let on_save = || {
|
||||
if let Ok(period) = self.reorg_period_edit.parse::<u32>() {
|
||||
NodeConfig::save_reorg_cache_period(period);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -288,7 +283,6 @@ impl PoolSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -302,7 +296,7 @@ impl PoolSetup {
|
||||
}
|
||||
|
||||
/// Draw maximum number of transactions in the pool setup content.
|
||||
fn pool_size_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn pool_size_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.max_tx_pool"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -318,7 +312,6 @@ impl PoolSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -356,7 +349,6 @@ impl PoolSetup {
|
||||
let on_save = || {
|
||||
if let Ok(size) = self.pool_size_edit.parse::<usize>() {
|
||||
NodeConfig::save_max_pool_size(size);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -370,7 +362,6 @@ impl PoolSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -384,7 +375,7 @@ impl PoolSetup {
|
||||
}
|
||||
|
||||
/// Draw maximum number of transactions in the stempool setup content.
|
||||
fn stem_size_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn stem_size_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.max_tx_stempool"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -402,7 +393,6 @@ impl PoolSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -440,7 +430,6 @@ impl PoolSetup {
|
||||
let on_save = || {
|
||||
if let Ok(size) = self.stempool_size_edit.parse::<usize>() {
|
||||
NodeConfig::save_max_stempool_size(size);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -454,7 +443,6 @@ impl PoolSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -468,7 +456,7 @@ impl PoolSetup {
|
||||
}
|
||||
|
||||
/// Draw maximum total weight of transactions setup content.
|
||||
fn max_weight_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn max_weight_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.max_tx_weight"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -486,7 +474,6 @@ impl PoolSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -524,7 +511,6 @@ impl PoolSetup {
|
||||
let on_save = || {
|
||||
if let Ok(weight) = self.max_weight_edit.parse::<u64>() {
|
||||
NodeConfig::save_mineable_max_weight(weight);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -538,7 +524,6 @@ impl PoolSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -227,19 +227,19 @@ impl StratumSetup {
|
||||
|
||||
});
|
||||
// Show stratum port setup.
|
||||
self.port_setup_ui(ui, cb);
|
||||
self.port_setup_ui(ui);
|
||||
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show attempt time setup.
|
||||
self.attempt_time_ui(ui, cb);
|
||||
self.attempt_time_ui(ui);
|
||||
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show minimum acceptable share difficulty setup.
|
||||
self.min_diff_ui(ui, cb);
|
||||
self.min_diff_ui(ui);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ impl StratumSetup {
|
||||
}
|
||||
|
||||
/// Draw stratum port value setup content.
|
||||
fn port_setup_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn port_setup_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.stratum_port"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -271,7 +271,6 @@ impl StratumSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(12.0);
|
||||
|
||||
@@ -330,7 +329,6 @@ impl StratumSetup {
|
||||
NodeConfig::save_stratum_address(&stratum_ip, &self.stratum_port_edit);
|
||||
|
||||
self.is_port_available = true;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -344,7 +342,6 @@ impl StratumSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -358,7 +355,7 @@ impl StratumSetup {
|
||||
}
|
||||
|
||||
/// Draw attempt time value setup content.
|
||||
fn attempt_time_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn attempt_time_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.attempt_time"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -375,7 +372,6 @@ impl StratumSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
ui.label(RichText::new(t!("network_settings.attempt_time_desc"))
|
||||
@@ -419,7 +415,6 @@ impl StratumSetup {
|
||||
let on_save = || {
|
||||
if let Ok(time) = self.attempt_time_edit.parse::<u32>() {
|
||||
NodeConfig::save_stratum_attempt_time(time);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -433,7 +428,6 @@ impl StratumSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -446,7 +440,7 @@ impl StratumSetup {
|
||||
}
|
||||
|
||||
/// Draw minimum share difficulty value setup content.
|
||||
fn min_diff_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn min_diff_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.min_share_diff"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
@@ -463,7 +457,6 @@ impl StratumSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
@@ -502,7 +495,6 @@ impl StratumSetup {
|
||||
let on_save = || {
|
||||
if let Ok(diff) = self.min_share_diff_edit.parse::<u64>() {
|
||||
NodeConfig::save_stratum_min_share_diff(diff);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -516,7 +508,6 @@ impl StratumSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -94,6 +94,8 @@ pub struct TextEditOptions {
|
||||
pub scan_qr: bool,
|
||||
/// Callback when scan button was pressed.
|
||||
pub scan_pressed: bool,
|
||||
/// Callback when Enter key was pressed.
|
||||
pub enter_pressed: bool,
|
||||
}
|
||||
|
||||
impl TextEditOptions {
|
||||
@@ -107,6 +109,7 @@ impl TextEditOptions {
|
||||
paste: false,
|
||||
scan_qr: false,
|
||||
scan_pressed: false,
|
||||
enter_pressed: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+61
-71
@@ -13,8 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::atomic::{AtomicI32, Ordering};
|
||||
use std::sync::Arc;
|
||||
use parking_lot::RwLock;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use egui::{Align, Button, CursorIcon, Layout, lerp, PointerState, Rect, Response, Rgba, RichText, Sense, SizeHint, Spinner, TextBuffer, TextStyle, TextureHandle, TextureOptions, Widget, UiBuilder};
|
||||
@@ -30,6 +28,7 @@ use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{CHECK_SQUARE, CLIPBOARD_TEXT, COPY, EYE, EYE_SLASH, SCAN, SQUARE};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{KeyboardContent, KeyboardInput};
|
||||
use crate::gui::views::types::{LinePosition, TextEditOptions};
|
||||
|
||||
pub struct View;
|
||||
@@ -450,59 +449,80 @@ impl View {
|
||||
.password(show_pass)
|
||||
.cursor_at_end(true)
|
||||
.ui(ui);
|
||||
// Show keyboard on click.
|
||||
if text_edit_resp.clicked() {
|
||||
text_edit_resp.request_focus();
|
||||
cb.show_keyboard();
|
||||
// Store focusing state on click or from options.
|
||||
let focus_id = egui::Id::new("focused_input");
|
||||
if text_edit_resp.clicked() || options.focus {
|
||||
ui.data_mut(|data| {
|
||||
data.insert_temp(focus_id, options.id);
|
||||
});
|
||||
}
|
||||
// Setup focus on input field.
|
||||
if options.focus {
|
||||
let focus = ui.data(|data| {
|
||||
data.get_temp(focus_id)
|
||||
}).unwrap_or(egui::Id::from(""));
|
||||
if focus == options.id {
|
||||
text_edit_resp.request_focus();
|
||||
cb.show_keyboard();
|
||||
KeyboardContent::show();
|
||||
}
|
||||
|
||||
// Apply text from input on Android as temporary fix for egui.
|
||||
// Apply text from software input.
|
||||
if text_edit_resp.has_focus() {
|
||||
Self::on_soft_input(ui, options.id, value);
|
||||
options.focus = true;
|
||||
options.enter_pressed = Self::on_soft_input(ui, options.id, false, value);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Apply soft keyboard input data to provided 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();
|
||||
|
||||
if !w_input.is_empty() {
|
||||
let mut state = TextEditState::load(ui.ctx(), id).unwrap();
|
||||
match state.cursor.char_range() {
|
||||
None => {}
|
||||
Some(range) => {
|
||||
let mut r = range.clone();
|
||||
|
||||
let mut index = r.primary.index;
|
||||
|
||||
value.insert_text(w_input.as_str(), index);
|
||||
index = index + 1;
|
||||
|
||||
if index == 0 {
|
||||
r.primary.index = value.len();
|
||||
r.secondary.index = r.primary.index;
|
||||
} else {
|
||||
r.primary.index = index;
|
||||
r.secondary.index = r.primary.index;
|
||||
/// Apply soft keyboard input data to provided String, returns `true` if Enter was pressed.
|
||||
fn on_soft_input(ui: &mut egui::Ui, id: egui::Id, multiline: bool, value: &mut String) -> bool {
|
||||
if let Some(input) = KeyboardContent::consume_action() {
|
||||
let mut enter_pressed = false;
|
||||
let mut state = TextEditState::load(ui.ctx(), id).unwrap();
|
||||
match state.cursor.char_range() {
|
||||
None => {}
|
||||
Some(range) => {
|
||||
let mut r = range.clone();
|
||||
let mut index = r.primary.index;
|
||||
match input {
|
||||
KeyboardInput::TEXT(text) => {
|
||||
value.insert_text(text.as_str(), index);
|
||||
index = index + 1;
|
||||
}
|
||||
KeyboardInput::CLEAR => {
|
||||
if index != 0 {
|
||||
*value = {
|
||||
let part1: String = value.chars()
|
||||
.skip(0)
|
||||
.take(index - 1)
|
||||
.collect();
|
||||
let part2: String = value.chars()
|
||||
.skip(index)
|
||||
.take(value.len() - index)
|
||||
.collect();
|
||||
format!("{}{}", part1, part2)
|
||||
};
|
||||
index = index - 1;
|
||||
}
|
||||
}
|
||||
KeyboardInput::ENTER => {
|
||||
if multiline {
|
||||
value.insert_text("\n", index);
|
||||
index = index + 1;
|
||||
} else {
|
||||
enter_pressed = true;
|
||||
}
|
||||
}
|
||||
state.cursor.set_char_range(Some(r));
|
||||
TextEditState::store(state, ui.ctx(), id);
|
||||
}
|
||||
// Setup cursor index.
|
||||
r.primary.index = index;
|
||||
r.secondary.index = r.primary.index;
|
||||
|
||||
state.cursor.set_char_range(Some(r));
|
||||
TextEditState::store(state, ui.ctx(), id);
|
||||
}
|
||||
}
|
||||
|
||||
*w_input = "".to_string();
|
||||
ui.ctx().request_repaint();
|
||||
return enter_pressed;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Calculate item background/button rounding based on item index.
|
||||
@@ -806,34 +826,4 @@ pub extern "C" fn Java_mw_gri_android_MainActivity_onDisplayInsets(
|
||||
RIGHT_DISPLAY_INSET.store(array[1], Ordering::Relaxed);
|
||||
BOTTOM_DISPLAY_INSET.store(array[2], Ordering::Relaxed);
|
||||
LEFT_DISPLAY_INSET.store(array[3], Ordering::Relaxed);
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref LAST_SOFT_KEYBOARD_INPUT: Arc<RwLock<String>> = Arc::new(RwLock::new("".into()));
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
/// Callback from Java code with last entered character from soft keyboard.
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onInput(
|
||||
_env: jni::JNIEnv,
|
||||
_class: jni::objects::JObject,
|
||||
char: jni::sys::jstring
|
||||
) {
|
||||
use jni::objects::JString;
|
||||
use std::ops::Add;
|
||||
|
||||
unsafe {
|
||||
let j_obj = JString::from_raw(char);
|
||||
let j_str = _env.get_string_unchecked(j_obj.as_ref()).unwrap();
|
||||
match j_str.to_str() {
|
||||
Ok(str) => {
|
||||
let mut w_input = LAST_SOFT_KEYBOARD_INPUT.write();
|
||||
*w_input = w_input.clone().add(str);
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ impl WalletsContent {
|
||||
ui.vertical_centered(|ui| {
|
||||
let pressed = Modal::opened() == Some(ADD_WALLET_MODAL);
|
||||
View::tab_button(ui, PLUS, pressed, |_| {
|
||||
self.show_add_wallet_modal(cb);
|
||||
self.show_add_wallet_modal();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -239,7 +239,7 @@ impl WalletsContent {
|
||||
ui.ctx().request_repaint_after(Duration::from_millis(1000));
|
||||
}
|
||||
// Show wallet list.
|
||||
self.wallet_list_ui(ui, cb);
|
||||
self.wallet_list_ui(ui);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ impl WalletsContent {
|
||||
// Show wallet creation button.
|
||||
let add_text = format!("{} {}", FOLDER_PLUS, t!("wallets.add"));
|
||||
View::button(ui, add_text, Colors::white_or_black(false), || {
|
||||
self.show_add_wallet_modal(cb);
|
||||
self.show_add_wallet_modal();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
@@ -307,7 +307,7 @@ impl WalletsContent {
|
||||
}
|
||||
|
||||
/// Handle data from deeplink or opened file.
|
||||
pub fn on_data(&mut self, ui: &mut egui::Ui, data: Option<String>, cb: &dyn PlatformCallbacks) {
|
||||
pub fn on_data(&mut self, ui: &mut egui::Ui, data: Option<String>) {
|
||||
let wallets_size = self.wallets.list().len();
|
||||
if wallets_size == 0 {
|
||||
return;
|
||||
@@ -322,7 +322,7 @@ impl WalletsContent {
|
||||
if w.is_open() {
|
||||
self.wallet_content = Some(WalletContent::new(w, data));
|
||||
} else {
|
||||
self.show_opening_modal(w, data, cb);
|
||||
self.show_opening_modal(w, data);
|
||||
}
|
||||
} else {
|
||||
self.show_wallet_selection_modal(data);
|
||||
@@ -330,13 +330,12 @@ impl WalletsContent {
|
||||
}
|
||||
|
||||
/// Show initial wallet creation [`Modal`].
|
||||
pub fn show_add_wallet_modal(&mut self, cb: &dyn PlatformCallbacks) {
|
||||
pub fn show_add_wallet_modal(&mut self) {
|
||||
self.add_wallet_modal_content = Some(AddWalletModal::default());
|
||||
Modal::new(ADD_WALLET_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.add"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
|
||||
/// Show wallet selection with provided optional data.
|
||||
@@ -492,9 +491,7 @@ impl WalletsContent {
|
||||
}
|
||||
|
||||
/// Draw list of wallets.
|
||||
fn wallet_list_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn wallet_list_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ScrollArea::vertical()
|
||||
.id_salt("wallet_list_scroll")
|
||||
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
||||
@@ -517,9 +514,9 @@ impl WalletsContent {
|
||||
// Check if wallet reopen is needed.
|
||||
if w.reopen_needed() && !w.is_open() {
|
||||
w.set_reopen(false);
|
||||
self.show_opening_modal(w.clone(), None, cb);
|
||||
self.show_opening_modal(w.clone(), None);
|
||||
}
|
||||
self.wallet_item_ui(ui, w, cb);
|
||||
self.wallet_item_ui(ui, w);
|
||||
ui.add_space(5.0);
|
||||
}
|
||||
});
|
||||
@@ -527,10 +524,7 @@ impl WalletsContent {
|
||||
}
|
||||
|
||||
/// Draw wallet list item.
|
||||
fn wallet_item_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn wallet_item_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet) {
|
||||
let config = wallet.get_config();
|
||||
let current = if let Some(content) = &self.wallet_content {
|
||||
content.wallet.get_config().id == config.id && wallet.is_open()
|
||||
@@ -553,7 +547,7 @@ impl WalletsContent {
|
||||
if !wallet.is_open() {
|
||||
// Show button to open closed wallet.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), FOLDER_OPEN, None, || {
|
||||
self.show_opening_modal(wallet.clone(), None, cb);
|
||||
self.show_opening_modal(wallet.clone(), None);
|
||||
});
|
||||
if !wallet.syncing() {
|
||||
let mut show_selection = false;
|
||||
@@ -628,17 +622,13 @@ impl WalletsContent {
|
||||
}
|
||||
|
||||
/// Show [`Modal`] to select and open wallet.
|
||||
fn show_opening_modal(&mut self,
|
||||
wallet: Wallet,
|
||||
data: Option<String>,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn show_opening_modal(&mut self, wallet: Wallet, data: Option<String>) {
|
||||
self.wallet_content = Some(WalletContent::new(wallet.clone(), None));
|
||||
self.open_wallet_content = Some(OpenWalletModal::new(wallet, data));
|
||||
Modal::new(OPEN_WALLET_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.open"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
|
||||
/// Check if it's possible to show [`WalletsContent`] and [`WalletContent`] panels at same time.
|
||||
|
||||
@@ -87,7 +87,7 @@ impl MnemonicSetup {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show words setup.
|
||||
self.word_list_ui(ui, self.mnemonic.mode() == PhraseMode::Import, cb);
|
||||
self.word_list_ui(ui, self.mnemonic.mode() == PhraseMode::Import);
|
||||
}
|
||||
|
||||
/// Draw content for phrase confirmation step.
|
||||
@@ -101,7 +101,7 @@ impl MnemonicSetup {
|
||||
ui.label(RichText::new(text).size(16.0).color(Colors::gray()));
|
||||
});
|
||||
ui.add_space(4.0);
|
||||
self.word_list_ui(ui, true, cb);
|
||||
self.word_list_ui(ui, true);
|
||||
}
|
||||
|
||||
/// Draw mode and size setup.
|
||||
@@ -149,7 +149,7 @@ impl MnemonicSetup {
|
||||
}
|
||||
|
||||
/// Draw grid of words for mnemonic phrase.
|
||||
fn word_list_ui(&mut self, ui: &mut egui::Ui, edit: bool, cb: &dyn PlatformCallbacks) {
|
||||
fn word_list_ui(&mut self, ui: &mut egui::Ui, edit: bool) {
|
||||
ui.add_space(6.0);
|
||||
ui.scope(|ui| {
|
||||
// Setup spacing between columns.
|
||||
@@ -167,25 +167,25 @@ impl MnemonicSetup {
|
||||
ui.columns(cols, |columns| {
|
||||
columns[0].horizontal(|ui| {
|
||||
let word = chunk.get(0).unwrap();
|
||||
self.word_item_ui(ui, word_number, word, edit, cb);
|
||||
self.word_item_ui(ui, word_number, word, edit);
|
||||
});
|
||||
columns[1].horizontal(|ui| {
|
||||
word_number += 1;
|
||||
let word = chunk.get(1).unwrap();
|
||||
self.word_item_ui(ui, word_number, word, edit, cb);
|
||||
self.word_item_ui(ui, word_number, word, edit);
|
||||
});
|
||||
if size > 2 {
|
||||
columns[2].horizontal(|ui| {
|
||||
word_number += 1;
|
||||
let word = chunk.get(2).unwrap();
|
||||
self.word_item_ui(ui, word_number, word, edit, cb);
|
||||
self.word_item_ui(ui, word_number, word, edit);
|
||||
});
|
||||
}
|
||||
if size > 3 {
|
||||
columns[3].horizontal(|ui| {
|
||||
word_number += 1;
|
||||
let word = chunk.get(3).unwrap();
|
||||
self.word_item_ui(ui, word_number, word, edit, cb);
|
||||
self.word_item_ui(ui, word_number, word, edit);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -193,7 +193,7 @@ impl MnemonicSetup {
|
||||
ui.columns(cols, |columns| {
|
||||
columns[0].horizontal(|ui| {
|
||||
let word = chunk.get(0).unwrap();
|
||||
self.word_item_ui(ui, word_number, word, edit, cb);
|
||||
self.word_item_ui(ui, word_number, word, edit);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -207,8 +207,7 @@ impl MnemonicSetup {
|
||||
ui: &mut egui::Ui,
|
||||
num: usize,
|
||||
word: &PhraseWord,
|
||||
edit: bool,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
edit: bool) {
|
||||
let color = if !word.valid || (word.text.is_empty() && !self.mnemonic.valid()) {
|
||||
Colors::red()
|
||||
} else {
|
||||
@@ -225,7 +224,6 @@ impl MnemonicSetup {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.recovery_phrase"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.label(RichText::new(format!("#{} {}", num, word.text))
|
||||
.size(17.0)
|
||||
@@ -276,7 +274,6 @@ impl MnemonicSetup {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -295,7 +292,6 @@ impl MnemonicSetup {
|
||||
(!next_word.as_ref().unwrap().text.is_empty() &&
|
||||
next_word.unwrap().valid);
|
||||
if close_modal {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
} else {
|
||||
self.word_index_edit += 1;
|
||||
|
||||
@@ -48,6 +48,8 @@ impl AddWalletModal {
|
||||
cb: &dyn PlatformCallbacks,
|
||||
mut on_input: impl FnMut(String, ZeroingString)) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
let mut enter_pressed = false;
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("wallets.name"))
|
||||
.size(17.0)
|
||||
@@ -62,8 +64,11 @@ impl AddWalletModal {
|
||||
name_edit_opts.focus = true;
|
||||
}
|
||||
View::text_edit(ui, cb, &mut self.name_edit, &mut name_edit_opts);
|
||||
ui.add_space(8.0);
|
||||
View::on_enter_key(ui, || {
|
||||
name_edit_opts.enter_pressed = name_edit_opts.focus;
|
||||
});
|
||||
|
||||
ui.add_space(8.0);
|
||||
ui.label(RichText::new(t!("wallets.pass"))
|
||||
.size(17.0)
|
||||
.color(Colors::gray()));
|
||||
@@ -73,7 +78,12 @@ impl AddWalletModal {
|
||||
let mut pass_text_edit_opts = TextEditOptions::new(Id::from(modal.id).with("pass"))
|
||||
.password()
|
||||
.no_focus();
|
||||
if name_edit_opts.enter_pressed {
|
||||
pass_text_edit_opts.focus = true;
|
||||
}
|
||||
View::text_edit(ui, cb, &mut self.pass_edit, &mut pass_text_edit_opts);
|
||||
enter_pressed = pass_text_edit_opts.enter_pressed;
|
||||
|
||||
ui.add_space(12.0);
|
||||
});
|
||||
|
||||
@@ -86,7 +96,6 @@ impl AddWalletModal {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -97,7 +106,6 @@ impl AddWalletModal {
|
||||
if name.is_empty() || pass.is_empty() {
|
||||
return;
|
||||
}
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
on_input(name, ZeroingString::from(pass));
|
||||
};
|
||||
@@ -106,6 +114,9 @@ impl AddWalletModal {
|
||||
View::on_enter_key(ui, || {
|
||||
(on_next)();
|
||||
});
|
||||
if enter_pressed {
|
||||
(on_next)();
|
||||
}
|
||||
|
||||
View::button(ui, t!("continue"), Colors::white_or_black(false), on_next);
|
||||
});
|
||||
|
||||
@@ -52,6 +52,8 @@ impl OpenWalletModal {
|
||||
cb: &dyn PlatformCallbacks,
|
||||
mut on_continue: impl FnMut(Wallet, Option<String>)) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
let mut enter_pressed = false;
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("wallets.pass"))
|
||||
.size(17.0)
|
||||
@@ -61,6 +63,7 @@ impl OpenWalletModal {
|
||||
// Show password input.
|
||||
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);
|
||||
enter_pressed = pass_edit_opts.enter_pressed;
|
||||
|
||||
// Show information when password is empty.
|
||||
if self.pass_edit.is_empty() {
|
||||
@@ -87,7 +90,6 @@ impl OpenWalletModal {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -101,7 +103,6 @@ impl OpenWalletModal {
|
||||
match self.wallet.open(ZeroingString::from(pass)) {
|
||||
Ok(_) => {
|
||||
self.pass_edit = "".to_string();
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
on_continue(self.wallet.clone(), self.data.clone());
|
||||
}
|
||||
@@ -113,6 +114,9 @@ impl OpenWalletModal {
|
||||
View::on_enter_key(ui, || {
|
||||
(on_continue)();
|
||||
});
|
||||
if enter_pressed {
|
||||
(on_continue)();
|
||||
}
|
||||
|
||||
View::button(ui, t!("continue"), Colors::white_or_black(false), on_continue);
|
||||
});
|
||||
|
||||
@@ -138,7 +138,7 @@ impl WalletContent {
|
||||
match result {
|
||||
QrScanResult::Address(address) => {
|
||||
self.current_tab =
|
||||
Box::new(WalletTransport::new(Some(address.to_string()), cb));
|
||||
Box::new(WalletTransport::new(Some(address.to_string())));
|
||||
}
|
||||
_ => {
|
||||
self.current_tab =
|
||||
@@ -409,7 +409,7 @@ impl WalletContent {
|
||||
});
|
||||
columns[2].vertical_centered_justified(|ui| {
|
||||
View::tab_button(ui, BRIDGE, current_type == WalletTabType::Transport, |_| {
|
||||
self.current_tab = Box::new(WalletTransport::new(None, cb));
|
||||
self.current_tab = Box::new(WalletTransport::new(None));
|
||||
});
|
||||
});
|
||||
columns[3].vertical_centered_justified(|ui| {
|
||||
|
||||
@@ -107,7 +107,7 @@ impl WalletMessages {
|
||||
ui.add_space(3.0);
|
||||
|
||||
// Show creation of request to send or receive funds.
|
||||
self.request_ui(ui, wallet, cb);
|
||||
self.request_ui(ui, wallet);
|
||||
|
||||
ui.add_space(12.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -173,10 +173,7 @@ impl WalletMessages {
|
||||
}
|
||||
|
||||
/// Draw creation of request to send or receive funds.
|
||||
fn request_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn request_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet) {
|
||||
ui.label(RichText::new(t!("wallets.create_request_desc"))
|
||||
.size(16.0)
|
||||
.color(Colors::inactive_text()));
|
||||
@@ -195,31 +192,31 @@ impl WalletMessages {
|
||||
send_text,
|
||||
Colors::red(),
|
||||
Colors::white_or_black(false), || {
|
||||
self.show_request_modal(false, cb);
|
||||
self.show_request_modal(false);
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
self.receive_button_ui(ui, cb);
|
||||
self.receive_button_ui(ui);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
self.receive_button_ui(ui, cb);
|
||||
self.receive_button_ui(ui);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw invoice request creation button.
|
||||
fn receive_button_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn receive_button_ui(&mut self, ui: &mut egui::Ui) {
|
||||
let receive_text = format!("{} {}", DOWNLOAD_SIMPLE, t!("wallets.receive"));
|
||||
View::colored_text_button(ui,
|
||||
receive_text,
|
||||
Colors::green(),
|
||||
Colors::white_or_black(false), || {
|
||||
self.show_request_modal(true, cb);
|
||||
self.show_request_modal(true);
|
||||
});
|
||||
}
|
||||
|
||||
/// Show [`Modal`] to create invoice or sending request.
|
||||
fn show_request_modal(&mut self, invoice: bool, cb: &dyn PlatformCallbacks) {
|
||||
fn show_request_modal(&mut self, invoice: bool) {
|
||||
self.request_modal_content = Some(MessageRequestModal::new(invoice));
|
||||
let title = if invoice {
|
||||
t!("wallets.receive")
|
||||
@@ -230,7 +227,6 @@ impl WalletMessages {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(title)
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
|
||||
/// Draw Slatepack message input content.
|
||||
@@ -274,14 +270,8 @@ impl WalletMessages {
|
||||
.desired_width(f32::INFINITY)
|
||||
.show(ui)
|
||||
.response;
|
||||
// Show soft keyboard on click.
|
||||
if resp.clicked() {
|
||||
resp.request_focus();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
if resp.has_focus() {
|
||||
// Apply text from input on Android as temporary fix for egui.
|
||||
View::on_soft_input(ui, input_id, &mut self.message_edit);
|
||||
}
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
|
||||
@@ -102,7 +102,6 @@ impl MessageRequestModal {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
self.amount_edit = "".to_string();
|
||||
self.request_error = None;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -113,7 +112,6 @@ impl MessageRequestModal {
|
||||
return;
|
||||
}
|
||||
if let Ok(a) = amount_from_hr_string(self.amount_edit.as_str()) {
|
||||
cb.hide_keyboard();
|
||||
modal.disable_closing();
|
||||
// Setup data for request.
|
||||
let wallet = wallet.clone();
|
||||
|
||||
@@ -96,7 +96,6 @@ impl WalletAccountsModal {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -108,7 +107,6 @@ impl WalletAccountsModal {
|
||||
match wallet.create_account(label) {
|
||||
Ok(_) => {
|
||||
let _ = wallet.set_active_account(label);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
},
|
||||
Err(_) => self.account_creation_error = true
|
||||
@@ -165,7 +163,6 @@ impl WalletAccountsModal {
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("create"), Colors::white_or_black(false), || {
|
||||
self.account_creating = true;
|
||||
cb.show_keyboard();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -87,7 +87,6 @@ impl CommonSettings {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.wallet"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
|
||||
ui.add_space(12.0);
|
||||
@@ -109,7 +108,6 @@ impl CommonSettings {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.wallet"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
|
||||
ui.add_space(12.0);
|
||||
@@ -127,7 +125,6 @@ impl CommonSettings {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_value"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
|
||||
ui.add_space(12.0);
|
||||
@@ -202,7 +199,6 @@ impl CommonSettings {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -211,7 +207,6 @@ impl CommonSettings {
|
||||
let on_save = || {
|
||||
if !self.name_edit.is_empty() {
|
||||
wallet.change_name(self.name_edit.clone());
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
@@ -288,7 +283,6 @@ impl CommonSettings {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -306,7 +300,6 @@ impl CommonSettings {
|
||||
self.old_pass_edit = "".to_string();
|
||||
self.new_pass_edit = "".to_string();
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
Err(_) => self.wrong_pass = true
|
||||
@@ -361,7 +354,6 @@ impl CommonSettings {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -370,7 +362,6 @@ impl CommonSettings {
|
||||
let on_save = || {
|
||||
if let Ok(min_conf) = self.min_confirmations_edit.parse::<u64>() {
|
||||
wallet.update_min_confirmations(min_conf);
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -129,7 +129,6 @@ impl ConnectionSettings {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.add_node"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(4.0);
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ impl RecoverySettings {
|
||||
// Draw button to show recovery phrase.
|
||||
let show_text = format!("{} {}", EYE, t!("show"));
|
||||
View::button(ui, show_text, Colors::white_or_black(false), || {
|
||||
self.show_recovery_phrase_modal(cb);
|
||||
self.show_recovery_phrase_modal();
|
||||
});
|
||||
|
||||
ui.add_space(12.0);
|
||||
@@ -164,7 +164,7 @@ impl RecoverySettings {
|
||||
}
|
||||
|
||||
/// Show recovery phrase [`Modal`].
|
||||
fn show_recovery_phrase_modal(&mut self, cb: &dyn PlatformCallbacks) {
|
||||
fn show_recovery_phrase_modal(&mut self) {
|
||||
// Setup modal values.
|
||||
self.pass_edit = "".to_string();
|
||||
self.wrong_pass = false;
|
||||
@@ -174,7 +174,6 @@ impl RecoverySettings {
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.recovery_phrase"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
|
||||
/// Draw recovery phrase [`Modal`] content.
|
||||
@@ -242,7 +241,6 @@ impl RecoverySettings {
|
||||
Ok(phrase) => {
|
||||
self.wrong_pass = false;
|
||||
self.recovery_phrase = Some(phrase);
|
||||
cb.hide_keyboard();
|
||||
}
|
||||
Err(_) => {
|
||||
self.wrong_pass = true;
|
||||
|
||||
@@ -61,14 +61,14 @@ const QR_ADDRESS_MODAL: &'static str = "qr_address_modal";
|
||||
|
||||
impl WalletTransport {
|
||||
/// Create new transport content instance, opening sending `Modal` if address was provided.
|
||||
pub fn new(address: Option<String>, cb: &dyn PlatformCallbacks) -> Self {
|
||||
pub fn new(address: Option<String>) -> Self {
|
||||
let mut content = Self {
|
||||
send_modal_content: None,
|
||||
qr_address_content: None,
|
||||
settings_modal_content: None,
|
||||
};
|
||||
if address.is_some() {
|
||||
content.show_send_tor_modal(cb, address)
|
||||
content.show_send_tor_modal(address)
|
||||
}
|
||||
content
|
||||
}
|
||||
@@ -135,7 +135,7 @@ impl WalletTransport {
|
||||
let service_id = &wallet.identifier();
|
||||
if data.info.amount_currently_spendable > 0 && wallet.foreign_api_port().is_some() &&
|
||||
!Tor::is_service_starting(service_id) {
|
||||
self.tor_send_ui(ui, cb);
|
||||
self.tor_send_ui(ui);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ impl WalletTransport {
|
||||
}
|
||||
|
||||
/// Draw Tor send content.
|
||||
fn tor_send_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn tor_send_ui(&mut self, ui: &mut egui::Ui) {
|
||||
// Setup layout size.
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
rect.set_height(55.0);
|
||||
@@ -346,20 +346,19 @@ impl WalletTransport {
|
||||
// Draw button to open sending modal.
|
||||
let send_text = format!("{} {}", EXPORT, t!("wallets.send"));
|
||||
View::button(ui, send_text, Colors::white_or_black(false), || {
|
||||
self.show_send_tor_modal(cb, None);
|
||||
self.show_send_tor_modal(None);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Show [`Modal`] to send over Tor.
|
||||
fn show_send_tor_modal(&mut self, cb: &dyn PlatformCallbacks, address: Option<String>) {
|
||||
fn show_send_tor_modal(&mut self, address: Option<String>) {
|
||||
self.send_modal_content = Some(TransportSendModal::new(address));
|
||||
// Show modal.
|
||||
Modal::new(SEND_TOR_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.send"))
|
||||
.show();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
}
|
||||
@@ -85,14 +85,17 @@ impl TransportSendModal {
|
||||
if self.sending {
|
||||
self.progress_ui(ui, wallet);
|
||||
} else if self.error {
|
||||
self.error_ui(ui, wallet, modal, cb);
|
||||
self.error_ui(ui, wallet, modal);
|
||||
} else {
|
||||
self.content_ui(ui, wallet, modal, cb);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw content to send.
|
||||
fn content_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet, modal: &Modal,
|
||||
fn content_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.
|
||||
@@ -107,7 +110,6 @@ impl TransportSendModal {
|
||||
self.address_edit = result.text();
|
||||
on_stop();
|
||||
self.address_scan_content = None;
|
||||
cb.show_keyboard();
|
||||
} else {
|
||||
scanner.ui(ui, cb);
|
||||
ui.add_space(6.0);
|
||||
@@ -128,7 +130,6 @@ impl TransportSendModal {
|
||||
View::button(ui, t!("back"), Colors::white_or_black(false), || {
|
||||
on_stop();
|
||||
self.address_scan_content = None;
|
||||
cb.show_keyboard();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -217,7 +218,6 @@ impl TransportSendModal {
|
||||
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.address_scan_content = Some(CameraContent::default());
|
||||
@@ -235,12 +235,12 @@ impl TransportSendModal {
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
self.close(modal, cb);
|
||||
self.close(modal);
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("continue"), Colors::white_or_black(false), || {
|
||||
self.send(wallet, modal, cb);
|
||||
self.send(wallet, modal);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -248,11 +248,7 @@ impl TransportSendModal {
|
||||
}
|
||||
|
||||
/// Draw error content.
|
||||
fn error_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn error_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet, modal: &Modal) {
|
||||
ui.add_space(6.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("transport.tor_send_error"))
|
||||
@@ -267,12 +263,12 @@ impl TransportSendModal {
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
self.close(modal, cb);
|
||||
self.close(modal);
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("repeat"), Colors::white_or_black(false), || {
|
||||
self.send(wallet, modal, cb);
|
||||
self.send(wallet, modal);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -280,7 +276,7 @@ impl TransportSendModal {
|
||||
}
|
||||
|
||||
/// Close modal and clear data.
|
||||
fn close(&mut self, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
fn close(&mut self, modal: &Modal) {
|
||||
self.amount_edit = "".to_string();
|
||||
self.address_edit = "".to_string();
|
||||
|
||||
@@ -290,19 +286,17 @@ impl TransportSendModal {
|
||||
self.tx_info_content = None;
|
||||
self.address_scan_content = None;
|
||||
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
|
||||
/// Send entered amount to address.
|
||||
fn send(&mut self, wallet: &Wallet, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
fn send(&mut self, wallet: &Wallet, modal: &Modal) {
|
||||
if self.amount_edit.is_empty() {
|
||||
return;
|
||||
}
|
||||
let addr_str = self.address_edit.as_str();
|
||||
if let Ok(addr) = SlatepackAddress::try_from(addr_str.trim()) {
|
||||
if let Ok(a) = amount_from_hr_string(self.amount_edit.as_str()) {
|
||||
cb.hide_keyboard();
|
||||
modal.disable_closing();
|
||||
// Send amount over Tor.
|
||||
let mut wallet = wallet.clone();
|
||||
|
||||
@@ -72,7 +72,6 @@ impl TransportSettingsModal {
|
||||
self.bridge_conn_line_edit = result.text();
|
||||
on_stop();
|
||||
self.bridge_qr_scan_content = None;
|
||||
cb.show_keyboard();
|
||||
} else {
|
||||
scanner.ui(ui, cb);
|
||||
ui.add_space(12.0);
|
||||
@@ -191,7 +190,6 @@ impl TransportSettingsModal {
|
||||
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.bridge_qr_scan_content = Some(CameraContent::default());
|
||||
|
||||
@@ -61,7 +61,7 @@ impl WalletTab for WalletTransactions {
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
self.modal_content_ui(ui, wallet, cb);
|
||||
self.txs_ui(ui, wallet, cb);
|
||||
self.txs_ui(ui, wallet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,10 +75,7 @@ impl WalletTransactions {
|
||||
pub const TX_ITEM_HEIGHT: f32 = 75.0;
|
||||
|
||||
/// Draw transactions content.
|
||||
fn txs_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn txs_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet) {
|
||||
let data = wallet.get_data().unwrap();
|
||||
if data.txs.is_none() {
|
||||
ui.centered_and_justified(|ui| {
|
||||
@@ -123,7 +120,7 @@ impl WalletTransactions {
|
||||
.show_rows(ui, Self::TX_ITEM_HEIGHT, txs.len(), |ui, row_range| {
|
||||
ui.add_space(1.0);
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
self.tx_list_ui(ui, awaiting_amount, row_range, wallet, txs, cb);
|
||||
self.tx_list_ui(ui, awaiting_amount, row_range, wallet, txs);
|
||||
});
|
||||
})
|
||||
});
|
||||
@@ -143,8 +140,7 @@ impl WalletTransactions {
|
||||
awaiting: bool,
|
||||
row_range: Range<usize>,
|
||||
wallet: &Wallet,
|
||||
txs: &Vec<WalletTransaction>,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
txs: &Vec<WalletTransaction>) {
|
||||
for index in row_range {
|
||||
let mut rect = if awaiting {
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
@@ -179,7 +175,6 @@ impl WalletTransactions {
|
||||
if wallet_loaded && tx.can_finalize {
|
||||
let (icon, color) = (CHECK, Some(Colors::green()));
|
||||
View::item_button(ui, Rounding::default(), icon, color, || {
|
||||
cb.hide_keyboard();
|
||||
self.show_tx_info_modal(wallet, tx, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,7 +116,6 @@ impl WalletTransactionModal {
|
||||
.filter(|tx| tx.data.id == self.tx_id)
|
||||
.collect::<Vec<WalletTransaction>>();
|
||||
if txs.is_empty() {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
return;
|
||||
}
|
||||
@@ -178,7 +177,6 @@ impl WalletTransactionModal {
|
||||
// Show button to close modal.
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("close"), Colors::white_or_black(false), || {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
@@ -266,7 +264,6 @@ impl WalletTransactionModal {
|
||||
};
|
||||
let r = View::item_rounding(0, 2, true);
|
||||
View::item_button(ui, r, icon, color, || {
|
||||
cb.hide_keyboard();
|
||||
if self.show_finalization {
|
||||
self.show_finalization = false;
|
||||
return;
|
||||
@@ -282,7 +279,6 @@ impl WalletTransactionModal {
|
||||
View::item_rounding(0, 2, true)
|
||||
};
|
||||
View::item_button(ui, r, PROHIBIT, Some(Colors::red()), || {
|
||||
cb.hide_keyboard();
|
||||
wallet.cancel(tx.data.id);
|
||||
});
|
||||
}
|
||||
@@ -321,7 +317,7 @@ impl WalletTransactionModal {
|
||||
|
||||
// Setup value to finalization input field.
|
||||
self.finalize_edit = result.text();
|
||||
self.on_finalization_input_change(tx, wallet, modal, cb);
|
||||
self.on_finalization_input_change(tx, wallet, modal);
|
||||
|
||||
modal.enable_closing();
|
||||
self.scan_qr_content = None;
|
||||
@@ -409,14 +405,8 @@ impl WalletTransactionModal {
|
||||
.hint_text(SLATEPACK_MESSAGE_HINT)
|
||||
.desired_width(f32::INFINITY)
|
||||
.show(ui).response;
|
||||
// Show soft keyboard on click.
|
||||
if self.show_finalization && resp.clicked() {
|
||||
resp.request_focus();
|
||||
cb.show_keyboard();
|
||||
}
|
||||
if self.show_finalization && resp.has_focus() {
|
||||
// Apply text from input on Android as temporary fix for egui.
|
||||
View::on_soft_input(ui, input_id, message_edit);
|
||||
}
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
@@ -440,7 +430,6 @@ impl WalletTransactionModal {
|
||||
// Draw button to scan Slatepack message QR code.
|
||||
let qr_text = format!("{} {}", SCAN, t!("scan"));
|
||||
View::button(ui, qr_text, Colors::fill_lite(), || {
|
||||
cb.hide_keyboard();
|
||||
modal.disable_closing();
|
||||
cb.start_camera();
|
||||
self.scan_qr_content = Some(CameraContent::default());
|
||||
@@ -473,7 +462,7 @@ impl WalletTransactionModal {
|
||||
|
||||
// Callback on finalization message input change.
|
||||
if message_before != self.finalize_edit {
|
||||
self.on_finalization_input_change(tx, wallet, modal, cb);
|
||||
self.on_finalization_input_change(tx, wallet, modal);
|
||||
}
|
||||
} else {
|
||||
ui.columns(2, |columns| {
|
||||
@@ -481,7 +470,6 @@ impl WalletTransactionModal {
|
||||
// Draw button to show Slatepack message as QR code.
|
||||
let qr_text = format!("{} {}", QR_CODE, t!("qr_code"));
|
||||
View::button(ui, qr_text.clone(), Colors::white_or_black(false), || {
|
||||
cb.hide_keyboard();
|
||||
let text = self.response_edit.clone();
|
||||
self.qr_code_content = Some(QrCodeContent::new(text, true));
|
||||
});
|
||||
@@ -495,7 +483,6 @@ impl WalletTransactionModal {
|
||||
if tx.can_finalize {
|
||||
self.show_finalization = true;
|
||||
} else {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
});
|
||||
@@ -521,27 +508,22 @@ impl WalletTransactionModal {
|
||||
}
|
||||
|
||||
/// Parse Slatepack message on transaction finalization input change.
|
||||
fn on_finalization_input_change(&mut self,
|
||||
tx: &WalletTransaction,
|
||||
wallet: &Wallet,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn on_finalization_input_change(&mut self, tx: &WalletTransaction, w: &Wallet, modal: &Modal) {
|
||||
let message = &self.finalize_edit;
|
||||
if message.is_empty() {
|
||||
self.finalize_error = false;
|
||||
} else {
|
||||
// Parse input message to finalize.
|
||||
if let Ok(slate) = wallet.parse_slatepack(message) {
|
||||
if let Ok(slate) = w.parse_slatepack(message) {
|
||||
let send = slate.state == SlateState::Standard2 &&
|
||||
tx.data.tx_type == TxLogEntryType::TxSent;
|
||||
let receive = slate.state == SlateState::Invoice2 &&
|
||||
tx.data.tx_type == TxLogEntryType::TxReceived;
|
||||
if Some(slate.id) == tx.data.tx_slate_id && (send || receive) {
|
||||
let message = message.clone();
|
||||
let wallet = wallet.clone();
|
||||
let wallet = w.clone();
|
||||
let final_res = self.final_result.clone();
|
||||
// Finalize transaction at separate thread.
|
||||
cb.hide_keyboard();
|
||||
self.finalizing = true;
|
||||
modal.disable_closing();
|
||||
thread::spawn(move || {
|
||||
|
||||
Reference in New Issue
Block a user