2023-04-27 01:28:55 +03:00
|
|
|
// Copyright 2023 The Grim Developers
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2023-08-09 04:19:15 +03:00
|
|
|
use std::time::Duration;
|
|
|
|
|
2023-08-03 23:49:11 +03:00
|
|
|
use egui::{Margin, RichText};
|
2023-08-09 20:11:44 +03:00
|
|
|
use grin_chain::SyncStatus;
|
2023-07-29 00:17:54 +03:00
|
|
|
|
2023-08-09 20:11:44 +03:00
|
|
|
use crate::AppConfig;
|
2023-08-03 23:49:11 +03:00
|
|
|
use crate::gui::Colors;
|
2023-08-09 20:11:44 +03:00
|
|
|
use crate::gui::icons::{DOWNLOAD, GEAR_FINE, POWER, REPEAT, UPLOAD, WALLET};
|
2023-04-27 01:28:55 +03:00
|
|
|
use crate::gui::platform::PlatformCallbacks;
|
2023-08-09 02:22:16 +03:00
|
|
|
use crate::gui::views::{Root, View};
|
2023-08-03 23:49:11 +03:00
|
|
|
use crate::gui::views::wallets::{WalletInfo, WalletReceive, WalletSend, WalletSettings};
|
|
|
|
use crate::gui::views::wallets::types::{WalletTab, WalletTabType};
|
|
|
|
use crate::node::Node;
|
2023-08-09 02:22:16 +03:00
|
|
|
use crate::wallet::Wallet;
|
2023-04-27 01:28:55 +03:00
|
|
|
|
2023-08-03 04:11:25 +03:00
|
|
|
/// Selected and opened wallet content.
|
2023-07-21 04:17:57 +03:00
|
|
|
pub struct WalletContent {
|
2023-08-03 23:49:11 +03:00
|
|
|
/// Current tab content to show.
|
|
|
|
current_tab: Box<dyn WalletTab>,
|
2023-07-13 03:54:27 +03:00
|
|
|
}
|
2023-04-27 01:28:55 +03:00
|
|
|
|
2023-07-29 00:17:54 +03:00
|
|
|
impl Default for WalletContent {
|
|
|
|
fn default() -> Self {
|
2023-08-03 23:49:11 +03:00
|
|
|
Self { current_tab: Box::new(WalletInfo::default()) }
|
2023-04-27 01:28:55 +03:00
|
|
|
}
|
2023-07-13 03:54:27 +03:00
|
|
|
}
|
2023-04-27 01:28:55 +03:00
|
|
|
|
2023-07-21 04:17:57 +03:00
|
|
|
impl WalletContent {
|
2023-07-29 00:17:54 +03:00
|
|
|
pub fn ui(&mut self,
|
|
|
|
ui: &mut egui::Ui,
|
|
|
|
frame: &mut eframe::Frame,
|
2023-08-03 00:00:23 +03:00
|
|
|
wallet: &mut Wallet,
|
2023-07-29 00:17:54 +03:00
|
|
|
cb: &dyn PlatformCallbacks) {
|
2023-08-03 23:49:11 +03:00
|
|
|
// Show bottom tabs.
|
|
|
|
egui::TopBottomPanel::bottom("wallet_tabs")
|
|
|
|
.frame(egui::Frame {
|
|
|
|
fill: Colors::FILL,
|
|
|
|
inner_margin: Margin {
|
|
|
|
left: View::far_left_inset_margin(ui) + 4.0,
|
|
|
|
right: View::get_right_inset() + 4.0,
|
|
|
|
top: 4.0,
|
|
|
|
bottom: View::get_bottom_inset() + 4.0,
|
|
|
|
},
|
|
|
|
..Default::default()
|
|
|
|
})
|
|
|
|
.show_inside(ui, |ui| {
|
|
|
|
self.tabs_ui(ui);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Show tab content.
|
2023-06-02 02:05:34 +03:00
|
|
|
egui::CentralPanel::default()
|
2023-07-13 03:54:27 +03:00
|
|
|
.frame(egui::Frame {
|
2023-06-02 02:05:34 +03:00
|
|
|
stroke: View::DEFAULT_STROKE,
|
2023-07-21 04:17:57 +03:00
|
|
|
fill: Colors::WHITE,
|
|
|
|
inner_margin: Margin {
|
|
|
|
left: View::far_left_inset_margin(ui) + 4.0,
|
2023-07-29 00:17:54 +03:00
|
|
|
right: View::get_right_inset() + 4.0,
|
|
|
|
top: 4.0,
|
2023-07-21 04:17:57 +03:00
|
|
|
bottom: 4.0,
|
|
|
|
},
|
2023-06-02 02:05:34 +03:00
|
|
|
..Default::default()
|
|
|
|
})
|
|
|
|
.show_inside(ui, |ui| {
|
2023-08-09 02:22:16 +03:00
|
|
|
self.current_tab.ui(ui, frame, wallet, cb);
|
2023-06-02 02:05:34 +03:00
|
|
|
});
|
2023-08-03 23:49:11 +03:00
|
|
|
|
2023-08-09 04:19:15 +03:00
|
|
|
// Refresh content after 1 second for loaded wallet.
|
2023-08-11 01:20:41 +03:00
|
|
|
if wallet.get_data().is_some() {
|
2023-08-09 04:19:15 +03:00
|
|
|
ui.ctx().request_repaint_after(Duration::from_millis(1000));
|
2023-08-03 23:49:11 +03:00
|
|
|
} else {
|
|
|
|
ui.ctx().request_repaint();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Draw tab buttons in the bottom of the screen.
|
|
|
|
fn tabs_ui(&mut self, ui: &mut egui::Ui) {
|
|
|
|
ui.scope(|ui| {
|
|
|
|
// Setup spacing between tabs.
|
|
|
|
ui.style_mut().spacing.item_spacing = egui::vec2(4.0, 0.0);
|
|
|
|
// Setup vertical padding inside tab button.
|
|
|
|
ui.style_mut().spacing.button_padding = egui::vec2(0.0, 8.0);
|
|
|
|
|
|
|
|
// Draw tab buttons.
|
|
|
|
let current_type = self.current_tab.get_type();
|
|
|
|
ui.columns(4, |columns| {
|
|
|
|
columns[0].vertical_centered_justified(|ui| {
|
|
|
|
View::tab_button(ui, WALLET, current_type == WalletTabType::Info, || {
|
|
|
|
self.current_tab = Box::new(WalletInfo::default());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[1].vertical_centered_justified(|ui| {
|
|
|
|
View::tab_button(ui, DOWNLOAD, current_type == WalletTabType::Receive, || {
|
|
|
|
self.current_tab = Box::new(WalletReceive::default());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[2].vertical_centered_justified(|ui| {
|
|
|
|
View::tab_button(ui, UPLOAD, current_type == WalletTabType::Send, || {
|
|
|
|
self.current_tab = Box::new(WalletSend::default());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[3].vertical_centered_justified(|ui| {
|
2023-08-09 04:19:15 +03:00
|
|
|
View::tab_button(ui, GEAR_FINE, current_type == WalletTabType::Settings, || {
|
2023-08-03 23:49:11 +03:00
|
|
|
self.current_tab = Box::new(WalletSettings::default());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2023-04-27 01:28:55 +03:00
|
|
|
}
|
2023-08-03 00:00:23 +03:00
|
|
|
|
2023-08-09 20:11:44 +03:00
|
|
|
/// Content to draw when wallet is loading, returns `true` if wallet is not ready.
|
|
|
|
pub fn loading_ui(ui: &mut egui::Ui, frame: &mut eframe::Frame, wallet: &Wallet) -> bool {
|
2023-08-11 01:20:41 +03:00
|
|
|
if wallet.is_closing() {
|
|
|
|
Self::loading_progress_ui(ui, wallet);
|
|
|
|
return true;
|
|
|
|
} else if wallet.config.ext_conn_id.is_none() {
|
2023-08-09 20:11:44 +03:00
|
|
|
if !Node::is_running() || Node::is_stopping() {
|
|
|
|
let dual_panel_root = Root::is_dual_panel_mode(frame);
|
2023-08-11 01:20:41 +03:00
|
|
|
View::center_content(ui, 108.0, |ui| {
|
2023-08-09 20:11:44 +03:00
|
|
|
let text = t!("wallets.enable_node", "settings" => GEAR_FINE);
|
|
|
|
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
2023-08-09 02:22:16 +03:00
|
|
|
ui.add_space(8.0);
|
2023-08-09 20:11:44 +03:00
|
|
|
// Show button to enable integrated node at non-dual root panel mode
|
|
|
|
// or when network connections are not showing and node is not stopping
|
|
|
|
if (!dual_panel_root || AppConfig::show_connections_network_panel())
|
|
|
|
&& !Node::is_stopping() {
|
|
|
|
let enable_node_text = format!("{} {}", POWER, t!("network.enable_node"));
|
|
|
|
View::button(ui, enable_node_text, Colors::GOLD, || {
|
|
|
|
Node::start();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return true
|
2023-08-11 01:20:41 +03:00
|
|
|
} else if wallet.loading_error()
|
|
|
|
&& Node::get_sync_status() == Some(SyncStatus::NoSync) {
|
|
|
|
Self::loading_error_ui(ui, wallet);
|
|
|
|
return true;
|
|
|
|
} else if wallet.get_data().is_none() {
|
|
|
|
Self::loading_progress_ui(ui, wallet);
|
2023-08-09 02:22:16 +03:00
|
|
|
return true;
|
2023-08-09 20:11:44 +03:00
|
|
|
}
|
2023-08-11 01:20:41 +03:00
|
|
|
} else if wallet.get_data().is_none() {
|
2023-08-09 20:11:44 +03:00
|
|
|
if wallet.loading_error() {
|
2023-08-11 01:20:41 +03:00
|
|
|
Self::loading_error_ui(ui, wallet);
|
2023-08-09 02:22:16 +03:00
|
|
|
} else {
|
2023-08-11 01:20:41 +03:00
|
|
|
Self::loading_progress_ui(ui, wallet);
|
2023-08-03 23:49:11 +03:00
|
|
|
}
|
2023-08-09 20:11:44 +03:00
|
|
|
return true;
|
2023-08-03 23:49:11 +03:00
|
|
|
}
|
2023-08-09 02:22:16 +03:00
|
|
|
false
|
2023-08-03 23:49:11 +03:00
|
|
|
}
|
2023-08-09 20:11:44 +03:00
|
|
|
|
2023-08-11 01:20:41 +03:00
|
|
|
/// Draw wallet loading error content.
|
|
|
|
fn loading_error_ui(ui: &mut egui::Ui, wallet: &Wallet) {
|
|
|
|
View::center_content(ui, 108.0, |ui| {
|
|
|
|
let text = t!("wallets.wallet_loading_err", "settings" => GEAR_FINE);
|
|
|
|
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
|
|
|
ui.add_space(8.0);
|
|
|
|
let retry_text = format!("{} {}", REPEAT, t!("retry"));
|
|
|
|
View::button(ui, retry_text, Colors::GOLD, || {
|
|
|
|
wallet.set_loading_error(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Draw wallet loading progress content.
|
|
|
|
fn loading_progress_ui(ui: &mut egui::Ui, wallet: &Wallet) {
|
2023-08-09 20:11:44 +03:00
|
|
|
View::center_content(ui, 162.0, |ui| {
|
|
|
|
View::big_loading_spinner(ui);
|
|
|
|
ui.add_space(18.0);
|
|
|
|
// Setup loading progress text.
|
2023-08-11 01:20:41 +03:00
|
|
|
let text = {
|
|
|
|
let info_progress = wallet.info_loading_progress();
|
|
|
|
if wallet.is_closing() {
|
|
|
|
t!("wallets.wallet_closing")
|
|
|
|
} else if info_progress != 100 {
|
|
|
|
if info_progress == 0 {
|
|
|
|
t!("wallets.wallet_loading")
|
|
|
|
} else {
|
|
|
|
format!("{}: {}%", t!("wallets.wallet_loading"), info_progress)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let tx_progress = wallet.txs_loading_progress();
|
|
|
|
if tx_progress == 0 {
|
|
|
|
t!("wallets.tx_loading")
|
|
|
|
} else {
|
|
|
|
format!("{}: {}%", t!("wallets.tx_loading"), tx_progress)
|
|
|
|
}
|
|
|
|
}
|
2023-08-09 20:11:44 +03:00
|
|
|
};
|
|
|
|
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
|
|
|
});
|
|
|
|
}
|
2023-04-27 01:28:55 +03:00
|
|
|
}
|