mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-13 10:18:54 +00:00
ui: content container
This commit is contained in:
+3
-26
@@ -21,6 +21,7 @@ use crate::gui::views::{Content, KeyboardContent, Modal, TitlePanel, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::wallet::ExternalConnection;
|
||||
use crate::AppConfig;
|
||||
use crate::gui::views::types::ContentContainer;
|
||||
|
||||
/// Implements ui entry point and contains platform-specific callbacks.
|
||||
pub struct App<Platform> {
|
||||
@@ -69,9 +70,7 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
|
||||
// Handle Esc keyboard key event.
|
||||
if ctx.input_mut(|i| i.consume_key(Modifiers::NONE, egui::Key::Escape)) {
|
||||
if Modal::on_back() {
|
||||
self.content.on_back(&self.platform);
|
||||
}
|
||||
self.content.on_back(&self.platform);
|
||||
// Request repaint to update previous content.
|
||||
ctx.request_repaint();
|
||||
}
|
||||
@@ -122,13 +121,6 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
Self::title_panel_bg(ui, false);
|
||||
self.content.ui(ui, &self.platform);
|
||||
}
|
||||
|
||||
// Provide incoming data to wallets.
|
||||
if let Some(data) = crate::consume_incoming_data() {
|
||||
if !data.is_empty() {
|
||||
self.content.wallets.on_data(ui, Some(data));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Check if desktop window was focused after requested attention.
|
||||
@@ -268,22 +260,7 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
}
|
||||
|
||||
// Paint the title.
|
||||
let dual_wallets_panel = ui.available_width() >= (Content::SIDE_PANEL_WIDTH * 3.0) +
|
||||
View::get_right_inset() + View::get_left_inset();
|
||||
let wallet_panel_opened = self.content.wallets.showing_wallet();
|
||||
let show_app_name = if dual_wallets_panel {
|
||||
wallet_panel_opened && !AppConfig::show_wallets_at_dual_panel()
|
||||
} else if Content::is_dual_panel_mode(ui.ctx()) {
|
||||
wallet_panel_opened
|
||||
} else {
|
||||
Content::is_network_panel_open() || wallet_panel_opened
|
||||
};
|
||||
let creating_wallet = self.content.wallets.creating_wallet();
|
||||
let title_text = if creating_wallet || show_app_name {
|
||||
format!("Grim {}", crate::VERSION)
|
||||
} else {
|
||||
"ツ".to_string()
|
||||
};
|
||||
let title_text = format!("Grim {}", crate::VERSION);
|
||||
painter.text(
|
||||
title_rect.center(),
|
||||
egui::Align2::CENTER_CENTER,
|
||||
|
||||
+32
-34
@@ -21,7 +21,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use crate::gui::icons::FILE_X;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::network::NetworkContent;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::gui::views::wallets::WalletsContent;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::Colors;
|
||||
@@ -39,7 +39,7 @@ pub struct Content {
|
||||
network: NetworkContent,
|
||||
|
||||
/// Central panel [`WalletsContent`] content.
|
||||
pub wallets: WalletsContent,
|
||||
wallets: WalletsContent,
|
||||
|
||||
/// Check if app exit is allowed on Desktop close event.
|
||||
pub exit_allowed: bool,
|
||||
@@ -48,16 +48,8 @@ pub struct Content {
|
||||
|
||||
/// Flag to check it's first draw of content.
|
||||
first_draw: bool,
|
||||
|
||||
/// List of allowed [`Modal`] ids for this [`ModalContainer`].
|
||||
allowed_modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for integrated node warning [`Modal`] on Android.
|
||||
const ANDROID_INTEGRATED_NODE_WARNING_MODAL: &'static str = "android_node_warning_modal";
|
||||
/// Identifier for crash report [`Modal`].
|
||||
const CRASH_REPORT_MODAL: &'static str = "crash_report_modal";
|
||||
|
||||
impl Default for Content {
|
||||
fn default() -> Self {
|
||||
// Exit from eframe only for non-mobile platforms.
|
||||
@@ -69,24 +61,25 @@ impl Default for Content {
|
||||
exit_allowed,
|
||||
show_exit_progress: false,
|
||||
first_draw: true,
|
||||
allowed_modal_ids: vec![
|
||||
Self::EXIT_CONFIRMATION_MODAL,
|
||||
ANDROID_INTEGRATED_NODE_WARNING_MODAL,
|
||||
CRASH_REPORT_MODAL
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for Content {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.allowed_modal_ids
|
||||
/// Identifier for integrated node warning [`Modal`] on Android.
|
||||
const ANDROID_INTEGRATED_NODE_WARNING_MODAL: &'static str = "android_node_warning_modal";
|
||||
/// Identifier for crash report [`Modal`].
|
||||
const CRASH_REPORT_MODAL: &'static str = "crash_report_modal";
|
||||
|
||||
impl ContentContainer for Content {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
Self::EXIT_CONFIRMATION_MODAL,
|
||||
ANDROID_INTEGRATED_NODE_WARNING_MODAL,
|
||||
CRASH_REPORT_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
match modal.id {
|
||||
Self::EXIT_CONFIRMATION_MODAL => self.exit_modal_content(ui, modal, cb),
|
||||
ANDROID_INTEGRATED_NODE_WARNING_MODAL => self.android_warning_modal_ui(ui),
|
||||
@@ -94,12 +87,23 @@ impl ModalContainer for Content {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_back(&mut self, cb: &dyn PlatformCallbacks) -> bool {
|
||||
if Modal::on_back() {
|
||||
if self.wallets.on_back(cb) {
|
||||
Self::show_exit_modal();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.content_ui(ui, cb);
|
||||
}
|
||||
}
|
||||
|
||||
impl Content {
|
||||
/// Identifier for exit confirmation [`Modal`].
|
||||
pub const EXIT_CONFIRMATION_MODAL: &'static str = "exit_confirmation_modal";
|
||||
|
||||
/// Default width of side panel at application UI.
|
||||
pub const SIDE_PANEL_WIDTH: f32 = 400.0;
|
||||
/// Desktop window title height.
|
||||
@@ -107,9 +111,10 @@ impl Content {
|
||||
/// Margin of window frame at desktop.
|
||||
pub const WINDOW_FRAME_MARGIN: f32 = 6.0;
|
||||
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.current_modal_ui(ui, cb);
|
||||
/// Identifier for exit confirmation [`Modal`].
|
||||
pub const EXIT_CONFIRMATION_MODAL: &'static str = "exit_confirmation_modal";
|
||||
|
||||
fn content_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
let dual_panel = Self::is_dual_panel_mode(ui.ctx());
|
||||
let (is_panel_open, mut panel_width) = network_panel_state_width(ui.ctx(), dual_panel);
|
||||
if self.network.showing_settings() {
|
||||
@@ -237,13 +242,6 @@ impl Content {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle Back key event.
|
||||
pub fn on_back(&mut self, cb: &dyn PlatformCallbacks) {
|
||||
if self.wallets.on_back(cb) {
|
||||
Self::show_exit_modal()
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw content for integrated node warning [`Modal`] on Android.
|
||||
fn android_warning_modal_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
+15
-7
@@ -23,6 +23,7 @@ use std::sync::Arc;
|
||||
use crate::gui::views::types::{ModalPosition, ModalState};
|
||||
use crate::gui::views::{Content, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
|
||||
lazy_static! {
|
||||
/// Showing [`Modal`] state to be accessible from different ui parts.
|
||||
@@ -173,8 +174,9 @@ impl Modal {
|
||||
modal.first_draw.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Draw opened [`Modal`] content.
|
||||
pub fn ui(ctx: &egui::Context, add_content: impl FnOnce(&mut egui::Ui, &Modal)) {
|
||||
pub fn ui(ctx: &egui::Context,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
add_content: impl FnOnce(&mut egui::Ui, &Modal, &dyn PlatformCallbacks)) {
|
||||
let has_modal = {
|
||||
MODAL_STATE.read().modal.is_some()
|
||||
};
|
||||
@@ -183,12 +185,15 @@ impl Modal {
|
||||
let r_state = MODAL_STATE.read();
|
||||
r_state.modal.clone().unwrap()
|
||||
};
|
||||
modal.window_ui(ctx, add_content);
|
||||
modal.window_ui(ctx, cb, add_content);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw [`egui::Window`] with provided content.
|
||||
fn window_ui(&self, ctx: &egui::Context, add_content: impl FnOnce(&mut egui::Ui, &Modal)) {
|
||||
fn window_ui(&self,
|
||||
ctx: &egui::Context,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
add_content: impl FnOnce(&mut egui::Ui, &Modal, &dyn PlatformCallbacks)) {
|
||||
let is_fullscreen = ctx.input(|i| {
|
||||
i.viewport().fullscreen.unwrap_or(false)
|
||||
});
|
||||
@@ -249,7 +254,7 @@ impl Modal {
|
||||
if let Some(title) = &self.title {
|
||||
title_ui(title, ui);
|
||||
}
|
||||
self.content_ui(ui, add_content);
|
||||
self.content_ui(ui, cb, add_content);
|
||||
});
|
||||
|
||||
// Setup first draw flag.
|
||||
@@ -289,7 +294,10 @@ impl Modal {
|
||||
}
|
||||
|
||||
/// Draw provided content.
|
||||
fn content_ui(&self, ui: &mut egui::Ui, add_content: impl FnOnce(&mut egui::Ui, &Modal)) {
|
||||
fn content_ui(&self,
|
||||
ui: &mut egui::Ui,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
add_content: impl FnOnce(&mut egui::Ui, &Modal, &dyn PlatformCallbacks)) {
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
|
||||
// Create background shape.
|
||||
@@ -308,7 +316,7 @@ impl Modal {
|
||||
rect.min += egui::emath::vec2(6.0, 0.0);
|
||||
rect.max -= egui::emath::vec2(6.0, 0.0);
|
||||
let resp = ui.scope_builder(UiBuilder::new().max_rect(rect), |ui| {
|
||||
(add_content)(ui, self);
|
||||
(add_content)(ui, self, cb);
|
||||
}).response;
|
||||
|
||||
// Setup background size.
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::network::modals::ExternalConnectionModal;
|
||||
use crate::gui::views::network::NodeSetup;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::node::{Node, NodeConfig};
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection};
|
||||
|
||||
@@ -29,25 +29,21 @@ use crate::wallet::{ConnectionsConfig, ExternalConnection};
|
||||
pub struct ConnectionsContent {
|
||||
/// External connection [`Modal`] content.
|
||||
ext_conn_modal: ExternalConnectionModal,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
impl Default for ConnectionsContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ext_conn_modal: ExternalConnectionModal::new(None),
|
||||
modal_ids: vec![
|
||||
ExternalConnectionModal::NETWORK_ID
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for ConnectionsContent {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for ConnectionsContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
ExternalConnectionModal::NETWORK_ID
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -61,13 +57,12 @@ impl ModalContainer for ConnectionsContent {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectionsContent {
|
||||
/// Draw connections content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
ui.add_space(2.0);
|
||||
|
||||
// Show network type selection.
|
||||
@@ -121,7 +116,9 @@ impl ConnectionsContent {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectionsContent {
|
||||
/// Draw integrated node connection item content.
|
||||
pub fn integrated_node_item_ui(ui: &mut egui::Ui, custom_button: impl FnOnce(&mut egui::Ui)) {
|
||||
// Draw round background.
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::gui::views::{Content, TitlePanel, View};
|
||||
use crate::gui::views::network::{ConnectionsContent, NetworkMetrics, NetworkMining, NetworkNode, NetworkSettings};
|
||||
use crate::gui::views::network::types::{NodeTab, NodeTabType};
|
||||
use crate::gui::views::settings::SettingsContent;
|
||||
use crate::gui::views::types::{LinePosition, TitleContentType, TitleType};
|
||||
use crate::gui::views::types::{ContentContainer, LinePosition, TitleContentType, TitleType};
|
||||
use crate::node::{Node, NodeConfig, NodeError};
|
||||
use crate::wallet::ExternalConnection;
|
||||
|
||||
@@ -111,7 +111,7 @@ impl NetworkContent {
|
||||
let rect = ui.available_rect_before_wrap();
|
||||
if let Some(c) = &mut self.settings_content {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
c.ui(ui);
|
||||
c.ui(ui, cb);
|
||||
});
|
||||
} else if self.node_tab_content.get_type() != NodeTabType::Settings {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
@@ -124,11 +124,11 @@ impl NetworkContent {
|
||||
Node::is_stopping() {
|
||||
NetworkContent::loading_ui(ui, None);
|
||||
} else {
|
||||
self.node_tab_content.ui(ui, cb);
|
||||
self.node_tab_content.tab_ui(ui, cb);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
self.node_tab_content.ui(ui, cb);
|
||||
self.node_tab_content.tab_ui(ui, cb);
|
||||
}
|
||||
|
||||
// Draw content divider line.
|
||||
|
||||
@@ -38,7 +38,7 @@ impl NodeTab for NetworkMetrics {
|
||||
NodeTabType::Metrics
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
fn tab_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
let server_stats = Node::get_stats();
|
||||
let stats = server_stats.as_ref().unwrap();
|
||||
if stats.diff_stats.height == 0 {
|
||||
|
||||
@@ -24,6 +24,7 @@ use crate::gui::views::{Content, View};
|
||||
use crate::gui::views::network::NetworkContent;
|
||||
use crate::gui::views::network::setup::StratumSetup;
|
||||
use crate::gui::views::network::types::{NodeTab, NodeTabType};
|
||||
use crate::gui::views::types::ContentContainer;
|
||||
use crate::node::{Node, NodeConfig};
|
||||
|
||||
/// Mining tab content.
|
||||
@@ -45,7 +46,7 @@ impl NodeTab for NetworkMining {
|
||||
NodeTabType::Mining
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
fn tab_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
if Node::is_stratum_starting() || Node::get_sync_status().unwrap() != SyncStatus::NoSync {
|
||||
NetworkContent::loading_ui(ui, Some(t!("network_mining.loading")));
|
||||
return;
|
||||
|
||||
@@ -22,6 +22,9 @@ use crate::wallet::{ConnectionsConfig, ExternalConnection};
|
||||
|
||||
/// Content to create or update external wallet connection.
|
||||
pub struct ExternalConnectionModal {
|
||||
/// Flag to check if content was just rendered.
|
||||
first_draw: bool,
|
||||
|
||||
/// External connection URL value for [`Modal`].
|
||||
ext_node_url_edit: String,
|
||||
/// External connection API secret value for [`Modal`].
|
||||
@@ -46,6 +49,7 @@ impl ExternalConnectionModal {
|
||||
("".to_string(), "".to_string(), None)
|
||||
};
|
||||
Self {
|
||||
first_draw: true,
|
||||
ext_node_url_edit,
|
||||
ext_node_secret_edit,
|
||||
ext_node_url_error: false,
|
||||
@@ -103,7 +107,7 @@ impl ExternalConnectionModal {
|
||||
let url_edit_id = Id::from(modal.id).with(self.ext_conn_id).with("node_url");
|
||||
let mut url_edit = TextEdit::new(url_edit_id)
|
||||
.paste()
|
||||
.focus(Modal::first_draw());
|
||||
.focus(self.first_draw);
|
||||
url_edit.ui(ui, &mut self.ext_node_url_edit, cb);
|
||||
|
||||
ui.add_space(8.0);
|
||||
@@ -163,5 +167,7 @@ impl ExternalConnectionModal {
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
|
||||
self.first_draw = false;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ impl NodeTab for NetworkNode {
|
||||
NodeTabType::Info
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
fn tab_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
ScrollArea::vertical()
|
||||
.id_salt("integrated_node_info_scroll")
|
||||
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, View};
|
||||
use crate::gui::views::network::setup::{DandelionSetup, NodeSetup, P2PSetup, PoolSetup, StratumSetup};
|
||||
use crate::gui::views::network::types::{NodeTab, NodeTabType};
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::node::{Node, NodeConfig};
|
||||
|
||||
/// Integrated node settings tab content.
|
||||
@@ -36,9 +36,6 @@ pub struct NetworkSettings {
|
||||
pool: PoolSetup,
|
||||
/// Dandelion server setup content.
|
||||
dandelion: DandelionSetup,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for settings reset confirmation [`Modal`].
|
||||
@@ -52,16 +49,15 @@ impl Default for NetworkSettings {
|
||||
stratum: StratumSetup::default(),
|
||||
pool: PoolSetup::default(),
|
||||
dandelion: DandelionSetup::default(),
|
||||
modal_ids: vec![
|
||||
RESET_SETTINGS_CONFIRMATION_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for NetworkSettings {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for NetworkSettings {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
RESET_SETTINGS_CONFIRMATION_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -73,17 +69,12 @@ impl ModalContainer for NetworkSettings {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeTab for NetworkSettings {
|
||||
fn get_type(&self) -> NodeTabType {
|
||||
NodeTabType::Settings
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
ScrollArea::vertical()
|
||||
.id_salt("node_settings_scroll")
|
||||
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
||||
@@ -135,6 +126,16 @@ impl NodeTab for NetworkSettings {
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeTab for NetworkSettings {
|
||||
fn get_type(&self) -> NodeTabType {
|
||||
NodeTabType::Settings
|
||||
}
|
||||
|
||||
fn tab_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.ui(ui, cb);
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkSettings {
|
||||
/// Reminder to restart enabled node to show on edit setting at [`Modal`].
|
||||
pub fn node_restart_required_ui(ui: &mut egui::Ui) {
|
||||
|
||||
@@ -16,7 +16,7 @@ use egui::{Id, RichText};
|
||||
|
||||
use crate::gui::icons::{CLOCK_COUNTDOWN, GRAPH, TIMER, WATCH};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::views::network::NetworkSettings;
|
||||
@@ -35,9 +35,6 @@ pub struct DandelionSetup {
|
||||
|
||||
/// Stem phase probability value (stem 90% of the time, fluff 10% of the time by default).
|
||||
stem_prob_edit: String,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>,
|
||||
}
|
||||
|
||||
/// Identifier epoch duration value [`Modal`].
|
||||
@@ -56,19 +53,18 @@ impl Default for DandelionSetup {
|
||||
embargo_edit: NodeConfig::get_reorg_cache_period(),
|
||||
aggregation_edit: NodeConfig::get_dandelion_aggregation(),
|
||||
stem_prob_edit: NodeConfig::get_stem_probability(),
|
||||
modal_ids: vec![
|
||||
EPOCH_MODAL,
|
||||
EMBARGO_MODAL,
|
||||
AGGREGATION_MODAL,
|
||||
STEM_PROBABILITY_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for DandelionSetup {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for DandelionSetup {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
EPOCH_MODAL,
|
||||
EMBARGO_MODAL,
|
||||
AGGREGATION_MODAL,
|
||||
STEM_PROBABILITY_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -83,13 +79,12 @@ impl ModalContainer for DandelionSetup {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DandelionSetup {
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
View::sub_title(ui, format!("{} {}", GRAPH, "Dandelion"));
|
||||
View::horizontal_line(ui, Colors::stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -131,7 +126,9 @@ impl DandelionSetup {
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl DandelionSetup {
|
||||
/// Draw epoch duration setup content.
|
||||
fn epoch_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.epoch_duration"))
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::gui::icons::{CLOCK_CLOCKWISE, COMPUTER_TOWER, PLUG, POWER, SHIELD, SH
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::network::settings::NetworkSettings;
|
||||
use crate::gui::views::network::NetworkContent;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::node::{Node, NodeConfig};
|
||||
@@ -43,9 +43,6 @@ pub struct NodeSetup {
|
||||
|
||||
/// Future Time Limit value.
|
||||
ftl_edit: String,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for API port value [`Modal`].
|
||||
@@ -68,19 +65,18 @@ impl Default for NodeSetup {
|
||||
is_api_port_available,
|
||||
secret_edit: "".to_string(),
|
||||
ftl_edit: NodeConfig::get_ftl(),
|
||||
modal_ids: vec![
|
||||
API_PORT_MODAL,
|
||||
API_SECRET_MODAL,
|
||||
FOREIGN_API_SECRET_MODAL,
|
||||
FTL_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for NodeSetup {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for NodeSetup {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
API_PORT_MODAL,
|
||||
API_SECRET_MODAL,
|
||||
FOREIGN_API_SECRET_MODAL,
|
||||
FTL_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -95,13 +91,12 @@ impl ModalContainer for NodeSetup {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeSetup {
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
View::sub_title(ui, format!("{} {}", COMPUTER_TOWER, t!("network_settings.server")));
|
||||
View::horizontal_line(ui, Colors::stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -218,7 +213,9 @@ impl NodeSetup {
|
||||
self.archive_mode_ui(ui);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeSetup {
|
||||
/// Draw [`ChainTypes`] setup content.
|
||||
pub fn chain_type_ui(ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::gui::icons::{ARROW_FAT_LINES_DOWN, ARROW_FAT_LINES_UP, GLOBE_SIMPLE,
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::gui::views::network::settings::NetworkSettings;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::node::{Node, NodeConfig, PeersConfig};
|
||||
|
||||
/// Type of peer.
|
||||
@@ -65,9 +65,6 @@ pub struct P2PSetup {
|
||||
|
||||
/// Flag to check if reset of peers was called.
|
||||
peers_reset: bool,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for port value [`Modal`].
|
||||
@@ -111,23 +108,22 @@ impl Default for P2PSetup {
|
||||
max_inbound_count: NodeConfig::get_max_inbound_peers(),
|
||||
max_outbound_count: NodeConfig::get_max_outbound_peers(),
|
||||
peers_reset: false,
|
||||
modal_ids: vec![
|
||||
PORT_MODAL,
|
||||
CUSTOM_SEED_MODAL,
|
||||
ALLOW_PEER_MODAL,
|
||||
DENY_PEER_MODAL,
|
||||
PREFER_PEER_MODAL,
|
||||
BAN_WINDOW_MODAL,
|
||||
MAX_INBOUND_MODAL,
|
||||
MAX_OUTBOUND_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for P2PSetup {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for P2PSetup {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
PORT_MODAL,
|
||||
CUSTOM_SEED_MODAL,
|
||||
ALLOW_PEER_MODAL,
|
||||
DENY_PEER_MODAL,
|
||||
PREFER_PEER_MODAL,
|
||||
BAN_WINDOW_MODAL,
|
||||
MAX_INBOUND_MODAL,
|
||||
MAX_OUTBOUND_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -146,16 +142,12 @@ impl ModalContainer for P2PSetup {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl P2PSetup {
|
||||
/// Title for custom DNS Seeds setup section.
|
||||
const DNS_SEEDS_TITLE: &'static str = "DNS Seeds";
|
||||
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
View::sub_title(ui, format!("{} {}", HANDSHAKE, t!("network_settings.p2p_server")));
|
||||
View::horizontal_line(ui, Colors::stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -236,7 +228,12 @@ impl P2PSetup {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Title for custom DNS Seeds setup section.
|
||||
const DNS_SEEDS_TITLE: &'static str = "DNS Seeds";
|
||||
|
||||
impl P2PSetup {
|
||||
/// Draw p2p port setup content.
|
||||
fn port_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.p2p_port"))
|
||||
@@ -398,7 +395,7 @@ impl P2PSetup {
|
||||
PeerType::Allowed => t!("network_settings.allow_list"),
|
||||
PeerType::Denied => t!("network_settings.deny_list"),
|
||||
PeerType::Preferred => t!("network_settings.favourites"),
|
||||
_ => Self::DNS_SEEDS_TITLE.to_string()
|
||||
_ => DNS_SEEDS_TITLE.to_string()
|
||||
};
|
||||
// Show modal to add peer.
|
||||
Modal::new(modal_id)
|
||||
@@ -483,8 +480,7 @@ impl P2PSetup {
|
||||
|
||||
/// Draw seeding type setup content.
|
||||
fn seeding_type_ui(&mut self, ui: &mut egui::Ui) {
|
||||
let title = Self::DNS_SEEDS_TITLE;
|
||||
ui.label(RichText::new(title).size(16.0).color(Colors::gray()));
|
||||
ui.label(RichText::new(DNS_SEEDS_TITLE).size(16.0).color(Colors::gray()));
|
||||
ui.add_space(2.0);
|
||||
|
||||
let default_seeding = NodeConfig::is_default_seeding_type();
|
||||
|
||||
@@ -19,40 +19,33 @@ use crate::gui::icons::{BEZIER_CURVE, BOUNDING_BOX, CHART_SCATTER, CIRCLES_THREE
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::gui::views::network::settings::NetworkSettings;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::node::NodeConfig;
|
||||
|
||||
/// Memory pool setup section content.
|
||||
pub struct PoolSetup {
|
||||
/// Base fee value that's accepted into the pool.
|
||||
fee_base_edit: String,
|
||||
|
||||
/// Reorg cache retention period value in minutes.
|
||||
reorg_period_edit: String,
|
||||
|
||||
/// Maximum number of transactions allowed in the pool.
|
||||
pool_size_edit: String,
|
||||
|
||||
/// Maximum number of transactions allowed in the stempool.
|
||||
stempool_size_edit: String,
|
||||
|
||||
/// Maximum total weight of transactions to build a block.
|
||||
max_weight_edit: String,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>,
|
||||
}
|
||||
|
||||
/// Identifier for base fee value [`Modal`].
|
||||
pub const FEE_BASE_MODAL: &'static str = "fee_base";
|
||||
const FEE_BASE_MODAL: &'static str = "fee_base";
|
||||
/// Identifier for reorg cache retention period value [`Modal`].
|
||||
pub const REORG_PERIOD_MODAL: &'static str = "reorg_period";
|
||||
const REORG_PERIOD_MODAL: &'static str = "reorg_period";
|
||||
/// Identifier for maximum number of transactions in the pool [`Modal`].
|
||||
pub const POOL_SIZE_MODAL: &'static str = "pool_size";
|
||||
const POOL_SIZE_MODAL: &'static str = "pool_size";
|
||||
/// Identifier for maximum number of transactions in the stempool [`Modal`].
|
||||
pub const STEMPOOL_SIZE_MODAL: &'static str = "stempool_size";
|
||||
const STEMPOOL_SIZE_MODAL: &'static str = "stempool_size";
|
||||
/// Identifier for maximum total weight of transactions [`Modal`].
|
||||
pub const MAX_WEIGHT_MODAL: &'static str = "max_weight";
|
||||
const MAX_WEIGHT_MODAL: &'static str = "max_weight";
|
||||
|
||||
impl Default for PoolSetup {
|
||||
fn default() -> Self {
|
||||
@@ -62,20 +55,19 @@ impl Default for PoolSetup {
|
||||
pool_size_edit: NodeConfig::get_max_pool_size(),
|
||||
stempool_size_edit: NodeConfig::get_max_stempool_size(),
|
||||
max_weight_edit: NodeConfig::get_mineable_max_weight(),
|
||||
modal_ids: vec![
|
||||
FEE_BASE_MODAL,
|
||||
REORG_PERIOD_MODAL,
|
||||
POOL_SIZE_MODAL,
|
||||
STEMPOOL_SIZE_MODAL,
|
||||
MAX_WEIGHT_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for PoolSetup {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for PoolSetup {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
FEE_BASE_MODAL,
|
||||
REORG_PERIOD_MODAL,
|
||||
POOL_SIZE_MODAL,
|
||||
STEMPOOL_SIZE_MODAL,
|
||||
MAX_WEIGHT_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -91,13 +83,12 @@ impl ModalContainer for PoolSetup {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PoolSetup {
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
View::sub_title(ui, format!("{} {}", CHART_SCATTER, t!("network_settings.tx_pool")));
|
||||
View::horizontal_line(ui, Colors::stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -135,7 +126,9 @@ impl PoolSetup {
|
||||
self.max_weight_ui(ui);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl PoolSetup {
|
||||
/// Draw fee base setup content.
|
||||
fn fee_base_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label(RichText::new(t!("network_settings.pool_fee"))
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::gui::icons::{BARBELL, HARD_DRIVES, PLUG, POWER, TIMER};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::gui::views::network::settings::NetworkSettings;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::gui::views::wallets::modals::WalletsModal;
|
||||
use crate::node::{Node, NodeConfig};
|
||||
use crate::wallet::{WalletConfig, WalletList};
|
||||
@@ -51,9 +51,6 @@ pub struct StratumSetup {
|
||||
|
||||
/// Minimum share difficulty value to request from miners.
|
||||
min_share_diff_edit: String,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for wallet selection [`Modal`].
|
||||
@@ -91,19 +88,18 @@ impl Default for StratumSetup {
|
||||
wallet_name,
|
||||
attempt_time_edit: NodeConfig::get_stratum_attempt_time(),
|
||||
min_share_diff_edit: NodeConfig::get_stratum_min_share_diff(),
|
||||
modal_ids: vec![
|
||||
WALLET_SELECTION_MODAL,
|
||||
STRATUM_PORT_MODAL,
|
||||
ATTEMPT_TIME_MODAL,
|
||||
MIN_SHARE_DIFF_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for StratumSetup {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for StratumSetup {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
WALLET_SELECTION_MODAL,
|
||||
STRATUM_PORT_MODAL,
|
||||
ATTEMPT_TIME_MODAL,
|
||||
MIN_SHARE_DIFF_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -112,7 +108,7 @@ impl ModalContainer for StratumSetup {
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
match modal.id {
|
||||
WALLET_SELECTION_MODAL => {
|
||||
self.wallets_modal.ui(ui, modal, &mut self.wallets, cb, |wallet, _| {
|
||||
self.wallets_modal.ui(ui, &mut self.wallets, |wallet, _| {
|
||||
let id = wallet.get_config().id;
|
||||
NodeConfig::save_stratum_wallet_id(id);
|
||||
self.wallet_name = WalletConfig::read_name_by_id(id);
|
||||
@@ -124,13 +120,12 @@ impl ModalContainer for StratumSetup {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StratumSetup {
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
View::sub_title(ui, format!("{} {}", HARD_DRIVES, t!("network_mining.server")));
|
||||
View::horizontal_line(ui, Colors::stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -192,8 +187,8 @@ impl StratumSetup {
|
||||
View::button(ui,
|
||||
t!("network_settings.choose_wallet"),
|
||||
Colors::white_or_black(false), || {
|
||||
self.show_wallets_modal();
|
||||
});
|
||||
self.show_wallets_modal();
|
||||
});
|
||||
ui.add_space(12.0);
|
||||
|
||||
if self.wallet_name.is_some() {
|
||||
@@ -242,7 +237,9 @@ impl StratumSetup {
|
||||
self.min_diff_ui(ui);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl StratumSetup {
|
||||
/// Show wallet selection [`Modal`].
|
||||
fn show_wallets_modal(&mut self) {
|
||||
self.wallets_modal = WalletsModal::new(NodeConfig::get_stratum_wallet_id(), None, false);
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::gui::platform::PlatformCallbacks;
|
||||
/// Integrated node tab content interface.
|
||||
pub trait NodeTab {
|
||||
fn get_type(&self) -> NodeTabType;
|
||||
fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks);
|
||||
fn tab_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks);
|
||||
}
|
||||
|
||||
/// Type of [`NodeTab`] content.
|
||||
|
||||
@@ -18,7 +18,9 @@ use egui::{Layout, RichText};
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{CHECK, CHECK_FAT};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::types::ContentContainer;
|
||||
|
||||
/// Application settings content.
|
||||
pub struct SettingsContent {
|
||||
@@ -34,9 +36,19 @@ impl Default for SettingsContent {
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsContent {
|
||||
/// Draw settings content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
impl ContentContainer for SettingsContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
}
|
||||
|
||||
fn on_back(&mut self, cb: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show theme selection.
|
||||
@@ -60,7 +72,9 @@ impl SettingsContent {
|
||||
Self::language_item_ui(locale, ui, index, locales.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsContent {
|
||||
/// Draw theme selection content.
|
||||
fn theme_selection_ui(ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
|
||||
+19
-20
@@ -51,28 +51,27 @@ pub struct ModalState {
|
||||
pub modal: Option<Modal>,
|
||||
}
|
||||
|
||||
/// Contains identifiers to draw opened [`Modal`] content for current ui container.
|
||||
pub trait ModalContainer {
|
||||
/// Content container to simplify modals management and navigation.
|
||||
pub trait ContentContainer {
|
||||
/// List of allowed [`Modal`] identifiers.
|
||||
fn modal_ids(&self) -> &Vec<&'static str>;
|
||||
|
||||
/// Draw modal ui content.
|
||||
fn modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks);
|
||||
|
||||
/// Draw [`Modal`] for current ui container if it's possible.
|
||||
fn current_modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
let modal_id = Modal::opened();
|
||||
let draw = modal_id.is_some() && self.modal_ids().contains(&modal_id.unwrap());
|
||||
if draw {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
self.modal_ui(ui, modal, cb);
|
||||
});
|
||||
fn modal_ids(&self) -> Vec<&'static str>;
|
||||
/// Draw modal content.
|
||||
fn modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks);
|
||||
/// Handle back key action, return `false` when consumed inside container.
|
||||
fn on_back(&mut self, cb: &dyn PlatformCallbacks) -> bool;
|
||||
/// Draw container content.
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks);
|
||||
/// Draw content, to call by parent container.
|
||||
fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content.
|
||||
if let Some(id) = Modal::opened() {
|
||||
if self.modal_ids().contains(&id) {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.modal_ui(ui, modal, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
self.container_ui(ui, cb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+112
-126
@@ -12,24 +12,24 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::time::Duration;
|
||||
use egui::{Align, CornerRadius, Id, Layout, Margin, RichText, ScrollArea, StrokeKind};
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Align, CornerRadius, Id, Layout, Margin, RichText, ScrollArea, StrokeKind};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROW_LEFT, CARET_RIGHT, COMPUTER_TOWER, FOLDER_OPEN, FOLDER_PLUS, GEAR, GLOBE, GLOBE_SIMPLE, LOCK_KEY, PLUS, SIDEBAR_SIMPLE, SUITCASE};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, TitlePanel, View};
|
||||
use crate::gui::views::settings::SettingsContent;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition, LinePosition, TitleContentType, TitleType};
|
||||
use crate::gui::views::wallets::creation::WalletCreation;
|
||||
use crate::gui::views::types::{ContentContainer, LinePosition, ModalPosition, TitleContentType, TitleType};
|
||||
use crate::gui::views::wallets::creation::WalletCreationContent;
|
||||
use crate::gui::views::wallets::modals::{AddWalletModal, OpenWalletModal, WalletConnectionModal, WalletsModal};
|
||||
use crate::gui::views::wallets::types::WalletTabType;
|
||||
use crate::gui::views::wallets::wallet::types::wallet_status_text;
|
||||
use crate::gui::views::wallets::WalletContent;
|
||||
use crate::wallet::{ExternalConnection, Wallet, WalletList};
|
||||
use crate::gui::views::{Content, Modal, TitlePanel, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::wallet::types::ConnectionMethod;
|
||||
use crate::wallet::{ExternalConnection, Wallet, WalletList};
|
||||
use crate::AppConfig;
|
||||
|
||||
/// Wallets content.
|
||||
pub struct WalletsContent {
|
||||
@@ -37,27 +37,21 @@ pub struct WalletsContent {
|
||||
wallets: WalletList,
|
||||
|
||||
/// Initial wallet creation [`Modal`] content.
|
||||
add_wallet_modal_content: Option<AddWalletModal>,
|
||||
add_wallet_modal_content: AddWalletModal,
|
||||
/// Wallet opening [`Modal`] content.
|
||||
open_wallet_content: Option<OpenWalletModal>,
|
||||
/// Wallet connection selection content.
|
||||
conn_selection_content: Option<WalletConnectionModal>,
|
||||
open_wallet_content: OpenWalletModal,
|
||||
/// Wallet connection selection [`Modal`] content.
|
||||
conn_selection_content: WalletConnectionModal,
|
||||
/// Wallet selection [`Modal`] content.
|
||||
wallet_selection_content: Option<WalletsModal>,
|
||||
wallet_selection_content: WalletsModal,
|
||||
|
||||
/// Selected [`Wallet`] content.
|
||||
wallet_content: Option<WalletContent>,
|
||||
/// Wallet creation content.
|
||||
creation_content: Option<WalletCreation>,
|
||||
creation_content: Option<WalletCreationContent>,
|
||||
|
||||
/// Settings content.
|
||||
settings_content: Option<SettingsContent>,
|
||||
|
||||
/// Flag to show [`Wallet`] list at dual panel mode.
|
||||
show_wallets_at_dual_panel: bool,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
const ADD_WALLET_MODAL: &'static str = "wallets_add_modal";
|
||||
@@ -69,97 +63,121 @@ impl Default for WalletsContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
wallets: WalletList::default(),
|
||||
wallet_selection_content: None,
|
||||
open_wallet_content: None,
|
||||
conn_selection_content: None,
|
||||
wallet_selection_content: WalletsModal::new(None, None, true),
|
||||
open_wallet_content: OpenWalletModal::new(None),
|
||||
add_wallet_modal_content: AddWalletModal::default(),
|
||||
conn_selection_content: WalletConnectionModal::new(ConnectionMethod::Integrated),
|
||||
wallet_content: None,
|
||||
creation_content: None,
|
||||
settings_content: None,
|
||||
show_wallets_at_dual_panel: AppConfig::show_wallets_at_dual_panel(),
|
||||
modal_ids: vec![
|
||||
ADD_WALLET_MODAL,
|
||||
OPEN_WALLET_MODAL,
|
||||
SELECT_CONNECTION_MODAL,
|
||||
SELECT_WALLET_MODAL,
|
||||
],
|
||||
add_wallet_modal_content: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for WalletsContent {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for WalletsContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
ADD_WALLET_MODAL,
|
||||
OPEN_WALLET_MODAL,
|
||||
SELECT_CONNECTION_MODAL,
|
||||
SELECT_WALLET_MODAL,
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
fn modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
match modal.id {
|
||||
ADD_WALLET_MODAL => {
|
||||
if let Some(content) = self.add_wallet_modal_content.as_mut() {
|
||||
content.ui(ui, modal, cb, |name, pass| {
|
||||
self.creation_content = Some(
|
||||
WalletCreation::new(name.clone(), pass.clone())
|
||||
);
|
||||
});
|
||||
}
|
||||
if self.creating_wallet() {
|
||||
self.add_wallet_modal_content = None;
|
||||
}
|
||||
self.add_wallet_modal_content.ui(ui, modal, cb, |name, pass| {
|
||||
self.creation_content = Some(
|
||||
WalletCreationContent::new(name.clone(), pass.clone())
|
||||
);
|
||||
});
|
||||
},
|
||||
OPEN_WALLET_MODAL => {
|
||||
let mut open = false;
|
||||
if let Some(open_content) = self.open_wallet_content.as_mut() {
|
||||
open_content.ui(ui, modal, cb, |wallet, data| {
|
||||
self.wallet_content = Some(WalletContent::new(wallet, data));
|
||||
open = true;
|
||||
});
|
||||
}
|
||||
if open {
|
||||
self.open_wallet_content = None;
|
||||
}
|
||||
self.open_wallet_content.ui(ui, modal, cb, |pass, _| {
|
||||
if let Some(content) = &self.wallet_content {
|
||||
return match content.wallet.open(pass) {
|
||||
Ok(_) => true,
|
||||
Err(_) => false
|
||||
};
|
||||
}
|
||||
true
|
||||
});
|
||||
},
|
||||
SELECT_CONNECTION_MODAL => {
|
||||
if let Some(content) = self.conn_selection_content.as_mut() {
|
||||
content.ui(ui, modal, cb, |conn| {
|
||||
if let Some(wallet_content) = &self.wallet_content {
|
||||
wallet_content.wallet.update_connection(&conn);
|
||||
}
|
||||
});
|
||||
}
|
||||
self.conn_selection_content.ui(ui, modal, cb, |conn| {
|
||||
if let Some(wallet_content) = &self.wallet_content {
|
||||
wallet_content.wallet.update_connection(&conn);
|
||||
}
|
||||
});
|
||||
}
|
||||
SELECT_WALLET_MODAL => {
|
||||
let mut select = false;
|
||||
if let Some(content) = self.wallet_selection_content.as_mut() {
|
||||
content.ui(ui, modal, &mut self.wallets, cb, |wallet, data| {
|
||||
self.wallet_content = Some(WalletContent::new(wallet, data));
|
||||
select = true;
|
||||
});
|
||||
}
|
||||
if select {
|
||||
self.wallet_selection_content = None;
|
||||
}
|
||||
self.wallet_selection_content.ui(ui, &mut self.wallets, |wallet, data| {
|
||||
if !wallet.is_open() {
|
||||
self.open_wallet_content = OpenWalletModal::new(data.clone());
|
||||
Modal::new(OPEN_WALLET_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.open"))
|
||||
.show();
|
||||
}
|
||||
self.wallet_content = Some(WalletContent::new(wallet, data));
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_back(&mut self, cb: &dyn PlatformCallbacks) -> bool {
|
||||
if self.showing_settings() {
|
||||
// Close settings.
|
||||
self.settings_content = None;
|
||||
return false;
|
||||
} else if self.creating_wallet() {
|
||||
// Close wallet creation.
|
||||
let creation = self.creation_content.as_mut().unwrap();
|
||||
if creation.on_back() {
|
||||
self.creation_content = None;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if self.showing_wallet() {
|
||||
let content = self.wallet_content.as_mut().unwrap();
|
||||
// Close opened QR code scanner.
|
||||
if content.qr_scan_content.is_some() {
|
||||
cb.stop_camera();
|
||||
content.qr_scan_content = None;
|
||||
return false;
|
||||
}
|
||||
// Close opened wallet.
|
||||
self.wallet_content = None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.content_ui(ui, cb);
|
||||
}
|
||||
}
|
||||
|
||||
impl WalletsContent {
|
||||
/// Draw wallets content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.current_modal_ui(ui, cb);
|
||||
fn content_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
if let Some(data) = crate::consume_incoming_data() {
|
||||
if !data.is_empty() {
|
||||
self.on_data(ui, Some(data));
|
||||
}
|
||||
}
|
||||
|
||||
let showing_settings = self.showing_settings();
|
||||
let creating_wallet = self.creating_wallet();
|
||||
let showing_wallet = self.showing_wallet() && !creating_wallet && !showing_settings;
|
||||
let dual_panel = Self::is_dual_panel_mode(ui);
|
||||
let dual_panel = is_dual_panel_mode(ui);
|
||||
let content_width = ui.available_width();
|
||||
let list_hidden = showing_settings || creating_wallet || self.wallets.list().is_empty()
|
||||
|| (showing_wallet && self.wallet_content.as_ref().unwrap().qr_scan_content.is_some())
|
||||
|| (dual_panel && showing_wallet && !self.show_wallets_at_dual_panel)
|
||||
|| (dual_panel && showing_wallet && !AppConfig::show_wallets_at_dual_panel())
|
||||
|| (!dual_panel && showing_wallet);
|
||||
|
||||
// Show title panel.
|
||||
@@ -262,7 +280,7 @@ impl WalletsContent {
|
||||
if self.showing_settings() {
|
||||
if let Some(c) = &mut self.settings_content {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
c.ui(ui);
|
||||
c.ui(ui, cb);
|
||||
});
|
||||
}
|
||||
} else if self.creating_wallet() {
|
||||
@@ -270,7 +288,7 @@ impl WalletsContent {
|
||||
let pass = creation.pass.clone();
|
||||
let mut created = false;
|
||||
// Show wallet creation content.
|
||||
creation.ui(ui, cb, |wallet| {
|
||||
creation.content_ui(ui, cb, |wallet| {
|
||||
self.wallets.add(wallet.clone());
|
||||
if let Ok(_) = wallet.open(pass.clone()) {
|
||||
self.wallet_content = Some(WalletContent::new(wallet, None));
|
||||
@@ -324,7 +342,7 @@ impl WalletsContent {
|
||||
}
|
||||
|
||||
/// Handle data from deeplink or opened file.
|
||||
pub fn on_data(&mut self, ui: &mut egui::Ui, data: Option<String>) {
|
||||
fn on_data(&mut self, ui: &mut egui::Ui, data: Option<String>) {
|
||||
let wallets_size = self.wallets.list().len();
|
||||
if wallets_size == 0 {
|
||||
return;
|
||||
@@ -348,7 +366,7 @@ impl WalletsContent {
|
||||
|
||||
/// Show initial wallet creation [`Modal`].
|
||||
pub fn show_add_wallet_modal(&mut self) {
|
||||
self.add_wallet_modal_content = Some(AddWalletModal::default());
|
||||
self.add_wallet_modal_content = AddWalletModal::default();
|
||||
Modal::new(ADD_WALLET_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.add"))
|
||||
@@ -357,50 +375,20 @@ impl WalletsContent {
|
||||
|
||||
/// Show wallet selection with provided optional data.
|
||||
fn show_wallet_selection_modal(&mut self, data: Option<String>) {
|
||||
self.wallet_selection_content = Some(WalletsModal::new(None, data, true));
|
||||
self.wallet_selection_content = WalletsModal::new(None, data, true);
|
||||
Modal::new(SELECT_WALLET_MODAL)
|
||||
.position(ModalPosition::Center)
|
||||
.title(t!("network_settings.choose_wallet"))
|
||||
.show();
|
||||
}
|
||||
|
||||
/// Handle Back key event returning `false` when event was handled.
|
||||
pub fn on_back(&mut self, cb: &dyn PlatformCallbacks) -> bool {
|
||||
if self.showing_settings() {
|
||||
// Close settings.
|
||||
self.settings_content = None;
|
||||
return false;
|
||||
} else if self.creating_wallet() {
|
||||
// Close wallet creation.
|
||||
let creation = self.creation_content.as_mut().unwrap();
|
||||
if creation.on_back() {
|
||||
self.creation_content = None;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if self.showing_wallet() {
|
||||
let content = self.wallet_content.as_mut().unwrap();
|
||||
// Close opened QR code scanner.
|
||||
if content.qr_scan_content.is_some() {
|
||||
cb.stop_camera();
|
||||
content.qr_scan_content = None;
|
||||
return false;
|
||||
}
|
||||
// Close opened wallet.
|
||||
self.wallet_content = None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Draw [`TitlePanel`] content.
|
||||
fn title_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
dual_panel: bool,
|
||||
show_wallet: bool,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
let show_list = self.show_wallets_at_dual_panel;
|
||||
let show_list = AppConfig::show_wallets_at_dual_panel();
|
||||
let showing_settings = self.showing_settings();
|
||||
let creating_wallet = self.creating_wallet();
|
||||
let qr_scan = {
|
||||
@@ -501,7 +489,6 @@ impl WalletsContent {
|
||||
SUITCASE
|
||||
};
|
||||
View::title_button_big(ui, list_icon, |_| {
|
||||
self.show_wallets_at_dual_panel = !show_list;
|
||||
AppConfig::toggle_show_wallets_at_dual_panel();
|
||||
});
|
||||
}
|
||||
@@ -586,9 +573,8 @@ impl WalletsContent {
|
||||
let mut show_selection = false;
|
||||
View::item_button(ui, CornerRadius::default(), GLOBE, None, || {
|
||||
self.wallet_content = Some(WalletContent::new(wallet.clone(), None));
|
||||
self.conn_selection_content = Some(
|
||||
WalletConnectionModal::new(wallet.get_current_connection())
|
||||
);
|
||||
self.conn_selection_content =
|
||||
WalletConnectionModal::new(wallet.get_current_connection());
|
||||
// Show connection selection modal.
|
||||
Modal::new(SELECT_CONNECTION_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
@@ -657,17 +643,17 @@ impl WalletsContent {
|
||||
/// Show [`Modal`] to select and open wallet.
|
||||
fn show_opening_modal(&mut self, wallet: Wallet, data: Option<String>) {
|
||||
self.wallet_content = Some(WalletContent::new(wallet.clone(), None));
|
||||
self.open_wallet_content = Some(OpenWalletModal::new(wallet, data));
|
||||
self.open_wallet_content = OpenWalletModal::new(data);
|
||||
Modal::new(OPEN_WALLET_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.open"))
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if it's possible to show [`WalletsContent`] and [`WalletContent`] panels at same time.
|
||||
fn is_dual_panel_mode(ui: &mut egui::Ui) -> bool {
|
||||
let dual_panel_root = Content::is_dual_panel_mode(ui.ctx());
|
||||
let max_width = ui.available_width();
|
||||
dual_panel_root && max_width >= (Content::SIDE_PANEL_WIDTH * 2.0) + View::get_right_inset()
|
||||
}
|
||||
/// Check if it's possible to show [`WalletsContent`] and [`WalletContent`] panels at same time.
|
||||
fn is_dual_panel_mode(ui: &mut egui::Ui) -> bool {
|
||||
let dual_panel_root = Content::is_dual_panel_mode(ui.ctx());
|
||||
let max_width = ui.available_width();
|
||||
dual_panel_root && max_width >= (Content::SIDE_PANEL_WIDTH * 2.0) + View::get_right_inset()
|
||||
}
|
||||
+22
-21
@@ -20,7 +20,7 @@ use crate::gui::Colors;
|
||||
use crate::gui::icons::{CHECK, CLIPBOARD_TEXT, COPY, SCAN};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, View, CameraScanModal};
|
||||
use crate::gui::views::types::{LinePosition, ModalContainer, ModalPosition, QrScanResult};
|
||||
use crate::gui::views::types::{LinePosition, ContentContainer, ModalPosition, QrScanResult};
|
||||
use crate::gui::views::wallets::creation::MnemonicSetup;
|
||||
use crate::gui::views::wallets::creation::types::Step;
|
||||
use crate::gui::views::wallets::ConnectionSettings;
|
||||
@@ -29,7 +29,7 @@ use crate::wallet::{ExternalConnection, Wallet};
|
||||
use crate::wallet::types::PhraseMode;
|
||||
|
||||
/// Wallet creation content.
|
||||
pub struct WalletCreation {
|
||||
pub struct WalletCreationContent {
|
||||
/// Wallet name.
|
||||
pub name: String,
|
||||
/// Wallet password.
|
||||
@@ -48,16 +48,15 @@ pub struct WalletCreation {
|
||||
|
||||
/// Flag to check if an error occurred during wallet creation.
|
||||
creation_error: Option<String>,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
const QR_CODE_PHRASE_SCAN_MODAL: &'static str = "qr_code_rec_phrase_scan_modal";
|
||||
|
||||
impl ModalContainer for WalletCreation {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for WalletCreationContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
QR_CODE_PHRASE_SCAN_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -86,10 +85,16 @@ impl ModalContainer for WalletCreation {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, _: &mut egui::Ui, _: &dyn PlatformCallbacks) {}
|
||||
}
|
||||
|
||||
impl WalletCreation {
|
||||
/// Create new wallet creation instance from name and password.
|
||||
impl WalletCreationContent {
|
||||
/// Create new wallet creation content from name and password.
|
||||
pub fn new(name: String, pass: ZeroingString) -> Self {
|
||||
Self {
|
||||
name,
|
||||
@@ -99,19 +104,15 @@ impl WalletCreation {
|
||||
mnemonic_setup: MnemonicSetup::default(),
|
||||
network_setup: ConnectionSettings::default(),
|
||||
creation_error: None,
|
||||
modal_ids: vec![
|
||||
QR_CODE_PHRASE_SCAN_MODAL
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw wallet creation content.
|
||||
pub fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
on_create: impl FnMut(Wallet)) {
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
pub fn content_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
on_create: impl FnMut(Wallet)) {
|
||||
self.ui(ui, cb);
|
||||
egui::TopBottomPanel::bottom("wallet_creation_step_panel")
|
||||
.frame(egui::Frame {
|
||||
inner_margin: Margin {
|
||||
@@ -350,14 +351,14 @@ impl WalletCreation {
|
||||
/// Draw wallet creation [`Step`] content.
|
||||
fn step_content_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
match &self.step {
|
||||
Step::EnterMnemonic => self.mnemonic_setup.ui(ui, cb),
|
||||
Step::EnterMnemonic => self.mnemonic_setup.import_ui(ui, cb),
|
||||
Step::ConfirmMnemonic => self.mnemonic_setup.confirm_ui(ui, cb),
|
||||
Step::SetupConnection => {
|
||||
// Redraw if node is running.
|
||||
if Node::is_running() && !Content::is_dual_panel_mode(ui.ctx()) {
|
||||
ui.ctx().request_repaint_after(Node::STATS_UPDATE_DELAY);
|
||||
}
|
||||
self.network_setup.create_ui(ui, cb)
|
||||
self.network_setup.content_ui(ui, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ use crate::gui::Colors;
|
||||
use crate::gui::icons::PENCIL;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, View, TextEdit};
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::wallet::Mnemonic;
|
||||
use crate::wallet::types::{PhraseMode, PhraseSize, PhraseWord};
|
||||
|
||||
@@ -33,9 +33,6 @@ pub struct MnemonicSetup {
|
||||
word_edit: String,
|
||||
/// Flag to check if entered word is valid at [`Modal`].
|
||||
valid_word_edit: bool,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for word input [`Modal`].
|
||||
@@ -48,16 +45,15 @@ impl Default for MnemonicSetup {
|
||||
word_index_edit: 0,
|
||||
word_edit: String::from(""),
|
||||
valid_word_edit: true,
|
||||
modal_ids: vec![
|
||||
WORD_INPUT_MODAL
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for MnemonicSetup {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for MnemonicSetup {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
WORD_INPUT_MODAL
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -69,14 +65,19 @@ impl ModalContainer for MnemonicSetup {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl MnemonicSetup {
|
||||
/// Draw content for phrase input step.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
/// Draw content for phrase import step.
|
||||
pub fn import_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
ui.add_space(10.0);
|
||||
|
||||
// Show mode and type setup.
|
||||
@@ -89,12 +90,8 @@ impl MnemonicSetup {
|
||||
// Show words setup.
|
||||
self.word_list_ui(ui, self.mnemonic.mode() == PhraseMode::Import);
|
||||
}
|
||||
|
||||
/// Draw content for phrase confirmation step.
|
||||
pub fn confirm_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
ui.add_space(4.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
let text = format!("{}:", t!("wallets.recovery_phrase"));
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
mod mnemonic;
|
||||
pub use mnemonic::MnemonicSetup;
|
||||
|
||||
mod creation;
|
||||
pub use creation::WalletCreation;
|
||||
mod content;
|
||||
pub use content::WalletCreationContent;
|
||||
|
||||
pub mod types;
|
||||
@@ -18,13 +18,9 @@ use grin_util::ZeroingString;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Wallet opening [`Modal`] content.
|
||||
pub struct OpenWalletModal {
|
||||
/// Wallet to open.
|
||||
wallet: Wallet,
|
||||
|
||||
/// Password to open wallet.
|
||||
pass_edit: String,
|
||||
/// Flag to check if wrong password was entered.
|
||||
@@ -36,9 +32,8 @@ pub struct OpenWalletModal {
|
||||
|
||||
impl OpenWalletModal {
|
||||
/// Create new content instance.
|
||||
pub fn new(wallet: Wallet, data: Option<String>) -> Self {
|
||||
pub fn new(data: Option<String>) -> Self {
|
||||
Self {
|
||||
wallet,
|
||||
pass_edit: "".to_string(),
|
||||
wrong_pass: false,
|
||||
data,
|
||||
@@ -49,20 +44,17 @@ impl OpenWalletModal {
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
mut on_continue: impl FnMut(Wallet, Option<String>)) {
|
||||
mut on_continue: impl FnMut(ZeroingString, &Option<String>) -> bool) {
|
||||
// Callback for button to continue.
|
||||
let mut on_continue = |m: &mut OpenWalletModal| {
|
||||
let pass = m.pass_edit.clone();
|
||||
if pass.is_empty() {
|
||||
return;
|
||||
}
|
||||
match m.wallet.open(ZeroingString::from(pass)) {
|
||||
Ok(_) => {
|
||||
m.pass_edit = "".to_string();
|
||||
Modal::close();
|
||||
on_continue(m.wallet.clone(), m.data.clone());
|
||||
}
|
||||
Err(_) => m.wrong_pass = true
|
||||
m.wrong_pass = !on_continue(ZeroingString::from(pass), &m.data);
|
||||
if !m.wrong_pass {
|
||||
m.pass_edit = "".to_string();
|
||||
Modal::close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Align, Layout, RichText, ScrollArea, StrokeKind};
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{CHECK, CHECK_FAT, COMPUTER_TOWER, FOLDER_OPEN, GLOBE_SIMPLE, PLUGS_CONNECTED};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::types::ModalPosition;
|
||||
use crate::gui::views::wallets::modals::OpenWalletModal;
|
||||
use crate::gui::views::wallets::wallet::types::wallet_status_text;
|
||||
use crate::wallet::{Wallet, WalletList};
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::wallet::types::ConnectionMethod;
|
||||
use crate::wallet::{Wallet, WalletList};
|
||||
|
||||
/// Wallet list [`Modal`] content
|
||||
pub struct WalletsModal {
|
||||
@@ -35,32 +32,19 @@ pub struct WalletsModal {
|
||||
|
||||
/// Flag to check if wallet can be opened from the list.
|
||||
can_open: bool,
|
||||
/// Wallet opening content.
|
||||
open_wallet_content: Option<OpenWalletModal>,
|
||||
}
|
||||
|
||||
impl WalletsModal {
|
||||
/// Create new content instance.
|
||||
pub fn new(selected_id: Option<i64>, data: Option<String>, can_open: bool) -> Self {
|
||||
Self { selected_id, data, can_open, open_wallet_content: None }
|
||||
Self { selected_id, data, can_open }
|
||||
}
|
||||
|
||||
/// Draw content.
|
||||
pub fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
modal: &Modal,
|
||||
wallets: &WalletList,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
mut on_select: impl FnMut(Wallet, Option<String>)) {
|
||||
// Draw wallet opening modal content.
|
||||
if let Some(open_content) = self.open_wallet_content.as_mut() {
|
||||
open_content.ui(ui, modal, cb, |wallet, data| {
|
||||
on_select(wallet, data);
|
||||
self.data = None;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
ui.add_space(4.0);
|
||||
ScrollArea::vertical()
|
||||
.max_height(373.0)
|
||||
@@ -123,14 +107,7 @@ impl WalletsModal {
|
||||
FOLDER_OPEN
|
||||
};
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), icon, None, || {
|
||||
if wallet.is_open() {
|
||||
on_select();
|
||||
} else {
|
||||
Modal::change_position(ModalPosition::CenterTop);
|
||||
self.open_wallet_content = Some(
|
||||
OpenWalletModal::new(wallet.clone(), self.data.clone())
|
||||
);
|
||||
}
|
||||
on_select();
|
||||
});
|
||||
} else {
|
||||
// Draw button to select wallet.
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROWS_CLOCKWISE, BRIDGE, CAMERA_ROTATE, CHAT_CIRCLE_TEXT, FOLDER_USER, GEAR_FINE, GRAPH, PACKAGE, POWER, SCAN, SPINNER, USERS_THREE};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, View, CameraContent};
|
||||
use crate::gui::views::types::{LinePosition, ModalContainer, ModalPosition, QrScanResult};
|
||||
use crate::gui::views::types::{LinePosition, ContentContainer, ModalPosition, QrScanResult};
|
||||
use crate::gui::views::wallets::{WalletTransactions, WalletMessages, WalletTransport};
|
||||
use crate::gui::views::wallets::types::{GRIN, WalletTab, WalletTabType};
|
||||
use crate::gui::views::wallets::wallet::modals::WalletAccountsModal;
|
||||
@@ -40,48 +40,47 @@ pub struct WalletContent {
|
||||
pub current_tab: Box<dyn WalletTab>,
|
||||
|
||||
/// Wallet accounts [`Modal`] content.
|
||||
accounts_modal_content: Option<WalletAccountsModal>,
|
||||
accounts_modal_content: WalletAccountsModal,
|
||||
|
||||
/// QR code scan content.
|
||||
pub qr_scan_content: Option<CameraContent>,
|
||||
|
||||
/// List of allowed [`Modal`] ids for this [`ModalContainer`].
|
||||
allowed_modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
/// Identifier for account list [`Modal`].
|
||||
const ACCOUNT_LIST_MODAL: &'static str = "account_list_modal";
|
||||
|
||||
impl ModalContainer for WalletContent {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.allowed_modal_ids
|
||||
impl ContentContainer for WalletContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
ACCOUNT_LIST_MODAL,
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
match modal.id {
|
||||
ACCOUNT_LIST_MODAL => {
|
||||
if let Some(content) = self.accounts_modal_content.as_mut() {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
content.ui(ui, &self.wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
self.accounts_modal_content.ui(ui, &self.wallet, modal, cb);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, _: &mut egui::Ui, _: &dyn PlatformCallbacks) {}
|
||||
}
|
||||
|
||||
impl WalletContent {
|
||||
/// Create new instance with optional data.
|
||||
pub fn new(wallet: Wallet, data: Option<String>) -> Self {
|
||||
let accounts_modal = WalletAccountsModal::new(wallet.accounts());
|
||||
let mut content = Self {
|
||||
wallet,
|
||||
accounts_modal_content: None,
|
||||
accounts_modal_content: accounts_modal,
|
||||
qr_scan_content: None,
|
||||
current_tab: Box::new(WalletTransactions::default()),
|
||||
allowed_modal_ids: vec![
|
||||
ACCOUNT_LIST_MODAL,
|
||||
],
|
||||
};
|
||||
if data.is_some() {
|
||||
content.on_data(data);
|
||||
@@ -97,7 +96,6 @@ impl WalletContent {
|
||||
/// Draw wallet content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
ui.ctx().request_repaint_after(Duration::from_millis(1000));
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
let dual_panel = Content::is_dual_panel_mode(ui.ctx());
|
||||
let show_wallets_dual = AppConfig::show_wallets_at_dual_panel();
|
||||
@@ -302,9 +300,7 @@ impl WalletContent {
|
||||
|
||||
// Draw button to show list of accounts.
|
||||
View::item_button(ui, View::item_rounding(1, 3, true), USERS_THREE, None, || {
|
||||
self.accounts_modal_content = Some(
|
||||
WalletAccountsModal::new(self.wallet.accounts())
|
||||
);
|
||||
self.accounts_modal_content = WalletAccountsModal::new(self.wallet.accounts());
|
||||
Modal::new(ACCOUNT_LIST_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.accounts"))
|
||||
|
||||
@@ -37,10 +37,10 @@ pub struct WalletMessages {
|
||||
first_draw: bool,
|
||||
|
||||
/// Invoice or sending request creation [`Modal`] content.
|
||||
request_modal_content: Option<MessageRequestModal>,
|
||||
request_modal_content: MessageRequestModal,
|
||||
|
||||
/// Wallet transaction [`Modal`] content.
|
||||
tx_info_content: Option<WalletTransactionModal>,
|
||||
tx_info_content: WalletTransactionModal,
|
||||
|
||||
/// Slatepacks message input text.
|
||||
message_edit: String,
|
||||
@@ -85,8 +85,8 @@ impl WalletMessages {
|
||||
message_loading: false,
|
||||
message_error: "".to_string(),
|
||||
message_result: Arc::new(Default::default()),
|
||||
tx_info_content: None,
|
||||
request_modal_content: None,
|
||||
tx_info_content: WalletTransactionModal::new(None, false),
|
||||
request_modal_content: MessageRequestModal::new(false),
|
||||
file_pick_button: FilePickButton::default(),
|
||||
scan_modal_content: None,
|
||||
}
|
||||
@@ -129,23 +129,19 @@ impl WalletMessages {
|
||||
Some(id) => {
|
||||
match id {
|
||||
REQUEST_MODAL => {
|
||||
if let Some(content) = self.request_modal_content.as_mut() {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
content.ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.request_modal_content.ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
TX_INFO_MODAL => {
|
||||
if let Some(content) = self.tx_info_content.as_mut() {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
content.ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.tx_info_content.ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
SCAN_QR_MODAL => {
|
||||
let mut result = None;
|
||||
if let Some(content) = self.scan_modal_content.as_mut() {
|
||||
Modal::ui(ui.ctx(), |ui, _| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, _, cb| {
|
||||
content.ui(ui, cb, |res| {
|
||||
result = Some(res.clone());
|
||||
Modal::close();
|
||||
@@ -217,7 +213,7 @@ impl WalletMessages {
|
||||
|
||||
/// Show [`Modal`] to create invoice or sending request.
|
||||
fn show_request_modal(&mut self, invoice: bool) {
|
||||
self.request_modal_content = Some(MessageRequestModal::new(invoice));
|
||||
self.request_modal_content = MessageRequestModal::new(invoice);
|
||||
let title = if invoice {
|
||||
t!("wallets.receive")
|
||||
} else {
|
||||
@@ -299,7 +295,7 @@ impl WalletMessages {
|
||||
Ok(tx) => {
|
||||
self.message_edit.clear();
|
||||
// Show transaction modal on success.
|
||||
self.tx_info_content = Some(WalletTransactionModal::new(wallet, tx, false));
|
||||
self.tx_info_content = WalletTransactionModal::new(Some(tx.data.id), false);
|
||||
Modal::new(TX_INFO_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.tx"))
|
||||
@@ -322,9 +318,8 @@ impl WalletMessages {
|
||||
// Show tx modal or show default error message.
|
||||
if let Some(tx) = wallet.tx_by_slate(&slate).as_ref() {
|
||||
self.message_edit.clear();
|
||||
self.tx_info_content = Some(
|
||||
WalletTransactionModal::new(wallet, tx, false)
|
||||
);
|
||||
self.tx_info_content =
|
||||
WalletTransactionModal::new(Some(tx.data.id), false);
|
||||
Modal::new(TX_INFO_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.tx"))
|
||||
@@ -427,7 +422,7 @@ impl WalletMessages {
|
||||
if exists {
|
||||
if let Some(tx) = wallet.tx_by_slate(&slate).as_ref() {
|
||||
self.message_edit.clear();
|
||||
self.tx_info_content = Some(WalletTransactionModal::new(wallet, tx, false));
|
||||
self.tx_info_content = WalletTransactionModal::new(Some(tx.data.id), false);
|
||||
Modal::new(TX_INFO_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.tx"))
|
||||
|
||||
@@ -229,7 +229,8 @@ impl MessageRequestModal {
|
||||
let result = r_request.as_ref().unwrap();
|
||||
match result {
|
||||
Ok(tx) => {
|
||||
self.result_tx_content = Some(WalletTransactionModal::new(wallet, tx, false));
|
||||
self.result_tx_content =
|
||||
Some(WalletTransactionModal::new(Some(tx.data.id), false));
|
||||
}
|
||||
Err(err) => {
|
||||
match err {
|
||||
|
||||
@@ -146,17 +146,17 @@ impl CommonSettings {
|
||||
Some(id) => {
|
||||
match id {
|
||||
NAME_EDIT_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.name_modal_ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
PASS_EDIT_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.pass_modal_ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
MIN_CONFIRMATIONS_EDIT_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.min_conf_modal_ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::network::ConnectionsContent;
|
||||
use crate::gui::views::network::modals::ExternalConnectionModal;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection, Wallet};
|
||||
use crate::wallet::types::ConnectionMethod;
|
||||
|
||||
@@ -31,9 +31,6 @@ pub struct ConnectionSettings {
|
||||
|
||||
/// External connection [`Modal`] content.
|
||||
ext_conn_modal: ExternalConnectionModal,
|
||||
|
||||
/// [`Modal`] identifiers allowed at this ui container.
|
||||
modal_ids: Vec<&'static str>
|
||||
}
|
||||
|
||||
impl Default for ConnectionSettings {
|
||||
@@ -41,16 +38,15 @@ impl Default for ConnectionSettings {
|
||||
Self {
|
||||
method: ConnectionMethod::Integrated,
|
||||
ext_conn_modal: ExternalConnectionModal::new(None),
|
||||
modal_ids: vec![
|
||||
ExternalConnectionModal::WALLET_ID
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalContainer for ConnectionSettings {
|
||||
fn modal_ids(&self) -> &Vec<&'static str> {
|
||||
&self.modal_ids
|
||||
impl ContentContainer for ConnectionSettings {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
ExternalConnectionModal::WALLET_ID
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self,
|
||||
@@ -64,20 +60,21 @@ impl ModalContainer for ConnectionSettings {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_back(&mut self, _: &dyn PlatformCallbacks) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, _: &mut egui::Ui, _: &dyn PlatformCallbacks) {}
|
||||
}
|
||||
|
||||
impl ConnectionSettings {
|
||||
/// Draw wallet creation setup content.
|
||||
pub fn create_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.ui(ui, cb);
|
||||
}
|
||||
|
||||
/// Draw existing wallet connection setup content.
|
||||
pub fn wallet_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
self.method = wallet.get_current_connection();
|
||||
|
||||
// Draw setup content.
|
||||
let changed = self.ui(ui, cb);
|
||||
let changed = self.content_ui(ui, cb);
|
||||
|
||||
if changed {
|
||||
wallet.update_connection(&self.method);
|
||||
@@ -90,10 +87,9 @@ impl ConnectionSettings {
|
||||
}
|
||||
|
||||
/// Draw connection setup content, returning `true` if connection was changed.
|
||||
fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) -> bool {
|
||||
pub fn content_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) -> bool {
|
||||
self.ui(ui, cb);
|
||||
let mut changed = false;
|
||||
// Draw modal content for current ui container.
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
ui.add_space(2.0);
|
||||
View::sub_title(ui, format!("{} {}", GLOBE, t!("wallets.conn_method")));
|
||||
|
||||
@@ -148,12 +148,12 @@ impl RecoverySettings {
|
||||
Some(id) => {
|
||||
match id {
|
||||
RECOVERY_PHRASE_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
self.recovery_phrase_modal_ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
DELETE_CONFIRMATION_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, _| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, _, _| {
|
||||
self.deletion_modal_ui(ui, wallet);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,20 +96,20 @@ impl WalletTransport {
|
||||
match id {
|
||||
SEND_TOR_MODAL => {
|
||||
if let Some(content) = self.send_modal_content.as_mut() {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
content.ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
TOR_SETTINGS_MODAL => {
|
||||
if let Some(content) = self.settings_modal_content.as_mut() {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
content.ui(ui, wallet, modal, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
QR_ADDRESS_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, _| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, _, cb| {
|
||||
self.qr_address_modal_ui(ui, cb);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ impl TransportSendModal {
|
||||
match res {
|
||||
Ok(tx) => {
|
||||
self.tx_info_content =
|
||||
Some(WalletTransactionModal::new(wallet, &tx, false));
|
||||
Some(WalletTransactionModal::new(Some(tx.data.id), false));
|
||||
}
|
||||
Err(_) => {
|
||||
self.error = true;
|
||||
|
||||
@@ -165,7 +165,7 @@ impl WalletTransactions {
|
||||
r.nw = 0.0 as u8;
|
||||
r.sw = 0.0 as u8;
|
||||
View::item_button(ui, r, FILE_TEXT, None, || {
|
||||
self.show_tx_info_modal(wallet, tx, false);
|
||||
self.show_tx_info_modal(tx, false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ impl WalletTransactions {
|
||||
if wallet_loaded && tx.can_finalize {
|
||||
let (icon, color) = (CHECK, Some(Colors::green()));
|
||||
View::item_button(ui, CornerRadius::default(), icon, color, || {
|
||||
self.show_tx_info_modal(wallet, tx, true);
|
||||
self.show_tx_info_modal(tx, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -246,14 +246,14 @@ impl WalletTransactions {
|
||||
Some(id) => {
|
||||
match id {
|
||||
TX_INFO_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, modal| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, modal, cb| {
|
||||
if let Some(content) = self.tx_info_content.as_mut() {
|
||||
content.ui(ui, wallet, modal, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
CANCEL_TX_CONFIRMATION_MODAL => {
|
||||
Modal::ui(ui.ctx(), |ui, _| {
|
||||
Modal::ui(ui.ctx(), cb, |ui, _, cb| {
|
||||
self.cancel_confirmation_modal(ui, wallet);
|
||||
});
|
||||
}
|
||||
@@ -453,8 +453,8 @@ impl WalletTransactions {
|
||||
}
|
||||
|
||||
/// Show transaction information [`Modal`].
|
||||
fn show_tx_info_modal(&mut self, wallet: &Wallet, tx: &WalletTransaction, finalize: bool) {
|
||||
let modal = WalletTransactionModal::new(wallet, tx, finalize);
|
||||
fn show_tx_info_modal(&mut self, tx: &WalletTransaction, finalize: bool) {
|
||||
let modal = WalletTransactionModal::new(Some(tx.data.id), finalize);
|
||||
self.tx_info_content = Some(modal);
|
||||
Modal::new(TX_INFO_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct WalletTransactionModal {
|
||||
tx_id: u32,
|
||||
|
||||
/// Response Slatepack message input value.
|
||||
response_edit: String,
|
||||
response_edit: Option<String>,
|
||||
|
||||
/// Flag to show transaction finalization input.
|
||||
show_finalization: bool,
|
||||
@@ -61,32 +61,10 @@ pub struct WalletTransactionModal {
|
||||
|
||||
impl WalletTransactionModal {
|
||||
/// Create new content instance with [`Wallet`] from provided [`WalletTransaction`].
|
||||
pub fn new(wallet: &Wallet, tx: &WalletTransaction, show_finalization: bool) -> Self {
|
||||
pub fn new(tx_id: Option<u32>, show_finalization: bool) -> Self {
|
||||
Self {
|
||||
tx_id: tx.data.id,
|
||||
response_edit: if !tx.cancelling && !tx.finalizing && !tx.data.confirmed &&
|
||||
tx.data.tx_slate_id.is_some() &&
|
||||
(tx.data.tx_type == TxLogEntryType::TxSent ||
|
||||
tx.data.tx_type == TxLogEntryType::TxReceived) {
|
||||
let mut slate = Slate::blank(1, false);
|
||||
slate.state = if tx.can_finalize {
|
||||
if tx.data.tx_type == TxLogEntryType::TxSent {
|
||||
SlateState::Standard1
|
||||
} else {
|
||||
SlateState::Invoice1
|
||||
}
|
||||
} else {
|
||||
if tx.data.tx_type == TxLogEntryType::TxReceived {
|
||||
SlateState::Standard2
|
||||
} else {
|
||||
SlateState::Invoice2
|
||||
}
|
||||
};
|
||||
slate.id = tx.data.tx_slate_id.unwrap();
|
||||
wallet.read_slatepack(&slate).unwrap_or("".to_string())
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
tx_id: tx_id.unwrap(),
|
||||
response_edit: None,
|
||||
finalize_edit: "".to_string(),
|
||||
finalize_error: false,
|
||||
show_finalization,
|
||||
@@ -121,13 +99,42 @@ impl WalletTransactionModal {
|
||||
}
|
||||
let tx = txs.get(0).unwrap();
|
||||
|
||||
// Check if response was loaded.
|
||||
if self.response_edit.is_none() {
|
||||
self.response_edit = Some(
|
||||
if !tx.cancelling && !tx.finalizing && !tx.data.confirmed &&
|
||||
tx.data.tx_slate_id.is_some() &&
|
||||
(tx.data.tx_type == TxLogEntryType::TxSent ||
|
||||
tx.data.tx_type == TxLogEntryType::TxReceived) {
|
||||
let mut slate = Slate::blank(1, false);
|
||||
slate.state = if tx.can_finalize {
|
||||
if tx.data.tx_type == TxLogEntryType::TxSent {
|
||||
SlateState::Standard1
|
||||
} else {
|
||||
SlateState::Invoice1
|
||||
}
|
||||
} else {
|
||||
if tx.data.tx_type == TxLogEntryType::TxReceived {
|
||||
SlateState::Standard2
|
||||
} else {
|
||||
SlateState::Invoice2
|
||||
}
|
||||
};
|
||||
slate.id = tx.data.tx_slate_id.unwrap();
|
||||
wallet.read_slatepack(&slate).unwrap_or("".to_string())
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Show transaction information.
|
||||
if self.qr_code_content.is_none() && self.scan_qr_content.is_none() {
|
||||
self.info_ui(ui, tx, wallet, cb);
|
||||
}
|
||||
|
||||
// Show Slatepack message interaction.
|
||||
if !self.response_edit.is_empty() {
|
||||
if !self.response_edit.as_ref().unwrap().is_empty() {
|
||||
self.message_ui(ui, tx, wallet, modal, cb);
|
||||
}
|
||||
|
||||
@@ -201,7 +208,7 @@ impl WalletTransactionModal {
|
||||
if let Ok(_) = res {
|
||||
self.show_finalization = false;
|
||||
self.finalize_edit = "".to_string();
|
||||
self.response_edit = "".to_string();
|
||||
self.response_edit = Some("".to_string());
|
||||
} else {
|
||||
self.finalize_error = true;
|
||||
}
|
||||
@@ -370,7 +377,7 @@ impl WalletTransactionModal {
|
||||
let message_edit = if self.show_finalization {
|
||||
&mut self.finalize_edit
|
||||
} else {
|
||||
&mut self.response_edit
|
||||
&mut self.response_edit.as_mut().unwrap()
|
||||
};
|
||||
let message_before = message_edit.clone();
|
||||
|
||||
@@ -471,14 +478,14 @@ impl WalletTransactionModal {
|
||||
let qr_text = format!("{} {}", QR_CODE, t!("qr_code"));
|
||||
View::button(ui, qr_text.clone(), Colors::white_or_black(false), || {
|
||||
let text = self.response_edit.clone();
|
||||
self.qr_code_content = Some(QrCodeContent::new(text, true));
|
||||
self.qr_code_content = Some(QrCodeContent::new(text.unwrap(), true));
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
// Draw copy button.
|
||||
let copy_text = format!("{} {}", COPY, t!("copy"));
|
||||
View::button(ui, copy_text, Colors::white_or_black(false), || {
|
||||
cb.copy_string_to_buffer(self.response_edit.clone());
|
||||
cb.copy_string_to_buffer(self.response_edit.clone().unwrap());
|
||||
self.finalize_edit = "".to_string();
|
||||
if tx.can_finalize {
|
||||
self.show_finalization = true;
|
||||
@@ -499,7 +506,7 @@ impl WalletTransactionModal {
|
||||
Colors::white_or_black(false), || {
|
||||
if let Some((s, _)) = wallet.read_slate_by_tx(tx) {
|
||||
let name = format!("{}.{}.slatepack", s.id, s.state);
|
||||
let data = self.response_edit.as_bytes().to_vec();
|
||||
let data = self.response_edit.as_ref().unwrap().as_bytes().to_vec();
|
||||
cb.share_data(name, data).unwrap_or_default();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user