mirror of
https://github.com/jwinterm/grim.git
synced 2026-10-21 23:48:34 +02:00
wallet + config + ui: load wallet info, wallet connections and app config refactoring, check external connections availability, config subdir argument format, item button color, radio buttons stroke, chain type selection from connections, update translations
This commit is contained in:
@@ -17,25 +17,25 @@ use url::Url;
|
||||
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{CARET_RIGHT, CHECK_CIRCLE, COMPUTER_TOWER, DOTS_THREE_CIRCLE, GLOBE_SIMPLE, PENCIL, PLAY, STOP, TRASH, X_CIRCLE};
|
||||
use crate::gui::icons::{CARET_RIGHT, CHECK_CIRCLE, COMPUTER_TOWER, DOTS_THREE_CIRCLE, PENCIL, POWER, TRASH, X_CIRCLE};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::{Modal, NodeSetup, View};
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::node::{Node, NodeConfig};
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection};
|
||||
|
||||
/// Network connections content.
|
||||
pub struct ConnectionsContent {
|
||||
/// Flag to check if modal was just opened.
|
||||
/// Flag to check if [`Modal`] was just opened to focus on input field.
|
||||
first_modal_launch: bool,
|
||||
/// External connection URL value for [`Modal`].
|
||||
ext_node_url_edit: String,
|
||||
/// External connection API secret value for [`Modal`].
|
||||
ext_node_secret_edit: String,
|
||||
/// Flag to show URL format error.
|
||||
/// Flag to show URL format error at [`Modal`].
|
||||
ext_node_url_error: bool,
|
||||
/// Flag to check if existing connection is editing.
|
||||
edit_ext_conn: Option<ExternalConnection>,
|
||||
/// Editing external connection identifier for [`Modal`].
|
||||
ext_conn_id_edit: Option<i64>,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
@@ -43,12 +43,15 @@ pub struct ConnectionsContent {
|
||||
|
||||
impl Default for ConnectionsContent {
|
||||
fn default() -> Self {
|
||||
if AppConfig::show_connections_network_panel() {
|
||||
ExternalConnection::start_ext_conn_availability_check();
|
||||
}
|
||||
Self {
|
||||
first_modal_launch: true,
|
||||
ext_node_url_edit: "".to_string(),
|
||||
ext_node_secret_edit: "".to_string(),
|
||||
ext_node_url_error: false,
|
||||
edit_ext_conn: None,
|
||||
ext_conn_id_edit: None,
|
||||
modal_ids: vec![
|
||||
Self::NETWORK_EXT_CONNECTION_MODAL
|
||||
]
|
||||
@@ -81,20 +84,30 @@ impl ConnectionsContent {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, frame, cb);
|
||||
|
||||
// Show network type selection.
|
||||
let saved_chain_type = AppConfig::chain_type();
|
||||
NodeSetup::chain_type_ui(ui);
|
||||
// Start external connections availability check on network type change.
|
||||
if saved_chain_type != AppConfig::chain_type() {
|
||||
ExternalConnection::start_ext_conn_availability_check();
|
||||
}
|
||||
ui.add_space(5.0);
|
||||
|
||||
// Show integrated node info content.
|
||||
Self::integrated_node_item_ui(ui);
|
||||
|
||||
ui.add_space(8.0);
|
||||
ui.label(RichText::new(t!("wallets.ext_conn")).size(16.0).color(Colors::GRAY));
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show external connections.
|
||||
let ext_conn_list = ConnectionsConfig::external_connections();
|
||||
for (index, conn) in ext_conn_list.iter().enumerate() {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
// Draw connection list item.
|
||||
self.ext_conn_item_ui(ui, conn, index, ext_conn_list.len(), cb);
|
||||
});
|
||||
let ext_conn_list = ConnectionsConfig::ext_conn_list();
|
||||
if !ext_conn_list.is_empty() {
|
||||
ui.add_space(6.0);
|
||||
ui.label(RichText::new(t!("wallets.ext_conn")).size(16.0).color(Colors::GRAY));
|
||||
ui.add_space(6.0);
|
||||
// Show external connections.
|
||||
for (index, conn) in ext_conn_list.iter().enumerate() {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
// Draw connection list item.
|
||||
self.ext_conn_item_ui(ui, conn, index, ext_conn_list.len(), cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,26 +128,26 @@ impl ConnectionsContent {
|
||||
ui.style_mut().visuals.widgets.hovered.rounding = Rounding::same(8.0);
|
||||
ui.style_mut().visuals.widgets.active.rounding = Rounding::same(8.0);
|
||||
|
||||
// Draw button to show integrated node.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), CARET_RIGHT, || {
|
||||
// Draw button to show integrated node info.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), CARET_RIGHT, None, || {
|
||||
AppConfig::toggle_show_connections_network_panel();
|
||||
});
|
||||
|
||||
if !Node::is_running() {
|
||||
// Draw button to start integrated node.
|
||||
View::item_button(ui, Rounding::none(), PLAY, || {
|
||||
View::item_button(ui, Rounding::none(), POWER, Some(Colors::GREEN), || {
|
||||
Node::start();
|
||||
});
|
||||
} else if !Node::is_starting() && !Node::is_stopping() && !Node::is_restarting() {
|
||||
// Show button to open closed wallet.
|
||||
View::item_button(ui, Rounding::none(), STOP, || {
|
||||
// Draw button to open closed wallet.
|
||||
View::item_button(ui, Rounding::none(), POWER, Some(Colors::RED), || {
|
||||
Node::stop(false);
|
||||
});
|
||||
}
|
||||
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(7.0);
|
||||
ui.add_space(6.0);
|
||||
ui.vertical(|ui| {
|
||||
ui.add_space(3.0);
|
||||
ui.label(RichText::new(t!("network.node"))
|
||||
@@ -157,7 +170,6 @@ impl ConnectionsContent {
|
||||
};
|
||||
let status_text = format!("{} {}", status_icon, Node::get_sync_status_text());
|
||||
ui.label(RichText::new(status_text).size(15.0).color(Colors::GRAY));
|
||||
ui.add_space(4.0);
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -172,28 +184,28 @@ impl ConnectionsContent {
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
// Setup layout size.
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
rect.set_height(42.0);
|
||||
rect.set_height(53.0);
|
||||
|
||||
// Draw round background.
|
||||
let bg_rect = rect.clone();
|
||||
let item_rounding = View::item_rounding(index, len, false);
|
||||
ui.painter().rect(bg_rect, item_rounding, Colors::FILL, View::ITEM_STROKE);
|
||||
ui.painter().rect(bg_rect, item_rounding, Colors::FILL_DARK, View::ITEM_STROKE);
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Draw buttons for non-default connections.
|
||||
if conn.url != ExternalConnection::DEFAULT_EXTERNAL_NODE_URL {
|
||||
if conn.url != ExternalConnection::DEFAULT_MAIN_URL {
|
||||
let button_rounding = View::item_rounding(index, len, true);
|
||||
View::item_button(ui, button_rounding, TRASH, || {
|
||||
ConnectionsConfig::remove_external_connection(conn);
|
||||
View::item_button(ui, button_rounding, TRASH, None, || {
|
||||
ConnectionsConfig::remove_ext_conn(conn.id);
|
||||
});
|
||||
View::item_button(ui, Rounding::none(), PENCIL, || {
|
||||
View::item_button(ui, Rounding::none(), PENCIL, None, || {
|
||||
// Setup values for Modal.
|
||||
self.first_modal_launch = true;
|
||||
self.ext_node_url_edit = conn.url.clone();
|
||||
self.ext_node_secret_edit = conn.secret.clone().unwrap_or("".to_string());
|
||||
self.ext_node_url_error = false;
|
||||
self.edit_ext_conn = Some(conn.clone());
|
||||
self.ext_conn_id_edit = Some(conn.id);
|
||||
// Show modal.
|
||||
Modal::new(Self::NETWORK_EXT_CONNECTION_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
@@ -206,11 +218,29 @@ impl ConnectionsContent {
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(6.0);
|
||||
// Draw connections URL.
|
||||
let conn_text = format!("{} {}", GLOBE_SIMPLE, conn.url);
|
||||
ui.label(RichText::new(conn_text)
|
||||
.color(Colors::TEXT_BUTTON)
|
||||
.size(16.0));
|
||||
ui.vertical(|ui| {
|
||||
// Draw connections URL.
|
||||
ui.add_space(4.0);
|
||||
let conn_text = format!("{} {}", COMPUTER_TOWER, conn.url);
|
||||
ui.label(RichText::new(conn_text)
|
||||
.color(Colors::TEXT)
|
||||
.size(15.0));
|
||||
|
||||
ui.add_space(1.0);
|
||||
|
||||
// Setup connection status text.
|
||||
let status_text = if let Some(available) = conn.available {
|
||||
if available {
|
||||
format!("{} {}", CHECK_CIRCLE, t!("network.available"))
|
||||
} else {
|
||||
format!("{} {}", X_CIRCLE, t!("network.not_available"))
|
||||
}
|
||||
} else {
|
||||
format!("{} {}", DOTS_THREE_CIRCLE, t!("network.availability_check"))
|
||||
};
|
||||
ui.label(RichText::new(status_text).size(15.0).color(Colors::GRAY));
|
||||
ui.add_space(3.0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -223,7 +253,7 @@ impl ConnectionsContent {
|
||||
self.ext_node_url_edit = "".to_string();
|
||||
self.ext_node_secret_edit = "".to_string();
|
||||
self.ext_node_url_error = false;
|
||||
self.edit_ext_conn = None;
|
||||
self.ext_conn_id_edit = None;
|
||||
// Show modal.
|
||||
Modal::new(Self::NETWORK_EXT_CONNECTION_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
@@ -246,7 +276,7 @@ impl ConnectionsContent {
|
||||
|
||||
// Draw node URL text edit.
|
||||
let url_edit_resp = egui::TextEdit::singleline(&mut self.ext_node_url_edit)
|
||||
.id(Id::from(modal.id).with("node_url_edit"))
|
||||
.id(Id::from(modal.id).with(self.ext_conn_id_edit))
|
||||
.font(TextStyle::Heading)
|
||||
.desired_width(ui.available_width())
|
||||
.cursor_at_end(true)
|
||||
@@ -315,13 +345,12 @@ impl ConnectionsContent {
|
||||
};
|
||||
|
||||
// Update or create new connections.
|
||||
let ext_conn = ExternalConnection::new(url.clone(), secret);
|
||||
if let Some(edit_conn) = self.edit_ext_conn.clone() {
|
||||
ConnectionsConfig::update_external_connection(edit_conn, ext_conn);
|
||||
self.edit_ext_conn = None;
|
||||
} else {
|
||||
ConnectionsConfig::add_external_connection(ext_conn);
|
||||
let mut ext_conn = ExternalConnection::new(url, secret);
|
||||
if let Some(id) = self.ext_conn_id_edit {
|
||||
ext_conn.id = id;
|
||||
}
|
||||
ConnectionsConfig::add_ext_conn(ext_conn);
|
||||
self.ext_conn_id_edit = None;
|
||||
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
|
||||
@@ -23,6 +23,7 @@ use crate::gui::views::{ConnectionsContent, NetworkMetrics, NetworkMining, Netwo
|
||||
use crate::gui::views::network::types::{NetworkTab, NetworkTabType};
|
||||
use crate::gui::views::types::TitleType;
|
||||
use crate::node::Node;
|
||||
use crate::wallet::ExternalConnection;
|
||||
|
||||
/// Network content.
|
||||
pub struct NetworkContent {
|
||||
@@ -178,6 +179,9 @@ impl NetworkContent {
|
||||
if !show_connections {
|
||||
View::title_button(ui, DOTS_THREE_OUTLINE_VERTICAL, || {
|
||||
AppConfig::toggle_show_connections_network_panel();
|
||||
if AppConfig::show_connections_network_panel() {
|
||||
ExternalConnection::start_ext_conn_availability_check();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
View::title_button(ui, PLUS_CIRCLE, || {
|
||||
|
||||
@@ -108,7 +108,7 @@ impl NodeSetup {
|
||||
ui.add_space(4.0);
|
||||
|
||||
// Show chain type setup.
|
||||
self.chain_type_ui(ui);
|
||||
Self::chain_type_ui(ui);
|
||||
|
||||
// Show loading indicator or controls to stop/start/restart node.
|
||||
if Node::is_stopping() || Node::is_restarting() || Node::is_starting() {
|
||||
@@ -220,7 +220,7 @@ impl NodeSetup {
|
||||
}
|
||||
|
||||
/// Draw [`ChainTypes`] setup content.
|
||||
fn chain_type_ui(&mut self, ui: &mut egui::Ui) {
|
||||
pub fn chain_type_ui(ui: &mut egui::Ui) {
|
||||
let saved_chain_type = AppConfig::chain_type();
|
||||
let mut selected_chain_type = saved_chain_type;
|
||||
|
||||
|
||||
@@ -908,7 +908,7 @@ fn peer_item_ui(ui: &mut egui::Ui,
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Draw delete button for non-default seed peers.
|
||||
if peer_type != &PeerType::DefaultSeed {
|
||||
View::item_button(ui, View::item_rounding(index, len, true), TRASH, || {
|
||||
View::item_button(ui, View::item_rounding(index, len, true), TRASH, None, || {
|
||||
match peer_type {
|
||||
PeerType::CustomSeed => {
|
||||
NodeConfig::remove_custom_seed(peer_addr);
|
||||
|
||||
+13
-4
@@ -104,6 +104,8 @@ impl View {
|
||||
/// Title button with transparent background fill color, contains only icon.
|
||||
pub fn title_button(ui: &mut egui::Ui, icon: &str, action: impl FnOnce()) {
|
||||
ui.scope(|ui| {
|
||||
// Disable stroke when inactive.
|
||||
ui.style_mut().visuals.widgets.inactive.bg_stroke = Stroke::NONE;
|
||||
// Setup stroke around title buttons on click.
|
||||
ui.style_mut().visuals.widgets.hovered.bg_stroke = Self::HOVER_STROKE;
|
||||
ui.style_mut().visuals.widgets.active.bg_stroke = Self::DEFAULT_STROKE;
|
||||
@@ -173,8 +175,12 @@ impl View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw list item [`Button`] with given vertical padding and rounding on left and right sides.
|
||||
pub fn item_button(ui: &mut egui::Ui, r: Rounding, icon: &'static str, action: impl FnOnce()) {
|
||||
/// Draw list item [`Button`] with provided rounding.
|
||||
pub fn item_button(ui: &mut egui::Ui,
|
||||
rounding: Rounding,
|
||||
text: &'static str,
|
||||
color: Option<Color32>,
|
||||
action: impl FnOnce()) {
|
||||
// Setup button size.
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
rect.set_width(32.0);
|
||||
@@ -193,9 +199,12 @@ impl View {
|
||||
ui.visuals_mut().widgets.hovered.bg_stroke = Self::HOVER_STROKE;
|
||||
ui.visuals_mut().widgets.active.bg_stroke = Self::ITEM_STROKE;
|
||||
|
||||
// Setup button text color.
|
||||
let text_color = if let Some(c) = color { c } else { Colors::ITEM_BUTTON };
|
||||
|
||||
// Show button.
|
||||
let br = Button::new(RichText::new(icon).size(20.0).color(Colors::ITEM_BUTTON))
|
||||
.rounding(r)
|
||||
let br = Button::new(RichText::new(text).size(20.0).color(text_color))
|
||||
.rounding(rounding)
|
||||
.min_size(button_size)
|
||||
.ui(ui);
|
||||
br.surrender_focus();
|
||||
|
||||
@@ -24,7 +24,7 @@ use crate::gui::views::{Modal, Root, TitlePanel, View};
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition, TitleType};
|
||||
use crate::gui::views::wallets::creation::WalletCreation;
|
||||
use crate::gui::views::wallets::WalletContent;
|
||||
use crate::wallet::{Wallet, Wallets};
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection, Wallet, Wallets};
|
||||
|
||||
/// Wallets content.
|
||||
pub struct WalletsContent {
|
||||
@@ -140,9 +140,7 @@ impl WalletsContent {
|
||||
}
|
||||
if create_wallet || !show_wallet {
|
||||
// Show wallet creation content.
|
||||
self.creation_content.ui(ui, frame, cb, |mut wallet| {
|
||||
// Load the wallet.
|
||||
Wallets::load(&mut wallet);
|
||||
self.creation_content.ui(ui, frame, cb, |wallet| {
|
||||
// Add created wallet to list.
|
||||
self.wallets.add(wallet);
|
||||
});
|
||||
@@ -365,17 +363,23 @@ impl WalletsContent {
|
||||
|
||||
if !wallet.is_open() {
|
||||
// Show button to open closed wallet.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), FOLDER_OPEN, || {
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), FOLDER_OPEN, None, || {
|
||||
self.wallets.select(Some(id));
|
||||
self.show_open_wallet_modal(cb);
|
||||
});
|
||||
} else if !is_selected {
|
||||
// Show button to select opened wallet.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), CARET_RIGHT, || {
|
||||
self.wallets.select(Some(id));
|
||||
});
|
||||
} else {
|
||||
if !is_selected {
|
||||
// Show button to select opened wallet.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), CARET_RIGHT, None, || {
|
||||
self.wallets.select(Some(id));
|
||||
});
|
||||
}
|
||||
// Show button to close opened wallet.
|
||||
View::item_button(ui, Rounding::none(), LOCK_KEY, || {
|
||||
View::item_button(ui, if !is_selected {
|
||||
Rounding::none()
|
||||
} else {
|
||||
View::item_rounding(0, 1, true)
|
||||
}, LOCK_KEY, None, || {
|
||||
let _ = wallet.close();
|
||||
});
|
||||
}
|
||||
@@ -390,9 +394,12 @@ impl WalletsContent {
|
||||
View::ellipsize_text(ui, wallet.config.name.to_owned(), 18.0, name_color);
|
||||
|
||||
// Setup wallet connection text.
|
||||
let external_url = &wallet.config.external_node_url;
|
||||
let conn_text = if let Some(url) = external_url {
|
||||
format!("{} {}", GLOBE_SIMPLE, url)
|
||||
let conn_text = if let Some(id) = wallet.config.ext_conn_id {
|
||||
let ext_conn_url = match ConnectionsConfig::ext_conn(id) {
|
||||
None => ExternalConnection::DEFAULT_MAIN_URL.to_string(),
|
||||
Some(ext_conn) => ext_conn.url
|
||||
};
|
||||
format!("{} {}", GLOBE_SIMPLE, ext_conn_url)
|
||||
} else {
|
||||
format!("{} {}", COMPUTER_TOWER, t!("network.node"))
|
||||
};
|
||||
@@ -525,7 +532,7 @@ impl WalletsContent {
|
||||
if self.pass_edit.is_empty() {
|
||||
return;
|
||||
}
|
||||
match self.wallets.open_selected(self.pass_edit.clone()) {
|
||||
match self.wallets.launch_selected(self.pass_edit.clone()) {
|
||||
Ok(_) => {
|
||||
// Clear values.
|
||||
self.pass_edit = "".to_string();
|
||||
|
||||
@@ -271,8 +271,8 @@ impl WalletCreation {
|
||||
let name = self.name_edit.clone();
|
||||
let pass = self.pass_edit.clone();
|
||||
let phrase = self.mnemonic_setup.mnemonic.get_phrase();
|
||||
let ext_conn = self.network_setup.get_ext_conn_url();
|
||||
let wallet = Wallet::create(name, pass.clone(), phrase, ext_conn).unwrap();
|
||||
let conn_method = &self.network_setup.method;
|
||||
let wallet = Wallet::create(name, pass.clone(), phrase, conn_method).unwrap();
|
||||
// Open created wallet.
|
||||
wallet.open(pass).unwrap();
|
||||
// Pass created wallet to callback.
|
||||
|
||||
@@ -20,13 +20,13 @@ use crate::gui::icons::{GLOBE, GLOBE_SIMPLE};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::wallets::setup::ConnectionMethod;
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection};
|
||||
use crate::wallet::types::ConnectionMethod;
|
||||
|
||||
/// Wallet node connection method setup content.
|
||||
pub struct ConnectionSetup {
|
||||
/// Selected connection method.
|
||||
method: ConnectionMethod,
|
||||
pub method: ConnectionMethod,
|
||||
|
||||
/// Flag to check if modal was just opened.
|
||||
first_modal_launch: bool,
|
||||
@@ -82,14 +82,6 @@ impl ConnectionSetup {
|
||||
// Self { method: ConnectionMethod::Integrated }
|
||||
// }
|
||||
|
||||
/// Get external connection URL.
|
||||
pub fn get_ext_conn_url(&self) -> Option<String> {
|
||||
match &self.method {
|
||||
ConnectionMethod::Integrated => None,
|
||||
ConnectionMethod::External(url) => Some(url.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, frame, cb);
|
||||
@@ -122,10 +114,10 @@ impl ConnectionSetup {
|
||||
ui.add_space(12.0);
|
||||
|
||||
// Show external nodes URLs selection.
|
||||
for conn in ConnectionsConfig::external_connections() {
|
||||
for conn in ConnectionsConfig::ext_conn_list() {
|
||||
View::radio_value(ui,
|
||||
&mut self.method,
|
||||
ConnectionMethod::External(conn.url.clone()),
|
||||
ConnectionMethod::External(conn.id),
|
||||
conn.url);
|
||||
ui.add_space(12.0);
|
||||
}
|
||||
@@ -162,7 +154,7 @@ impl ConnectionSetup {
|
||||
|
||||
// Draw node URL text edit.
|
||||
let url_edit_resp = egui::TextEdit::singleline(&mut self.ext_node_url_edit)
|
||||
.id(Id::from(modal.id).with("node_url_edit"))
|
||||
.id(Id::from(modal.id))
|
||||
.font(TextStyle::Heading)
|
||||
.desired_width(ui.available_width())
|
||||
.cursor_at_end(true)
|
||||
@@ -230,10 +222,10 @@ impl ConnectionSetup {
|
||||
Some(self.ext_node_secret_edit.to_owned())
|
||||
};
|
||||
let ext_conn = ExternalConnection::new(url.clone(), secret);
|
||||
ConnectionsConfig::add_external_connection(ext_conn);
|
||||
ConnectionsConfig::add_ext_conn(ext_conn.clone());
|
||||
|
||||
// Set added connection as current.
|
||||
self.method = ConnectionMethod::External(url);
|
||||
self.method = ConnectionMethod::External(ext_conn.id);
|
||||
|
||||
// Close modal.
|
||||
cb.hide_keyboard();
|
||||
|
||||
@@ -13,7 +13,4 @@
|
||||
// limitations under the License.
|
||||
|
||||
mod connection;
|
||||
pub use connection::ConnectionSetup;
|
||||
|
||||
mod types;
|
||||
pub use types::*;
|
||||
pub use connection::ConnectionSetup;
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
/// Wallet node connection method type.
|
||||
#[derive(PartialEq)]
|
||||
pub enum ConnectionMethod {
|
||||
/// Integrated node connection.
|
||||
Integrated,
|
||||
/// External node connection.
|
||||
External(String)
|
||||
}
|
||||
@@ -15,13 +15,13 @@
|
||||
use egui::{Margin, RichText};
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{DOWNLOAD, UPLOAD, WALLET, WRENCH};
|
||||
use crate::gui::icons::{DOWNLOAD, POWER, UPLOAD, WALLET, WRENCH};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::View;
|
||||
use crate::gui::views::{Root, View};
|
||||
use crate::gui::views::wallets::{WalletInfo, WalletReceive, WalletSend, WalletSettings};
|
||||
use crate::gui::views::wallets::types::{WalletTab, WalletTabType};
|
||||
use crate::node::Node;
|
||||
use crate::wallet::{Wallet, Wallets};
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Selected and opened wallet content.
|
||||
pub struct WalletContent {
|
||||
@@ -71,11 +71,12 @@ impl WalletContent {
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
self.current_tab.ui(ui, frame, wallet, cb);
|
||||
});
|
||||
|
||||
// Refresh content after delay for loaded wallet.
|
||||
if wallet.is_loaded() {
|
||||
ui.ctx().request_repaint_after(Wallets::INFO_UPDATE_DELAY);
|
||||
if wallet.get_info().is_some() {
|
||||
ui.ctx().request_repaint_after(Wallet::INFO_UPDATE_DELAY);
|
||||
} else {
|
||||
ui.ctx().request_repaint();
|
||||
}
|
||||
@@ -117,34 +118,48 @@ impl WalletContent {
|
||||
}
|
||||
|
||||
/// Content to draw when wallet is loading.
|
||||
fn loading_ui(ui: &mut egui::Ui, wallet: &Wallet) {
|
||||
if wallet.config.external_node_url.is_none() && !Node::is_running() {
|
||||
|
||||
pub fn show_loading_ui(ui: &mut egui::Ui, frame: &mut eframe::Frame, wallet: &Wallet) -> bool {
|
||||
if wallet.config.ext_conn_id.is_none() && !Node::is_running() {
|
||||
let dual_panel_root = Root::is_dual_panel_mode(frame);
|
||||
View::center_content(ui, if !dual_panel_root { 162.0 } else { 96.0 }, |ui| {
|
||||
let text = t!("wallets.enable_node", "settings" => WRENCH);
|
||||
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||
// Show button to enable integrated node at non-dual root panel mode.
|
||||
if !dual_panel_root {
|
||||
ui.add_space(8.0);
|
||||
let enable_node_text = format!("{} {}", POWER, t!("network.enable_node"));
|
||||
View::button(ui, enable_node_text, Colors::GOLD, || {
|
||||
Node::start();
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
if let Some(error) = &wallet.loading_error {
|
||||
// View::center_content(ui, 162.0, |ui| {
|
||||
// let text = t!("wallets.enable_node", "settings" => WRENCH);
|
||||
// View::big_loading_spinner(ui);
|
||||
// ui.add_space(18.0);
|
||||
// let text = if wallet.loading_progress == 0 {
|
||||
// t!("wallet_loading")
|
||||
// } else {
|
||||
// format!("{}: {}%", t!("wallet_loading"), wallet.loading_progress)
|
||||
// };
|
||||
// ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||
// });
|
||||
} else if !wallet.is_loaded() {
|
||||
View::center_content(ui, 162.0, |ui| {
|
||||
View::big_loading_spinner(ui);
|
||||
ui.add_space(18.0);
|
||||
let text = if wallet.loading_progress == 0 {
|
||||
t!("wallets.wallet_loading")
|
||||
} else {
|
||||
format!("{}: {}%", t!("wallets.wallet_loading"), wallet.loading_progress)
|
||||
};
|
||||
if wallet.get_info().is_none() || wallet.loading_progress() < 100 {
|
||||
if let Some(error) = &wallet.loading_error {
|
||||
println!("e: {}", error);
|
||||
let text = t!("wallets.wallet_loading_err");
|
||||
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||
});
|
||||
//TODO: button to retry.
|
||||
} else {
|
||||
View::center_content(ui, 162.0, |ui| {
|
||||
View::big_loading_spinner(ui);
|
||||
ui.add_space(18.0);
|
||||
// Setup loading progress text.
|
||||
let progress = wallet.loading_progress();
|
||||
let text = if progress == 0 {
|
||||
t!("wallets.wallet_loading")
|
||||
} else {
|
||||
format!("{}: {}%", t!("wallets.wallet_loading"), progress)
|
||||
};
|
||||
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||
});
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
println!("12345 info!!!");
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::wallets::types::WalletTab;
|
||||
use crate::gui::views::wallets::wallet::types::WalletTabType;
|
||||
use crate::gui::views::wallets::wallet::WalletContent;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Wallet info tab content.
|
||||
#[derive(Default)]
|
||||
@@ -25,6 +27,11 @@ impl WalletTab for WalletInfo {
|
||||
WalletTabType::Info
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
frame: &mut eframe::Frame,
|
||||
wallet: &Wallet,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
WalletContent::show_loading_ui(ui, frame, wallet);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Receive funds tab content.
|
||||
#[derive(Default)]
|
||||
@@ -24,6 +25,6 @@ impl WalletTab for WalletReceive {
|
||||
WalletTabType::Receive
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Send funds tab content.
|
||||
#[derive(Default)]
|
||||
@@ -24,6 +25,6 @@ impl WalletTab for WalletSend {
|
||||
WalletTabType::Send
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Wallet settings tab content.
|
||||
#[derive(Default)]
|
||||
@@ -24,6 +25,6 @@ impl WalletTab for WalletSettings {
|
||||
WalletTabType::Settings
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,16 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Wallet tab content interface.
|
||||
pub trait WalletTab {
|
||||
fn get_type(&self) -> WalletTabType;
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks);
|
||||
fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
frame: &mut eframe::Frame,
|
||||
wallet: &Wallet,
|
||||
cb: &dyn PlatformCallbacks);
|
||||
}
|
||||
|
||||
/// Type of [`WalletTab`] content.
|
||||
|
||||
Reference in New Issue
Block a user