ui + config: optimize ip list at config ui, api port modal, update, translations, better check ports availability, refactor settings initialization and arguments passing
This commit is contained in:
parent
8fdc2c1e39
commit
1a74678c67
11 changed files with 381 additions and 248 deletions
|
@ -11,7 +11,7 @@ network:
|
|||
restart: Restart
|
||||
autorun: Autorun
|
||||
disabled_server: 'Enable integrated node or add another connection method by pressing %{dots} in the top-left corner of the screen.'
|
||||
no_ip_addresses: There are no available IP addresses on your system, server cannot be started, check your network connectivity.
|
||||
no_ips: There are no available IP addresses on your system, server cannot be started, check your network connectivity.
|
||||
sync_status:
|
||||
node_restarting: Node is restarting
|
||||
node_down: Node is down
|
||||
|
@ -60,7 +60,6 @@ network_mining:
|
|||
enable_server: Enable server
|
||||
server_setting: 'Enable stratum server or change more settings by selecting %{settings} at the bottom of the screen. App restart is required to change settings of the running server.'
|
||||
info: 'Mining server is enabled, you can change its settings by selecting %{settings} at the bottom of the screen. Data is updating when devices are connected.'
|
||||
port_unavailable: Specified port is unavailable
|
||||
rewards_wallet: Wallet for rewards
|
||||
server: Stratum server
|
||||
address: Address
|
||||
|
@ -72,15 +71,17 @@ network_mining:
|
|||
disconnected: Disconnected
|
||||
network_settings:
|
||||
port: Port
|
||||
ip_address: IP Address
|
||||
ip: IP Address
|
||||
change_port: Change port
|
||||
enter_value: 'Enter value:'
|
||||
server:
|
||||
title: Server
|
||||
enable: Enable
|
||||
disable: Disable
|
||||
restart: Restart
|
||||
api_ip_address: API IP Address
|
||||
enter_value: Enter value
|
||||
port_unavailable: Specified port is unavailable
|
||||
restart_app_required: App restart is required to apply changes.
|
||||
enable: Enable
|
||||
disable: Disable
|
||||
restart: Restart
|
||||
server: Server
|
||||
api_ip: API IP Address
|
||||
api_port: API Port
|
||||
modal:
|
||||
cancel: Cancel
|
||||
save: Save
|
||||
|
|
|
@ -11,7 +11,7 @@ network:
|
|||
restart: Перезапустить
|
||||
autorun: Автозапуск
|
||||
disabled_server: 'Включите встроенный узел или добавьте другой способ подключения, нажав %{dots} в левом-верхнем углу экрана.'
|
||||
no_ip_addresses: В вашей системе отсутствуют доступные IP адреса, запуск сервера невозможен, проверьте ваше подключение к сети.
|
||||
no_ips: В вашей системе отсутствуют доступные IP адреса, запуск сервера невозможен, проверьте ваше подключение к сети.
|
||||
sync_status:
|
||||
node_restarting: Узел перезапускается
|
||||
node_down: Узел выключен
|
||||
|
@ -60,7 +60,6 @@ network_mining:
|
|||
enable_server: Включить сервер
|
||||
server_setting: 'Включите stratum-сервер или измените больше настроек, выбрав %{settings} внизу экрана. Для изменения настроек запущенного сервера потребуется перезапуск приложения.'
|
||||
info: 'Сервер майнинга запущен, вы можете изменить его настройки, выбрав %{settings} внизу экрана. Данные обновляются, когда устройства подключены.'
|
||||
port_unavailable: Указанный порт недоступен
|
||||
rewards_wallet: Кошелёк для наград
|
||||
server: Stratum-сервер
|
||||
address: Адрес
|
||||
|
@ -71,20 +70,22 @@ network_mining:
|
|||
connected: Подключен
|
||||
disconnected: Отключен
|
||||
network_settings:
|
||||
ip_address: IP Адрес
|
||||
ip: IP Адрес
|
||||
port: Порт
|
||||
change_port: Изменить порт
|
||||
enter_value: 'Введите значение:'
|
||||
server:
|
||||
title: Сервер
|
||||
enable: Включить
|
||||
disable: Выключить
|
||||
restart: Перезапустить
|
||||
api_ip_address: API IP Адрес
|
||||
enter_value: Введите значение
|
||||
port_unavailable: Указанный порт недоступен
|
||||
restart_app_required: Для применения изменений требуется перезапуск приложения.
|
||||
enable: Включить
|
||||
disable: Выключить
|
||||
restart: Перезапустить
|
||||
server: Сервер
|
||||
api_ip: API IP Адрес
|
||||
api_port: API Порт
|
||||
modal:
|
||||
cancel: Отмена
|
||||
save: Сохранить
|
||||
confirmation: Подтверждение
|
||||
modal_exit:
|
||||
description: Вы уверены, что хотите выйти из приложения?
|
||||
exit: Выход
|
||||
exit: Выход
|
|
@ -45,7 +45,7 @@ impl Default for Root {
|
|||
}
|
||||
|
||||
impl ModalContainer for Root {
|
||||
fn allowed_modal_ids(&self) -> &Vec<&'static str> {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
self.allowed_modal_ids.as_ref()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,12 @@ use crate::gui::views::View;
|
|||
|
||||
/// Contains modal ids to draw at current container if possible.
|
||||
pub trait ModalContainer {
|
||||
fn allowed_modal_ids(&self) -> &Vec<&'static str>;
|
||||
/// List of modal ids to show at current view container.
|
||||
fn modal_ids(&self) -> &Vec<&'static str>;
|
||||
|
||||
/// Check if it's possible to show modal.
|
||||
fn can_show_modal(&self, id: &'static str) -> bool {
|
||||
self.allowed_modal_ids().contains(&id)
|
||||
self.modal_ids().contains(&id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ 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_settings::NetworkSettings;
|
||||
use crate::gui::views::settings_node::NodeSetup;
|
||||
use crate::gui::views::settings_stratum::StratumServerSetup;
|
||||
use crate::node::Node;
|
||||
use crate::Settings;
|
||||
|
@ -60,23 +61,24 @@ impl NetworkTabType {
|
|||
|
||||
pub struct Network {
|
||||
current_tab: Box<dyn NetworkTab>,
|
||||
allowed_modal_ids: Vec<&'static str>,
|
||||
modal_ids: Vec<&'static str>,
|
||||
}
|
||||
|
||||
impl Default for Network {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
current_tab: Box::new(NetworkNode::default()),
|
||||
allowed_modal_ids: vec![
|
||||
StratumServerSetup::STRATUM_PORT_MODAL
|
||||
modal_ids: vec![
|
||||
StratumServerSetup::STRATUM_PORT_MODAL,
|
||||
NodeSetup::API_PORT_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for Network {
|
||||
fn allowed_modal_ids(&self) -> &Vec<&'static str> {
|
||||
self.allowed_modal_ids.as_ref()
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
self.modal_ids.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,10 +280,57 @@ impl Network {
|
|||
addresses
|
||||
}
|
||||
|
||||
/// Draw IP list radio buttons.
|
||||
pub fn ip_list_ui(ui: &mut egui::Ui,
|
||||
saved_ip: &String,
|
||||
ips: &Vec<IpAddr>,
|
||||
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 !ips.contains(selected_ip_addr) {
|
||||
selected_ip_addr = ips.get(0).unwrap();
|
||||
}
|
||||
|
||||
// Show available IP addresses on the system.
|
||||
let _ = ips.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::<Vec<_>>();
|
||||
|
||||
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_ip_addresses"))
|
||||
ui.label(RichText::new(t!("network.no_ips"))
|
||||
.size(16.0)
|
||||
.color(Colors::INACTIVE_TEXT)
|
||||
);
|
||||
|
@ -290,10 +339,13 @@ impl Network {
|
|||
}
|
||||
|
||||
/// Check whether a port is available on the provided host.
|
||||
pub fn is_port_available(host: &str, port: u16) -> bool {
|
||||
let ip_addr = Ipv4Addr::from_str(host).unwrap();
|
||||
let ipv4 = SocketAddrV4::new(ip_addr, port);
|
||||
TcpListener::bind(ipv4).is_ok()
|
||||
pub fn is_port_available(host: &String, port: &String) -> bool {
|
||||
if let Ok(p) = port.parse::<u16>() {
|
||||
let ip_addr = Ipv4Addr::from_str(host.as_str()).unwrap();
|
||||
let ipv4 = SocketAddrV4::new(ip_addr, p);
|
||||
return TcpListener::bind(ipv4).is_ok();
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,29 +77,21 @@ impl NetworkTab for NetworkMining {
|
|||
ui.add_space(4.0);
|
||||
|
||||
// Show button to enable stratum server if port is available.
|
||||
if self.stratum_server_setup.is_stratum_port_available {
|
||||
if self.stratum_server_setup.is_port_available {
|
||||
ui.add_space(6.0);
|
||||
View::button(ui, t!("network_mining.enable_server"), Colors::GOLD, || {
|
||||
Node::start_stratum_server();
|
||||
});
|
||||
ui.add_space(2.0);
|
||||
|
||||
// Show stratum server autorun checkbox.
|
||||
let stratum_enabled = NodeConfig::is_stratum_autorun_enabled();
|
||||
View::checkbox(ui, stratum_enabled, t!("network.autorun"), || {
|
||||
NodeConfig::toggle_stratum_autorun();
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
|
||||
let stratum_enabled = Settings::node_config_to_read()
|
||||
.members.clone()
|
||||
.server.stratum_mining_config.unwrap()
|
||||
.enable_stratum_server.unwrap();
|
||||
|
||||
// Show stratum server autorun checkbox.
|
||||
View::checkbox(ui, stratum_enabled, t!("network.autorun"), || {
|
||||
let mut w_node_config = Settings::node_config_to_update();
|
||||
w_node_config.members
|
||||
.server.stratum_mining_config.as_mut().unwrap()
|
||||
.enable_stratum_server = Some(!stratum_enabled);
|
||||
w_node_config.save();
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
return;
|
||||
} else if Node::is_stratum_server_starting() {
|
||||
|
|
|
@ -37,6 +37,11 @@ impl NetworkTab for NetworkSettings {
|
|||
}
|
||||
|
||||
fn on_modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
|
||||
match modal.id {
|
||||
NodeSetup::API_PORT_MODAL => {
|
||||
self.node_setup.api_port_modal_ui(ui, modal, cb);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,24 +14,22 @@
|
|||
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use egui::RichText;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::COMPUTER_TOWER;
|
||||
use egui::{RichText, TextStyle, Widget};
|
||||
use crate::gui::{Colors, Navigator};
|
||||
use crate::gui::icons::{COMPUTER_TOWER, POWER};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Network, View};
|
||||
use crate::gui::views::{Modal, ModalPosition, Network, View};
|
||||
use crate::node::{Node, NodeConfig};
|
||||
|
||||
/// Integrated node server setup ui section.
|
||||
pub struct NodeSetup {
|
||||
/// API IP address to be used inside edit modal.
|
||||
api_address_edit: String,
|
||||
/// API port to be used inside edit modal.
|
||||
api_port_edit: String,
|
||||
/// Flag to check if API port is available inside edit modal.
|
||||
api_port_available_edit: bool,
|
||||
|
||||
/// Flag to check if API port is available from saved config value.
|
||||
pub(crate) api_port_available: bool,
|
||||
pub(crate) is_api_port_available: bool,
|
||||
|
||||
/// API secret to be used inside edit modal.
|
||||
api_secret_edit: String,
|
||||
|
@ -45,13 +43,12 @@ pub struct NodeSetup {
|
|||
|
||||
impl Default for NodeSetup {
|
||||
fn default() -> Self {
|
||||
let (api_address, api_port) = NodeConfig::get_api_address_port();
|
||||
let is_api_port_available = Network::is_port_available(api_address.as_str(), api_port);
|
||||
let (api_ip, api_port) = NodeConfig::get_api_address_port();
|
||||
let is_api_port_available = is_api_port_available(&api_ip, &api_port);
|
||||
Self {
|
||||
api_address_edit: api_address,
|
||||
api_port_edit: api_port.to_string(),
|
||||
api_port_edit: api_port,
|
||||
api_port_available_edit: is_api_port_available,
|
||||
api_port_available: is_api_port_available,
|
||||
is_api_port_available,
|
||||
api_secret_edit: "".to_string(),
|
||||
foreign_api_secret_edit: "".to_string(),
|
||||
ftl_edit: "".to_string(),
|
||||
|
@ -62,10 +59,10 @@ impl Default for NodeSetup {
|
|||
const SECRET_SYMBOLS: &'static str = "••••••••••••";
|
||||
|
||||
impl NodeSetup {
|
||||
pub const API_PORT_MODAL: &'static str = "stratum_port";
|
||||
pub const API_PORT_MODAL: &'static str = "api_port";
|
||||
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
View::sub_title(ui, format!("{} {}", COMPUTER_TOWER, t!("network_settings.server.title")));
|
||||
View::sub_title(ui, format!("{} {}", COMPUTER_TOWER, t!("network_settings.server")));
|
||||
View::horizontal_line(ui, Colors::ITEM_STROKE);
|
||||
ui.add_space(4.0);
|
||||
|
||||
|
@ -79,17 +76,17 @@ impl NodeSetup {
|
|||
if Node::is_running() {
|
||||
ui.scope(|ui| {
|
||||
// Setup spacing between buttons.
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
||||
ui.add_space(6.0);
|
||||
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("network_settings.server.disable"), Colors::GOLD, || {
|
||||
View::button(ui, t!("network_settings.disable"), Colors::GOLD, || {
|
||||
Node::stop(false);
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("network_settings.server.restart"), Colors::GOLD, || {
|
||||
View::button(ui, t!("network_settings.restart"), Colors::GOLD, || {
|
||||
Node::restart();
|
||||
});
|
||||
});
|
||||
|
@ -98,7 +95,8 @@ impl NodeSetup {
|
|||
} else {
|
||||
ui.add_space(6.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
View::button(ui, t!("network_settings.server.enable"), Colors::GOLD, || {
|
||||
let enable_text = format!("{} {}", POWER, t!("network_settings.enable"));
|
||||
View::button(ui, enable_text, Colors::GOLD, || {
|
||||
Node::start();
|
||||
});
|
||||
});
|
||||
|
@ -112,7 +110,7 @@ impl NodeSetup {
|
|||
ui.add_space(4.0);
|
||||
|
||||
let addrs = Network::get_ip_list();
|
||||
// Show error message when IP addresses are not available on the system.
|
||||
// Show message when IP addresses are not available on the system.
|
||||
if addrs.is_empty() {
|
||||
Network::no_ip_address_ui(ui);
|
||||
ui.add_space(4.0);
|
||||
|
@ -121,63 +119,146 @@ impl NodeSetup {
|
|||
ui.add_space(4.0);
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("network_settings.server.api_ip_address"))
|
||||
ui.label(RichText::new(t!("network_settings.api_ip"))
|
||||
.size(16.0)
|
||||
.color(Colors::GRAY)
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
|
||||
// Show API IP address setup.
|
||||
self.api_ip_address_setup_ui(ui, addrs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Show API IP address setup.
|
||||
fn api_ip_address_setup_ui(&mut self, ui: &mut egui::Ui, addrs: Vec<IpAddr>) {
|
||||
let (addr, port) = NodeConfig::get_api_address_port();
|
||||
let saved_ip_addr = &IpAddr::from_str(addr.as_str()).unwrap();
|
||||
let mut selected_addr = saved_ip_addr;
|
||||
|
||||
// Set first IP address as current if saved is not present at system.
|
||||
if !addrs.contains(selected_addr) {
|
||||
selected_addr = addrs.get(0).unwrap();
|
||||
}
|
||||
|
||||
// Show available IP addresses on the system.
|
||||
let _ = addrs.chunks(2).map(|x| {
|
||||
if x.len() == 2 {
|
||||
ui.columns(2, |columns| {
|
||||
let addr0 = x.get(0).unwrap();
|
||||
columns[0].vertical_centered(|ui| {
|
||||
View::radio_value(ui,
|
||||
&mut selected_addr,
|
||||
addr0,
|
||||
addr0.to_string());
|
||||
});
|
||||
let addr1 = x.get(1).unwrap();
|
||||
columns[1].vertical_centered(|ui| {
|
||||
View::radio_value(ui,
|
||||
&mut selected_addr,
|
||||
addr1,
|
||||
addr1.to_string());
|
||||
})
|
||||
// Show API IP addresses to select.
|
||||
let (api_ip, api_port) = NodeConfig::get_api_address_port();
|
||||
Network::ip_list_ui(ui, &api_ip, &addrs, |selected_ip| {
|
||||
self.is_api_port_available = is_api_port_available(selected_ip, &api_port);
|
||||
NodeConfig::save_api_address_port(selected_ip, &api_port);
|
||||
});
|
||||
} else {
|
||||
let addr = x.get(0).unwrap();
|
||||
View::radio_value(ui,
|
||||
&mut selected_addr,
|
||||
addr,
|
||||
addr.to_string());
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
// Save stratum server address at config if it was changed and check port availability.
|
||||
if saved_ip_addr != selected_addr {
|
||||
NodeConfig::save_api_server_address_port(selected_addr.to_string(), port.to_string());
|
||||
let available = Network::is_port_available(selected_addr.to_string().as_str(), port);
|
||||
self.api_port_available = available;
|
||||
ui.label(RichText::new(t!("network_settings.api_port"))
|
||||
.size(16.0)
|
||||
.color(Colors::GRAY)
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
// Show API port setup.
|
||||
self.api_port_setup_ui(ui, cb);
|
||||
|
||||
View::horizontal_line(ui, Colors::ITEM_STROKE);
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw API port setup ui.
|
||||
fn api_port_setup_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
let (_, port) = NodeConfig::get_api_address_port();
|
||||
// Show button to choose API server port.
|
||||
View::button(ui, port.clone(), Colors::BUTTON, || {
|
||||
// Setup values for modal.
|
||||
self.api_port_edit = port;
|
||||
self.api_port_available_edit = self.is_api_port_available;
|
||||
|
||||
// Show API port modal.
|
||||
let port_modal = Modal::new(Self::API_PORT_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_port"));
|
||||
Navigator::show_modal(port_modal);
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(14.0);
|
||||
|
||||
// Show error when API server port is unavailable.
|
||||
if !self.is_api_port_available {
|
||||
ui.label(RichText::new(t!("network_settings.port_unavailable"))
|
||||
.size(16.0)
|
||||
.color(Colors::RED));
|
||||
ui.add_space(12.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw API port [`Modal`] content ui.
|
||||
pub fn api_port_modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
ui.add_space(6.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("network_settings.enter_value"))
|
||||
.size(16.0)
|
||||
.color(Colors::GRAY));
|
||||
ui.add_space(8.0);
|
||||
|
||||
// Draw API port text edit.
|
||||
let text_edit_resp = egui::TextEdit::singleline(&mut self.api_port_edit)
|
||||
.font(TextStyle::Heading)
|
||||
.desired_width(58.0)
|
||||
.cursor_at_end(true)
|
||||
.ui(ui);
|
||||
text_edit_resp.request_focus();
|
||||
if text_edit_resp.clicked() {
|
||||
cb.show_keyboard();
|
||||
}
|
||||
|
||||
// Show error when specified port is unavailable.
|
||||
if !self.api_port_available_edit {
|
||||
ui.add_space(12.0);
|
||||
ui.label(RichText::new(t!("network_settings.port_unavailable"))
|
||||
.size(16.0)
|
||||
.color(Colors::RED));
|
||||
}
|
||||
|
||||
ui.add_space(12.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!("modal.cancel"), Colors::WHITE, || {
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.save"), Colors::WHITE, || {
|
||||
// Check if port is available.
|
||||
let (ip, _) = NodeConfig::get_api_address_port();
|
||||
let available = is_api_port_available(&ip, &self.api_port_edit);
|
||||
self.api_port_available_edit = available;
|
||||
|
||||
if self.api_port_available_edit {
|
||||
// Save port at config if it's available.
|
||||
NodeConfig::save_api_address_port(
|
||||
&ip,
|
||||
&self.api_port_edit
|
||||
);
|
||||
|
||||
self.is_api_port_available = true;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn is_api_port_available(ip: &String, port: &String) -> bool {
|
||||
let same_address_as_running = {
|
||||
let (current_ip, current_port) = NodeConfig::get_api_address_port();
|
||||
Node::is_running() && ¤t_ip == ip && ¤t_port == port
|
||||
};
|
||||
|
||||
if same_address_as_running || (!Node::is_running() && Network::is_port_available(&ip, &port)) {
|
||||
if &NodeConfig::get_p2p_port().to_string() != port {
|
||||
let (stratum_ip, stratum_port) = NodeConfig::get_stratum_address_port();
|
||||
return if &stratum_ip == ip {
|
||||
&stratum_port != port
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
|
@ -22,29 +22,27 @@ use crate::gui::icons::WRENCH;
|
|||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, ModalPosition, Network, View};
|
||||
use crate::node::NodeConfig;
|
||||
use crate::Settings;
|
||||
|
||||
/// Stratum server setup ui section.
|
||||
pub struct StratumServerSetup {
|
||||
/// Stratum IP address to be used inside edit modal.
|
||||
stratum_address_edit: String,
|
||||
/// Stratum port to be used inside edit modal.
|
||||
stratum_port_edit: String,
|
||||
/// Flag to check if stratum port is available inside edit modal.
|
||||
stratum_port_available_edit: bool,
|
||||
|
||||
/// Flag to check if stratum port is available from saved config value.
|
||||
pub(crate) is_stratum_port_available: bool
|
||||
pub(crate) is_port_available: bool
|
||||
}
|
||||
|
||||
impl Default for StratumServerSetup {
|
||||
fn default() -> Self {
|
||||
let (stratum_address, stratum_port) = NodeConfig::get_stratum_address_port();
|
||||
let is_port_available = Network::is_port_available(stratum_address.as_str(), stratum_port);
|
||||
let (ip, port) = NodeConfig::get_stratum_address_port();
|
||||
let is_port_available = is_stratum_port_available(&ip, &port);
|
||||
Self {
|
||||
stratum_address_edit: stratum_address,
|
||||
stratum_port_edit: stratum_port.to_string(),
|
||||
stratum_port_edit: port,
|
||||
stratum_port_available_edit: is_port_available,
|
||||
is_stratum_port_available: is_port_available
|
||||
is_port_available
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,66 +56,70 @@ impl StratumServerSetup {
|
|||
View::horizontal_line(ui, Colors::ITEM_STROKE);
|
||||
ui.add_space(4.0);
|
||||
|
||||
// Show error message when IP addresses are not available on the system.
|
||||
let addrs = Network::get_ip_list();
|
||||
if addrs.is_empty() {
|
||||
// Show message when IP addresses are not available on the system.
|
||||
let all_ips = Network::get_ip_list();
|
||||
if all_ips.is_empty() {
|
||||
Network::no_ip_address_ui(ui);
|
||||
return;
|
||||
}
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("network_settings.ip_address"))
|
||||
ui.label(RichText::new(t!("network_settings.ip"))
|
||||
.size(16.0)
|
||||
.color(Colors::GRAY)
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show stratum IP address setup.
|
||||
self.ip_address_setup_ui(ui, addrs);
|
||||
|
||||
View::horizontal_line(ui, Colors::ITEM_STROKE);
|
||||
ui.add_space(6.0);
|
||||
// Show stratum IP addresses to select.
|
||||
let (ip, port) = NodeConfig::get_stratum_address_port();
|
||||
Network::ip_list_ui(ui, &ip, &all_ips, |selected_ip| {
|
||||
self.is_port_available = is_stratum_port_available(selected_ip, &port);
|
||||
NodeConfig::save_stratum_address_port(selected_ip, &port);
|
||||
if !self.is_port_available {
|
||||
NodeConfig::disable_stratum_autorun();
|
||||
}
|
||||
});
|
||||
|
||||
ui.label(RichText::new(t!("network_settings.port"))
|
||||
.size(16.0)
|
||||
.color(Colors::GRAY)
|
||||
);
|
||||
|
||||
// Show button to choose stratum server port.
|
||||
ui.add_space(6.0);
|
||||
let (stratum_address, stratum_port) = NodeConfig::get_stratum_address_port();
|
||||
View::button(ui, stratum_port.to_string(), Colors::BUTTON, || {
|
||||
// Setup values for modal.
|
||||
self.stratum_address_edit = stratum_address.clone();
|
||||
self.stratum_port_edit = stratum_port.to_string();
|
||||
self.stratum_port_available_edit = Network::is_port_available(
|
||||
stratum_address.as_str(),
|
||||
stratum_port
|
||||
);
|
||||
|
||||
// Show stratum port modal.
|
||||
let port_modal = Modal::new(Self::STRATUM_PORT_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_port"));
|
||||
Navigator::show_modal(port_modal);
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(14.0);
|
||||
|
||||
// Show error when stratum server port is unavailable.
|
||||
if !self.is_stratum_port_available {
|
||||
ui.label(RichText::new(t!("network_mining.port_unavailable"))
|
||||
.size(16.0)
|
||||
.color(Colors::RED));
|
||||
ui.add_space(12.0);
|
||||
}
|
||||
// Show stratum port setup.
|
||||
self.port_setup_ui(ui, cb);
|
||||
|
||||
View::horizontal_line(ui, Colors::ITEM_STROKE);
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw stratum port [`Modal`] content.
|
||||
/// Draw stratum port setup ui.
|
||||
fn port_setup_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
let (_, port) = NodeConfig::get_stratum_address_port();
|
||||
// Show button to choose stratum server port.
|
||||
View::button(ui, port.clone(), Colors::BUTTON, || {
|
||||
// Setup values for modal.
|
||||
self.stratum_port_edit = port;
|
||||
self.stratum_port_available_edit = self.is_port_available;
|
||||
|
||||
// Show stratum port modal.
|
||||
let port_modal = Modal::new(Self::STRATUM_PORT_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("network_settings.change_port"));
|
||||
Navigator::show_modal(port_modal);
|
||||
cb.show_keyboard();
|
||||
});
|
||||
ui.add_space(14.0);
|
||||
|
||||
// Show error when stratum server port is unavailable.
|
||||
if !self.is_port_available {
|
||||
ui.label(RichText::new(t!("network_settings.port_unavailable"))
|
||||
.size(16.0)
|
||||
.color(Colors::RED));
|
||||
ui.add_space(12.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw stratum port [`Modal`] content ui.
|
||||
pub fn stratum_port_modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
|
@ -143,7 +145,7 @@ impl StratumServerSetup {
|
|||
// Show error when specified port is unavailable.
|
||||
if !self.stratum_port_available_edit {
|
||||
ui.add_space(12.0);
|
||||
ui.label(RichText::new(t!("network_mining.port_unavailable"))
|
||||
ui.label(RichText::new(t!("network_settings.port_unavailable"))
|
||||
.size(16.0)
|
||||
.color(Colors::RED));
|
||||
}
|
||||
|
@ -153,7 +155,7 @@ impl StratumServerSetup {
|
|||
// Show modal buttons.
|
||||
ui.scope(|ui| {
|
||||
// Setup spacing between buttons.
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
|
@ -166,21 +168,15 @@ impl StratumServerSetup {
|
|||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.save"), Colors::WHITE, || {
|
||||
// Check if port is available.
|
||||
let port_parse = self.stratum_port_edit.parse::<u16>();
|
||||
let is_available = port_parse.is_ok() && Network::is_port_available(
|
||||
self.stratum_address_edit.as_str(),
|
||||
port_parse.unwrap()
|
||||
);
|
||||
self.stratum_port_available_edit = is_available;
|
||||
let (ip, _) = NodeConfig::get_api_address_port();
|
||||
let available = is_stratum_port_available(&ip, &self.stratum_port_edit);
|
||||
self.stratum_port_available_edit = available;
|
||||
|
||||
// Save port at config if it's available.
|
||||
if self.stratum_port_available_edit {
|
||||
NodeConfig::save_stratum_address_port(
|
||||
self.stratum_address_edit.clone(),
|
||||
self.stratum_port_edit.clone()
|
||||
);
|
||||
NodeConfig::save_stratum_address_port(&ip, &self.stratum_port_edit);
|
||||
|
||||
self.is_stratum_port_available = true;
|
||||
self.is_port_available = true;
|
||||
cb.hide_keyboard();
|
||||
modal.close();
|
||||
}
|
||||
|
@ -191,52 +187,18 @@ impl StratumServerSetup {
|
|||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Show stratum IP address setup.
|
||||
fn ip_address_setup_ui(&mut self, ui: &mut egui::Ui, addrs: Vec<IpAddr>) {
|
||||
let (addr, port) = NodeConfig::get_stratum_address_port();
|
||||
let saved_ip_addr = &IpAddr::from_str(addr.as_str()).unwrap();
|
||||
let mut selected_addr = saved_ip_addr;
|
||||
|
||||
// Set first IP address as current if saved is not present at system.
|
||||
if !addrs.contains(selected_addr) {
|
||||
selected_addr = addrs.get(0).unwrap();
|
||||
}
|
||||
|
||||
// Show available IP addresses on the system.
|
||||
let _ = addrs.chunks(2).map(|x| {
|
||||
if x.len() == 2 {
|
||||
ui.columns(2, |columns| {
|
||||
let addr0 = x.get(0).unwrap();
|
||||
columns[0].vertical_centered(|ui| {
|
||||
View::radio_value(ui,
|
||||
&mut selected_addr,
|
||||
addr0,
|
||||
addr0.to_string());
|
||||
});
|
||||
let addr1 = x.get(1).unwrap();
|
||||
columns[1].vertical_centered(|ui| {
|
||||
View::radio_value(ui,
|
||||
&mut selected_addr,
|
||||
addr1,
|
||||
addr1.to_string());
|
||||
})
|
||||
});
|
||||
fn is_stratum_port_available(ip: &String, port: &String) -> bool {
|
||||
if Network::is_port_available(&ip, &port) {
|
||||
if &NodeConfig::get_p2p_port().to_string() != port {
|
||||
let (api_ip, api_port) = NodeConfig::get_api_address_port();
|
||||
return if &api_ip == ip {
|
||||
&api_port != port
|
||||
} else {
|
||||
let addr = x.get(0).unwrap();
|
||||
View::radio_value(ui,
|
||||
&mut selected_addr,
|
||||
addr,
|
||||
addr.to_string());
|
||||
true
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
// Save stratum server address at config if it was changed and check port availability.
|
||||
if saved_ip_addr != selected_addr {
|
||||
NodeConfig::save_stratum_address_port(selected_addr.to_string(), port.to_string());
|
||||
let available = Network::is_port_available(selected_addr.to_string().as_str(), port);
|
||||
self.is_stratum_port_available = available;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
|
@ -35,7 +35,7 @@ pub struct NodeConfig {
|
|||
|
||||
impl NodeConfig {
|
||||
/// Initialize integrated node config.
|
||||
pub fn init(chain_type: ChainTypes) -> Self {
|
||||
pub fn init(chain_type: &ChainTypes) -> Self {
|
||||
let _ = Self::check_api_secret_files(chain_type, API_SECRET_FILE_NAME);
|
||||
let _ = Self::check_api_secret_files(chain_type, FOREIGN_API_SECRET_FILE_NAME);
|
||||
|
||||
|
@ -46,11 +46,11 @@ impl NodeConfig {
|
|||
}
|
||||
|
||||
/// Initialize config with provided [`ChainTypes`].
|
||||
pub fn for_chain_type(chain_type: ChainTypes) -> ConfigMembers {
|
||||
pub fn for_chain_type(chain_type: &ChainTypes) -> ConfigMembers {
|
||||
let path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
|
||||
let parsed = Settings::read_from_file::<ConfigMembers>(path.clone());
|
||||
if !path.exists() || parsed.is_err() {
|
||||
let mut default_config = GlobalConfig::for_chain(&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);
|
||||
|
@ -62,14 +62,16 @@ impl NodeConfig {
|
|||
|
||||
/// Save node config to disk.
|
||||
pub fn save(&mut self) {
|
||||
let chain_type = self.members.server.chain_type;
|
||||
let config_path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
|
||||
let config_path = Settings::get_config_path(
|
||||
SERVER_CONFIG_FILE_NAME,
|
||||
Some(&self.members.server.chain_type)
|
||||
);
|
||||
Settings::write_to_file(&self.members, config_path);
|
||||
}
|
||||
|
||||
/// Check that the api secret files exist and are valid.
|
||||
fn check_api_secret_files(
|
||||
chain_type: ChainTypes,
|
||||
chain_type: &ChainTypes,
|
||||
secret_file_name: &str,
|
||||
) -> Result<(), ConfigError> {
|
||||
let grin_path = Settings::get_working_path(Some(chain_type));
|
||||
|
@ -83,7 +85,7 @@ impl NodeConfig {
|
|||
}
|
||||
|
||||
/// Get stratum server IP address and port.
|
||||
pub fn get_stratum_address_port() -> (String, u16) {
|
||||
pub fn get_stratum_address_port() -> (String, String) {
|
||||
let r_config = Settings::node_config_to_read();
|
||||
let saved_stratum_addr = r_config
|
||||
.members
|
||||
|
@ -95,11 +97,11 @@ impl NodeConfig {
|
|||
.as_ref()
|
||||
.unwrap();
|
||||
let (addr, port) = saved_stratum_addr.split_once(":").unwrap();
|
||||
(addr.to_string(), port.parse().unwrap())
|
||||
(addr.into(), port.into())
|
||||
}
|
||||
|
||||
/// Save stratum server IP address and port.
|
||||
pub fn save_stratum_address_port(addr: String, port: String) {
|
||||
pub fn save_stratum_address_port(addr: &String, port: &String) {
|
||||
let addr_to_save = format!("{}:{}", addr, port);
|
||||
let mut w_node_config = Settings::node_config_to_update();
|
||||
w_node_config
|
||||
|
@ -112,8 +114,47 @@ impl NodeConfig {
|
|||
w_node_config.save();
|
||||
}
|
||||
|
||||
/// Check if stratum mining server autorun is enabled.
|
||||
pub fn is_stratum_autorun_enabled() -> bool {
|
||||
let stratum_config = Settings::node_config_to_read()
|
||||
.members
|
||||
.clone()
|
||||
.server
|
||||
.stratum_mining_config
|
||||
.unwrap();
|
||||
if let Some(enable) = stratum_config.enable_stratum_server {
|
||||
return enable;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Toggle stratum mining server autorun.
|
||||
pub fn toggle_stratum_autorun() {
|
||||
let autorun = Self::is_stratum_autorun_enabled();
|
||||
let mut w_node_config = Settings::node_config_to_update();
|
||||
w_node_config.members
|
||||
.server
|
||||
.stratum_mining_config
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.enable_stratum_server = Some(!autorun);
|
||||
w_node_config.save();
|
||||
}
|
||||
|
||||
/// Disable stratum mining server autorun.
|
||||
pub fn disable_stratum_autorun() {
|
||||
let mut w_node_config = Settings::node_config_to_update();
|
||||
w_node_config.members
|
||||
.server
|
||||
.stratum_mining_config
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.enable_stratum_server = Some(false);
|
||||
w_node_config.save();
|
||||
}
|
||||
|
||||
/// Get API server IP address and port.
|
||||
pub fn get_api_address_port() -> (String, u16) {
|
||||
pub fn get_api_address_port() -> (String, String) {
|
||||
let r_config = Settings::node_config_to_read();
|
||||
let saved_api_addr = r_config
|
||||
.members
|
||||
|
@ -121,11 +162,11 @@ impl NodeConfig {
|
|||
.api_http_addr
|
||||
.as_str();
|
||||
let (addr, port) = saved_api_addr.split_once(":").unwrap();
|
||||
(addr.to_string(), port.parse().unwrap())
|
||||
(addr.into(), port.into())
|
||||
}
|
||||
|
||||
/// Save API server IP address and port.
|
||||
pub fn save_api_server_address_port(addr: String, port: String) {
|
||||
pub fn save_api_address_port(addr: &String, port: &String) {
|
||||
let addr_to_save = format!("{}:{}", addr, port);
|
||||
let mut w_node_config = Settings::node_config_to_update();
|
||||
w_node_config.members.server.api_http_addr = addr_to_save;
|
||||
|
@ -149,7 +190,7 @@ impl NodeConfig {
|
|||
}
|
||||
|
||||
/// Save API secret text.
|
||||
pub fn save_api_secret(api_secret: String) {
|
||||
pub fn save_api_secret(api_secret: &String) {
|
||||
if api_secret.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
@ -181,7 +222,7 @@ impl NodeConfig {
|
|||
}
|
||||
|
||||
/// Save Foreign API secret text.
|
||||
pub fn save_foreign_api_secret(api_secret: String) {
|
||||
pub fn save_foreign_api_secret(api_secret: &String) {
|
||||
if api_secret.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -65,11 +65,9 @@ impl AppConfig {
|
|||
}
|
||||
|
||||
/// Change chain type and load new [`NodeConfig`] accordingly.
|
||||
pub fn change_chain_type(&mut self, chain_type: ChainTypes) {
|
||||
if self.chain_type == chain_type {
|
||||
return;
|
||||
} else {
|
||||
self.chain_type = chain_type;
|
||||
pub fn change_chain_type(&mut self, chain_type: &ChainTypes) {
|
||||
if self.chain_type != *chain_type {
|
||||
self.chain_type = *chain_type;
|
||||
self.save();
|
||||
|
||||
// Load config for selected chain type.
|
||||
|
@ -95,10 +93,9 @@ impl Settings {
|
|||
/// Initialize settings with app and node configs.
|
||||
fn init() -> Self {
|
||||
let app_config = AppConfig::init();
|
||||
let chain_type = app_config.chain_type;
|
||||
Self {
|
||||
app_config: Arc::new(RwLock::new(app_config)),
|
||||
node_config: Arc::new(RwLock::new(NodeConfig::init(chain_type)))
|
||||
node_config: Arc::new(RwLock::new(NodeConfig::init(&app_config.chain_type))),
|
||||
app_config: Arc::new(RwLock::new(app_config))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +120,7 @@ impl Settings {
|
|||
}
|
||||
|
||||
/// Get working directory path for the application.
|
||||
pub fn get_working_path(chain_type: Option<ChainTypes>) -> PathBuf {
|
||||
pub fn get_working_path(chain_type: Option<&ChainTypes>) -> PathBuf {
|
||||
// Check if dir exists.
|
||||
let mut path = match dirs::home_dir() {
|
||||
Some(p) => p,
|
||||
|
@ -141,7 +138,7 @@ impl Settings {
|
|||
}
|
||||
|
||||
/// Get config file path from provided name and [`ChainTypes`] if needed.
|
||||
pub fn get_config_path(config_name: &str, chain_type: Option<ChainTypes>) -> PathBuf {
|
||||
pub fn get_config_path(config_name: &str, chain_type: Option<&ChainTypes>) -> PathBuf {
|
||||
let main_path = Self::get_working_path(chain_type);
|
||||
let mut settings_path = main_path.clone();
|
||||
settings_path.push(config_name);
|
||||
|
|
Loading…
Reference in a new issue