From 91e743fab5f85ff33f97c0143ec6d5006afb0fcb Mon Sep 17 00:00:00 2001 From: ardocrat Date: Tue, 4 Jul 2023 00:39:13 +0300 Subject: [PATCH] config + ui: settings source files location/names refactoring, reset node settings to default values --- locales/en.yml | 4 +- locales/ru.yml | 4 +- src/gui/views/network.rs | 4 +- src/gui/views/network/configs.rs | 19 ++ .../{settings => configs}/dandelion.rs | 0 .../network/{settings => configs}/p2p.rs | 0 .../network/{settings => configs}/pool.rs | 0 .../network/{settings => configs}/server.rs | 18 +- .../network/{settings => configs}/stratum.rs | 18 +- src/gui/views/network/container.rs | 15 +- src/gui/views/network/mining.rs | 2 +- src/gui/views/network/node_settings.rs | 197 -------------- src/gui/views/network/settings.rs | 249 +++++++++++++++++- src/node/config.rs | 32 ++- 14 files changed, 324 insertions(+), 238 deletions(-) create mode 100644 src/gui/views/network/configs.rs rename src/gui/views/network/{settings => configs}/dandelion.rs (100%) rename src/gui/views/network/{settings => configs}/p2p.rs (100%) rename src/gui/views/network/{settings => configs}/pool.rs (100%) rename src/gui/views/network/{settings => configs}/server.rs (97%) rename src/gui/views/network/{settings => configs}/stratum.rs (95%) delete mode 100644 src/gui/views/network/node_settings.rs diff --git a/locales/en.yml b/locales/en.yml index 557cdf3..9a187a2 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -98,11 +98,13 @@ network_settings: attempt_time: Attempt time attempt_time_desc: The amount of time in seconds to attempt to mine on a particular header before stopping and re-collecting transactions from the pool min_share_diff: The minimum acceptable share difficulty - reset_settings_desc: Reset integrated node settings to default values + reset_settings_desc: Reset node settings to default values reset_settings: Reset settings + reset: Reset modal: cancel: Cancel save: Save + confirmation: Confirmation modal_exit: description: Are you sure you want to quit the application? exit: Exit \ No newline at end of file diff --git a/locales/ru.yml b/locales/ru.yml index 71b0bc7..306db6e 100644 --- a/locales/ru.yml +++ b/locales/ru.yml @@ -98,11 +98,13 @@ network_settings: attempt_time: Время попытки attempt_time_desc: Количество времени в секундах для попытки майнинга на определённом заголовке перед остановкой и повторным сбором транзакций из пула min_share_diff: Минимальная допустимая сложность шары - reset_settings_desc: Сбросить настройки встроенного узла до стандартных значений + reset_settings_desc: Сбросить настройки узла до стандартных значений reset_settings: Сброс настроек + reset: Сбросить modal: cancel: Отмена save: Сохранить + confirmation: Подтверждение modal_exit: description: Вы уверены, что хотите выйти из приложения? exit: Выход \ No newline at end of file diff --git a/src/gui/views/network.rs b/src/gui/views/network.rs index ebad78c..0f7848d 100644 --- a/src/gui/views/network.rs +++ b/src/gui/views/network.rs @@ -15,8 +15,8 @@ mod container; mod metrics; mod mining; -mod node_settings; -mod node; mod settings; +mod node; +mod configs; pub use container::*; \ No newline at end of file diff --git a/src/gui/views/network/configs.rs b/src/gui/views/network/configs.rs new file mode 100644 index 0000000..b3666e1 --- /dev/null +++ b/src/gui/views/network/configs.rs @@ -0,0 +1,19 @@ +// 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. + +pub mod stratum; +pub mod server; +pub mod p2p; +pub mod pool; +pub mod dandelion; \ No newline at end of file diff --git a/src/gui/views/network/settings/dandelion.rs b/src/gui/views/network/configs/dandelion.rs similarity index 100% rename from src/gui/views/network/settings/dandelion.rs rename to src/gui/views/network/configs/dandelion.rs diff --git a/src/gui/views/network/settings/p2p.rs b/src/gui/views/network/configs/p2p.rs similarity index 100% rename from src/gui/views/network/settings/p2p.rs rename to src/gui/views/network/configs/p2p.rs diff --git a/src/gui/views/network/settings/pool.rs b/src/gui/views/network/configs/pool.rs similarity index 100% rename from src/gui/views/network/settings/pool.rs rename to src/gui/views/network/configs/pool.rs diff --git a/src/gui/views/network/settings/server.rs b/src/gui/views/network/configs/server.rs similarity index 97% rename from src/gui/views/network/settings/server.rs rename to src/gui/views/network/configs/server.rs index 6e55e9c..91b0dcf 100644 --- a/src/gui/views/network/settings/server.rs +++ b/src/gui/views/network/configs/server.rs @@ -21,7 +21,7 @@ use crate::gui::{Colors, Navigator}; use crate::gui::icons::{CLIPBOARD_TEXT, CLOCK_CLOCKWISE, COMPUTER_TOWER, COPY, PLUG, POWER, SHIELD, SHIELD_SLASH}; use crate::gui::platform::PlatformCallbacks; use crate::gui::views::{Modal, ModalPosition, NetworkContainer, View}; -use crate::gui::views::network::node_settings::NetworkNodeSettings; +use crate::gui::views::network::settings::NetworkSettings; use crate::node::{Node, NodeConfig}; /// Integrated node server setup ui section. @@ -129,7 +129,7 @@ impl ServerSetup { let addrs = NodeConfig::get_ip_addrs(); if addrs.is_empty() { // Show message when IP addresses are not available on the system. - NetworkNodeSettings::no_ip_address_ui(ui); + NetworkSettings::no_ip_address_ui(ui); ui.add_space(4.0); } else { @@ -145,7 +145,7 @@ impl ServerSetup { // Show API IP addresses to select. let (api_ip, api_port) = NodeConfig::get_api_address(); - NetworkNodeSettings::ip_addrs_ui(ui, &api_ip, &addrs, |selected_ip| { + NetworkSettings::ip_addrs_ui(ui, &api_ip, &addrs, |selected_ip| { let api_available = NodeConfig::is_api_port_available(selected_ip, &api_port); self.is_api_port_available = api_available; NodeConfig::save_api_address(selected_ip, &api_port); @@ -232,7 +232,7 @@ impl ServerSetup { if saved_chain_type != selected_chain_type { AppConfig::change_chain_type(&selected_chain_type); - NetworkNodeSettings::show_node_restart_required_modal(); + NetworkSettings::show_node_restart_required_modal(); } } @@ -293,7 +293,7 @@ impl ServerSetup { .size(16.0) .color(Colors::RED)); } else { - NetworkNodeSettings::node_restart_required_ui(ui); + NetworkSettings::node_restart_required_ui(ui); } ui.add_space(12.0); }); @@ -434,7 +434,7 @@ impl ServerSetup { }); // Show reminder to restart enabled node. - NetworkNodeSettings::node_restart_required_ui(ui); + NetworkSettings::node_restart_required_ui(ui); ui.add_space(12.0); }); @@ -524,7 +524,7 @@ impl ServerSetup { .size(18.0) .color(Colors::RED)); } else { - NetworkNodeSettings::node_restart_required_ui(ui); + NetworkSettings::node_restart_required_ui(ui); } ui.add_space(12.0); }); @@ -564,7 +564,7 @@ impl ServerSetup { let validate = NodeConfig::is_full_chain_validation(); View::checkbox(ui, validate, t!("network_settings.full_validation"), || { NodeConfig::toggle_full_chain_validation(); - NetworkNodeSettings::show_node_restart_required_modal(); + NetworkSettings::show_node_restart_required_modal(); }); ui.add_space(4.0); ui.label(RichText::new(t!("network_settings.full_validation_description")) @@ -578,7 +578,7 @@ impl ServerSetup { let archive_mode = NodeConfig::is_archive_mode(); View::checkbox(ui, archive_mode, t!("network_settings.archive_mode"), || { NodeConfig::toggle_archive_mode(); - NetworkNodeSettings::show_node_restart_required_modal(); + NetworkSettings::show_node_restart_required_modal(); }); ui.add_space(4.0); ui.label(RichText::new(t!("network_settings.archive_mode_desc")) diff --git a/src/gui/views/network/settings/stratum.rs b/src/gui/views/network/configs/stratum.rs similarity index 95% rename from src/gui/views/network/settings/stratum.rs rename to src/gui/views/network/configs/stratum.rs index 7600341..0951fb9 100644 --- a/src/gui/views/network/settings/stratum.rs +++ b/src/gui/views/network/configs/stratum.rs @@ -18,7 +18,7 @@ use crate::gui::{Colors, Navigator}; use crate::gui::icons::{BARBELL, HARD_DRIVES, PLUG, TIMER}; use crate::gui::platform::PlatformCallbacks; use crate::gui::views::{Modal, ModalPosition, View}; -use crate::gui::views::network::node_settings::NetworkNodeSettings; +use crate::gui::views::network::settings::NetworkSettings; use crate::node::{Node, NodeConfig}; /// Stratum server setup ui section. @@ -59,9 +59,9 @@ impl StratumServerSetup { /// Identifier for stratum port [`Modal`]. pub const STRATUM_PORT_MODAL: &'static str = "stratum_port"; /// Identifier for attempt time [`Modal`]. - pub const STRATUM_ATTEMPT_TIME_MODAL: &'static str = "stratum_attempt_time"; + pub const ATTEMPT_TIME_MODAL: &'static str = "stratum_attempt_time"; /// Identifier for minimum share difficulty [`Modal`]. - pub const STRATUM_MIN_SHARE_MODAL: &'static str = "stratum_min_share"; + pub const MIN_SHARE_DIFF_MODAL: &'static str = "stratum_min_share_diff"; pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) { View::sub_title(ui, format!("{} {}", HARD_DRIVES, t!("network_mining.server_setup"))); @@ -100,7 +100,7 @@ impl StratumServerSetup { // Show message when IP addresses are not available on the system. let all_ips = NodeConfig::get_ip_addrs(); if all_ips.is_empty() { - NetworkNodeSettings::no_ip_address_ui(ui); + NetworkSettings::no_ip_address_ui(ui); return; } @@ -112,7 +112,7 @@ impl StratumServerSetup { ui.add_space(6.0); // Show stratum IP addresses to select. let (ip, port) = NodeConfig::get_stratum_address(); - NetworkNodeSettings::ip_addrs_ui(ui, &ip, &all_ips, |selected_ip| { + NetworkSettings::ip_addrs_ui(ui, &ip, &all_ips, |selected_ip| { NodeConfig::save_stratum_address(selected_ip, &port); self.is_port_available = NodeConfig::is_stratum_port_available(selected_ip, &port); @@ -253,7 +253,7 @@ impl StratumServerSetup { self.attempt_time_edit = time; // Show attempt time modal. - let time_modal = Modal::new(Self::STRATUM_ATTEMPT_TIME_MODAL) + let time_modal = Modal::new(Self::ATTEMPT_TIME_MODAL) .position(ModalPosition::CenterTop) .title(t!("network_settings.change_value")); Navigator::show_modal(time_modal); @@ -290,7 +290,7 @@ impl StratumServerSetup { .size(18.0) .color(Colors::RED)); } else { - NetworkNodeSettings::node_restart_required_ui(ui); + NetworkSettings::node_restart_required_ui(ui); } ui.add_space(12.0); }); @@ -339,7 +339,7 @@ impl StratumServerSetup { self.min_share_diff_edit = diff; // Show attempt time modal. - let diff_modal = Modal::new(Self::STRATUM_MIN_SHARE_MODAL) + let diff_modal = Modal::new(Self::MIN_SHARE_DIFF_MODAL) .position(ModalPosition::CenterTop) .title(t!("network_settings.change_value")); Navigator::show_modal(diff_modal); @@ -376,7 +376,7 @@ impl StratumServerSetup { .size(18.0) .color(Colors::RED)); } else { - NetworkNodeSettings::node_restart_required_ui(ui); + NetworkSettings::node_restart_required_ui(ui); } ui.add_space(12.0); }); diff --git a/src/gui/views/network/container.rs b/src/gui/views/network/container.rs index 1016c36..9696b62 100644 --- a/src/gui/views/network/container.rs +++ b/src/gui/views/network/container.rs @@ -24,12 +24,12 @@ use crate::gui::{Colors, Navigator}; use crate::gui::icons::{CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE}; use crate::gui::platform::PlatformCallbacks; use crate::gui::views::{Modal, ModalContainer, View}; +use crate::gui::views::network::configs::server::ServerSetup; +use crate::gui::views::network::configs::stratum::StratumServerSetup; use crate::gui::views::network::metrics::NetworkMetrics; use crate::gui::views::network::mining::NetworkMining; use crate::gui::views::network::node::NetworkNode; -use crate::gui::views::network::node_settings::NetworkNodeSettings; -use crate::gui::views::network::settings::server::ServerSetup; -use crate::gui::views::network::settings::stratum::StratumServerSetup; +use crate::gui::views::network::settings::NetworkSettings; use crate::node::Node; pub trait NetworkTab { @@ -67,10 +67,11 @@ impl Default for NetworkContainer { Self { current_tab: Box::new(NetworkNode::default()), modal_ids: vec![ - NetworkNodeSettings::NODE_RESTART_REQUIRED_MODAL, + NetworkSettings::NODE_RESTART_REQUIRED_MODAL, + NetworkSettings::RESET_SETTINGS_MODAL, StratumServerSetup::STRATUM_PORT_MODAL, - StratumServerSetup::STRATUM_ATTEMPT_TIME_MODAL, - StratumServerSetup::STRATUM_MIN_SHARE_MODAL, + StratumServerSetup::ATTEMPT_TIME_MODAL, + StratumServerSetup::MIN_SHARE_DIFF_MODAL, ServerSetup::API_PORT_MODAL, ServerSetup::API_SECRET_MODAL, ServerSetup::FOREIGN_API_SECRET_MODAL, @@ -155,7 +156,7 @@ impl NetworkContainer { }); columns[3].vertical_centered_justified(|ui| { View::tab_button(ui, FADERS, self.is_current_tab(NetworkTabType::Settings), || { - self.current_tab = Box::new(NetworkNodeSettings::default()); + self.current_tab = Box::new(NetworkSettings::default()); }); }); }); diff --git a/src/gui/views/network/mining.rs b/src/gui/views/network/mining.rs index 942c4f8..e670a51 100644 --- a/src/gui/views/network/mining.rs +++ b/src/gui/views/network/mining.rs @@ -22,7 +22,7 @@ use crate::gui::icons::{BARBELL, CLOCK_AFTERNOON, COMPUTER_TOWER, CPU, CUBE, FAD use crate::gui::platform::PlatformCallbacks; use crate::gui::views::{Modal, NetworkContainer, View}; use crate::gui::views::network::{NetworkTab, NetworkTabType}; -use crate::gui::views::network::settings::stratum::StratumServerSetup; +use crate::gui::views::network::configs::stratum::StratumServerSetup; use crate::node::{Node, NodeConfig}; #[derive(Default)] diff --git a/src/gui/views/network/node_settings.rs b/src/gui/views/network/node_settings.rs deleted file mode 100644 index afc9862..0000000 --- a/src/gui/views/network/node_settings.rs +++ /dev/null @@ -1,197 +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. - -use std::net::IpAddr; -use std::str::FromStr; - -use egui::{RichText, ScrollArea}; - -use crate::gui::{Colors, Navigator}; -use crate::gui::platform::PlatformCallbacks; -use crate::gui::views::{Modal, ModalPosition, View}; -use crate::gui::views::network::{NetworkTab, NetworkTabType}; -use crate::gui::views::network::settings::server::ServerSetup; -use crate::gui::views::network::settings::stratum::StratumServerSetup; -use crate::node::Node; - -#[derive(Default)] -pub struct NetworkNodeSettings { - server_setup: ServerSetup, - stratum_server_setup: StratumServerSetup -} - -impl NetworkTab for NetworkNodeSettings { - fn get_type(&self) -> NetworkTabType { - NetworkTabType::Settings - } - - fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) { - ScrollArea::vertical() - .id_source("network_settings") - .auto_shrink([false; 2]) - .show(ui, |ui| { - self.server_setup.ui(ui, cb); - self.stratum_server_setup.ui(ui, cb); - }); - } - - fn on_modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) { - match modal.id { - Self::NODE_RESTART_REQUIRED_MODAL => { - self.node_restart_required_modal(ui, modal); - } - - ServerSetup::API_PORT_MODAL => { - self.server_setup.api_port_modal(ui, modal, cb); - }, - ServerSetup::API_SECRET_MODAL => { - self.server_setup.secret_modal(ui, modal, cb); - }, - ServerSetup::FOREIGN_API_SECRET_MODAL => { - self.server_setup.secret_modal(ui, modal, cb); - }, - ServerSetup::FTL_MODAL => { - self.server_setup.ftl_modal(ui, modal, cb); - }, - - StratumServerSetup::STRATUM_PORT_MODAL => { - self.stratum_server_setup.port_modal(ui, modal, cb); - } - StratumServerSetup::STRATUM_ATTEMPT_TIME_MODAL => { - self.stratum_server_setup.attempt_modal(ui, modal, cb); - } - StratumServerSetup::STRATUM_MIN_SHARE_MODAL => { - self.stratum_server_setup.min_diff_modal(ui, modal, cb); - } - _ => {} - } - } -} - -impl NetworkNodeSettings { - pub const NODE_RESTART_REQUIRED_MODAL: &'static str = "node_restart_required"; - - /// Reminder to restart enabled node to show on edit setting at [`Modal`]. - pub fn node_restart_required_ui(ui: &mut egui::Ui) { - if Node::is_running() { - ui.add_space(12.0); - ui.label(RichText::new(t!("network_settings.restart_node_required")) - .size(16.0) - .color(Colors::GREEN) - ); - } - } - - /// Show [`Modal`] to ask node restart if setting is changed on enabled node. - pub fn show_node_restart_required_modal() { - if Node::is_running() { - // Show modal to apply changes by node restart. - let port_modal = Modal::new(NetworkNodeSettings::NODE_RESTART_REQUIRED_MODAL) - .position(ModalPosition::Center) - .title(t!("network.settings")); - Navigator::show_modal(port_modal); - } - } - - /// Node restart reminder modal content. - fn node_restart_required_modal(&self, ui: &mut egui::Ui, modal: &Modal) { - ui.add_space(6.0); - ui.vertical_centered(|ui| { - ui.label(RichText::new(t!("network_settings.restart_node_required")) - .size(18.0) - .color(Colors::GRAY)); - ui.add_space(8.0); - }); - - // Show modal buttons. - ui.scope(|ui| { - // Setup spacing between buttons. - ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0); - - ui.columns(2, |columns| { - columns[0].vertical_centered_justified(|ui| { - View::button(ui, t!("network_settings.restart"), Colors::WHITE, || { - Node::restart(); - modal.close(); - }); - }); - columns[1].vertical_centered_justified(|ui| { - View::button(ui, t!("modal.cancel"), Colors::WHITE, || { - modal.close(); - }); - }); - }); - ui.add_space(6.0); - }); - } - - /// Draw IP addresses as radio buttons. - pub fn ip_addrs_ui(ui: &mut egui::Ui, - saved_ip: &String, - ip_addrs: &Vec, - on_change: impl FnOnce(&String)) { - let saved_ip_addr = &IpAddr::from_str(saved_ip.as_str()).unwrap(); - let mut selected_ip_addr = saved_ip_addr; - - // Set first IP address as current if saved is not present at system. - if !ip_addrs.contains(selected_ip_addr) { - selected_ip_addr = ip_addrs.get(0).unwrap(); - } - - ui.add_space(2.0); - // Show available IP addresses on the system. - let _ = ip_addrs.chunks(2).map(|x| { - if x.len() == 2 { - ui.columns(2, |columns| { - let ip_addr_l = x.get(0).unwrap(); - columns[0].vertical_centered(|ui| { - View::radio_value(ui, - &mut selected_ip_addr, - ip_addr_l, - ip_addr_l.to_string()); - }); - let ip_addr_r = x.get(1).unwrap(); - columns[1].vertical_centered(|ui| { - View::radio_value(ui, - &mut selected_ip_addr, - ip_addr_r, - ip_addr_r.to_string()); - }) - }); - } else { - let ip_addr = x.get(0).unwrap(); - View::radio_value(ui, - &mut selected_ip_addr, - ip_addr, - ip_addr.to_string()); - } - ui.add_space(12.0); - }).collect::>(); - - if saved_ip_addr != selected_ip_addr { - (on_change)(&selected_ip_addr.to_string()); - } - } - - /// Show message when IP addresses are not available at system. - pub fn no_ip_address_ui(ui: &mut egui::Ui) { - ui.vertical_centered(|ui| { - ui.label(RichText::new(t!("network.no_ips")) - .size(16.0) - .color(Colors::INACTIVE_TEXT) - ); - ui.add_space(6.0); - }); - } -} \ No newline at end of file diff --git a/src/gui/views/network/settings.rs b/src/gui/views/network/settings.rs index b3666e1..28d8763 100644 --- a/src/gui/views/network/settings.rs +++ b/src/gui/views/network/settings.rs @@ -12,8 +12,247 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod stratum; -pub mod server; -pub mod p2p; -pub mod pool; -pub mod dandelion; \ No newline at end of file +use std::net::IpAddr; +use std::str::FromStr; + +use egui::{RichText, ScrollArea}; + +use crate::gui::{Colors, Navigator}; +use crate::gui::icons::ARROW_COUNTER_CLOCKWISE; +use crate::gui::platform::PlatformCallbacks; +use crate::gui::views::{Modal, ModalPosition, View}; +use crate::gui::views::network::{NetworkTab, NetworkTabType}; +use crate::gui::views::network::configs::server::ServerSetup; +use crate::gui::views::network::configs::stratum::StratumServerSetup; +use crate::node::{Node, NodeConfig}; + +#[derive(Default)] +pub struct NetworkSettings { + server_setup: ServerSetup, + stratum_server_setup: StratumServerSetup +} + +impl NetworkTab for NetworkSettings { + fn get_type(&self) -> NetworkTabType { + NetworkTabType::Settings + } + + fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) { + ScrollArea::vertical() + .id_source("network_settings") + .auto_shrink([false; 2]) + .show(ui, |ui| { + self.server_setup.ui(ui, cb); + self.stratum_server_setup.ui(ui, cb); + self.reset_settings_ui(ui); + }); + } + + fn on_modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) { + match modal.id { + Self::NODE_RESTART_REQUIRED_MODAL => self.node_restart_required_modal(ui, modal), + Self::RESET_SETTINGS_MODAL => self.reset_settings_confirmation_modal(ui, modal), + + ServerSetup::API_PORT_MODAL => self.server_setup.api_port_modal(ui, modal, cb), + ServerSetup::API_SECRET_MODAL => self.server_setup.secret_modal(ui, modal, cb), + ServerSetup::FOREIGN_API_SECRET_MODAL => self.server_setup.secret_modal(ui, modal, cb), + ServerSetup::FTL_MODAL => self.server_setup.ftl_modal(ui, modal, cb), + + StratumServerSetup::STRATUM_PORT_MODAL => { + self.stratum_server_setup.port_modal(ui, modal, cb); + } + StratumServerSetup::ATTEMPT_TIME_MODAL => { + self.stratum_server_setup.attempt_modal(ui, modal, cb); + } + StratumServerSetup::MIN_SHARE_DIFF_MODAL => { + self.stratum_server_setup.min_diff_modal(ui, modal, cb); + } + _ => {} + } + } +} + +impl NetworkSettings { + /// Identifier for node restart confirmation [`Modal`]. + pub const NODE_RESTART_REQUIRED_MODAL: &'static str = "node_restart_required"; + /// Identifier for settings reset confirmation [`Modal`]. + pub const RESET_SETTINGS_MODAL: &'static str = "reset_settings"; + + /// Draw button to reset integrated node settings to default values. + fn reset_settings_ui(&self, ui: &mut egui::Ui) { + View::horizontal_line(ui, Colors::ITEM_STROKE); + ui.add_space(6.0); + ui.vertical_centered(|ui| { + ui.label(RichText::new(t!("network_settings.reset_settings_desc")) + .size(16.0) + .color(Colors::TEXT)); + ui.add_space(10.0); + let button_text = format!("{} {}", + ARROW_COUNTER_CLOCKWISE, + t!("network_settings.reset_settings")); + View::button(ui, button_text, Colors::GOLD, || { + // Show modal to confirm settings reset. + let reset_modal = Modal::new(Self::RESET_SETTINGS_MODAL) + .position(ModalPosition::Center) + .title(t!("modal.confirmation")); + Navigator::show_modal(reset_modal); + }); + + // Show reminder to restart enabled node. + if Node::is_running() { + ui.add_space(12.0); + ui.label(RichText::new(t!("network_settings.restart_node_required")) + .size(16.0) + .color(Colors::GRAY) + ); + } + ui.add_space(12.0); + }); + + } + + /// Confirmation to reset settings to default values. + fn reset_settings_confirmation_modal(&self, ui: &mut egui::Ui, modal: &Modal) { + ui.add_space(6.0); + ui.vertical_centered(|ui| { + ui.label(RichText::new(t!("network_settings.reset_settings_desc")) + .size(18.0) + .color(Colors::TEXT)); + ui.add_space(8.0); + }); + + // Show modal buttons. + ui.scope(|ui| { + // Setup spacing between buttons. + ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0); + + ui.columns(2, |columns| { + columns[0].vertical_centered_justified(|ui| { + View::button(ui, t!("network_settings.reset"), Colors::WHITE, || { + NodeConfig::reset_to_default(); + modal.close(); + }); + }); + columns[1].vertical_centered_justified(|ui| { + View::button(ui, t!("modal.cancel"), Colors::WHITE, || { + modal.close(); + }); + }); + }); + ui.add_space(6.0); + }); + } + + /// Reminder to restart enabled node to show on edit setting at [`Modal`]. + pub fn node_restart_required_ui(ui: &mut egui::Ui) { + if Node::is_running() { + ui.add_space(12.0); + ui.label(RichText::new(t!("network_settings.restart_node_required")) + .size(16.0) + .color(Colors::GREEN) + ); + } + } + + /// Show [`Modal`] to ask node restart if setting is changed on enabled node. + pub fn show_node_restart_required_modal() { + if Node::is_running() { + // Show modal to apply changes by node restart. + let port_modal = Modal::new(Self::NODE_RESTART_REQUIRED_MODAL) + .position(ModalPosition::Center) + .title(t!("network.settings")); + Navigator::show_modal(port_modal); + } + } + + /// Node restart reminder modal content. + fn node_restart_required_modal(&self, ui: &mut egui::Ui, modal: &Modal) { + ui.add_space(6.0); + ui.vertical_centered(|ui| { + ui.label(RichText::new(t!("network_settings.restart_node_required")) + .size(18.0) + .color(Colors::GRAY)); + ui.add_space(8.0); + }); + + // Show modal buttons. + ui.scope(|ui| { + // Setup spacing between buttons. + ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0); + + ui.columns(2, |columns| { + columns[0].vertical_centered_justified(|ui| { + View::button(ui, t!("network_settings.restart"), Colors::WHITE, || { + Node::restart(); + modal.close(); + }); + }); + columns[1].vertical_centered_justified(|ui| { + View::button(ui, t!("modal.cancel"), Colors::WHITE, || { + modal.close(); + }); + }); + }); + ui.add_space(6.0); + }); + } + + /// Draw IP addresses as radio buttons. + pub fn ip_addrs_ui(ui: &mut egui::Ui, + saved_ip: &String, + ip_addrs: &Vec, + on_change: impl FnOnce(&String)) { + let saved_ip_addr = &IpAddr::from_str(saved_ip.as_str()).unwrap(); + let mut selected_ip_addr = saved_ip_addr; + + // Set first IP address as current if saved is not present at system. + if !ip_addrs.contains(selected_ip_addr) { + selected_ip_addr = ip_addrs.get(0).unwrap(); + } + + ui.add_space(2.0); + // Show available IP addresses on the system. + let _ = ip_addrs.chunks(2).map(|x| { + if x.len() == 2 { + ui.columns(2, |columns| { + let ip_addr_l = x.get(0).unwrap(); + columns[0].vertical_centered(|ui| { + View::radio_value(ui, + &mut selected_ip_addr, + ip_addr_l, + ip_addr_l.to_string()); + }); + let ip_addr_r = x.get(1).unwrap(); + columns[1].vertical_centered(|ui| { + View::radio_value(ui, + &mut selected_ip_addr, + ip_addr_r, + ip_addr_r.to_string()); + }) + }); + } else { + let ip_addr = x.get(0).unwrap(); + View::radio_value(ui, + &mut selected_ip_addr, + ip_addr, + ip_addr.to_string()); + } + ui.add_space(12.0); + }).collect::>(); + + if saved_ip_addr != selected_ip_addr { + (on_change)(&selected_ip_addr.to_string()); + } + } + + /// Show message when IP addresses are not available at system. + pub fn no_ip_address_ui(ui: &mut egui::Ui) { + ui.vertical_centered(|ui| { + ui.label(RichText::new(t!("network.no_ips")) + .size(16.0) + .color(Colors::INACTIVE_TEXT) + ); + ui.add_space(6.0); + }); + } +} \ No newline at end of file diff --git a/src/node/config.rs b/src/node/config.rs index e99d100..6bb61b9 100644 --- a/src/node/config.rs +++ b/src/node/config.rs @@ -54,16 +54,22 @@ impl NodeConfig { let path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type)); let parsed = Settings::read_from_file::(path.clone()); if !path.exists() || parsed.is_err() { - let mut default_config = GlobalConfig::for_chain(chain_type); - default_config.update_paths(&Settings::get_working_path(Some(chain_type))); - let config = default_config.members.unwrap(); - Settings::write_to_file(&config, path); - config + Self::save_default_config(chain_type) } else { parsed.unwrap() } } + /// Generate and save default node config for specified [`ChainTypes`]. + fn save_default_config(chain_type: &ChainTypes) -> ConfigMembers { + let path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type)); + let mut default_config = GlobalConfig::for_chain(chain_type); + default_config.update_paths(&Settings::get_working_path(Some(chain_type))); + let config = default_config.members.unwrap(); + Settings::write_to_file(&config, path); + config + } + /// Save node config to disk. pub fn save(&mut self) { let config_path = Settings::get_config_path( @@ -73,12 +79,26 @@ impl NodeConfig { Settings::write_to_file(&self.members, config_path); } - /// Get node config values, requires to start node. + /// Get node config values. pub fn get_members() -> ConfigMembers { let r_config = Settings::node_config_to_read(); r_config.members.clone() } + /// Reset node config to default values. + pub fn reset_to_default() { + let chain_type = { + let r_config = Settings::node_config_to_read(); + r_config.members.server.chain_type + }; + let members = Self::save_default_config(&chain_type); + { + let mut w_node_config = Settings::node_config_to_update(); + w_node_config.members = members; + w_node_config.save(); + } + } + /// Check that the api secret files exist and are valid. fn check_api_secret_files( chain_type: &ChainTypes,