config + ui: fix connections dir, add wallet tabs, initial wallet loading content, fix wallet content width, update translations
This commit is contained in:
parent
7333da63bd
commit
0ec5d415b1
14 changed files with 315 additions and 56 deletions
|
@ -29,7 +29,13 @@ wallets:
|
||||||
wrong_pass: Entered password is wrong
|
wrong_pass: Entered password is wrong
|
||||||
locked: Locked
|
locked: Locked
|
||||||
unlocked: Unlocked
|
unlocked: Unlocked
|
||||||
enable_node_required: 'Enable integrated node to use the wallet or change connection settings by selecting %{settings} at the bottom of the screen.'
|
enable_node: 'Enable integrated node to use the wallet or change connection settings by selecting %{settings} at the bottom of the screen.'
|
||||||
|
wallet_loading: 'Wallet is loading'
|
||||||
|
wallet_loading_err: 'An error occurred during loading the wallet, you can retry or change connection settings by selecting %{settings} at the bottom of the screen.'
|
||||||
|
wallet: Wallet
|
||||||
|
send: Send
|
||||||
|
receive: Receive
|
||||||
|
settings: Wallet settings
|
||||||
network:
|
network:
|
||||||
self: Network
|
self: Network
|
||||||
node: Integrated node
|
node: Integrated node
|
||||||
|
|
|
@ -29,7 +29,13 @@ wallets:
|
||||||
wrong_pass: Введён неправильный пароль
|
wrong_pass: Введён неправильный пароль
|
||||||
locked: Заблокирован
|
locked: Заблокирован
|
||||||
unlocked: Разблокирован
|
unlocked: Разблокирован
|
||||||
enable_node_required: 'Чтобы использовать кошелёк, включите встроенный узел или измените настройки подключения, выбрав %{settings} внизу экрана.'
|
enable_node: 'Чтобы использовать кошелёк, включите встроенный узел или измените настройки подключения, выбрав %{settings} внизу экрана.'
|
||||||
|
wallet_loading: 'Кошелёк загружается'
|
||||||
|
wallet_loading_err: 'Во время загрузки кошелька произошла ошибка, вы можете повторить загрузку или изменить настройки подключения, выбрав %{settings} внизу экрана.'
|
||||||
|
wallet: Кошелёк
|
||||||
|
send: Отправить
|
||||||
|
receive: Получить
|
||||||
|
settings: Настройки кошелька
|
||||||
network:
|
network:
|
||||||
self: Сеть
|
self: Сеть
|
||||||
node: Встроенный узел
|
node: Встроенный узел
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl WalletsContent {
|
||||||
let dual_panel = is_dual_panel_mode(ui, frame);
|
let dual_panel = is_dual_panel_mode(ui, frame);
|
||||||
let open_wallet_panel = dual_panel || show_wallet || create_wallet || empty_list;
|
let open_wallet_panel = dual_panel || show_wallet || create_wallet || empty_list;
|
||||||
let wallet_panel_width = self.wallet_panel_width(ui, empty_list, dual_panel, show_wallet);
|
let wallet_panel_width = self.wallet_panel_width(ui, empty_list, dual_panel, show_wallet);
|
||||||
let available_width_zero = ui.available_width() == 0.0;
|
let content_width = ui.available_width();
|
||||||
|
|
||||||
// Show title panel.
|
// Show title panel.
|
||||||
self.title_ui(ui, frame, dual_panel, create_wallet, show_wallet);
|
self.title_ui(ui, frame, dual_panel, create_wallet, show_wallet);
|
||||||
|
@ -135,12 +135,14 @@ impl WalletsContent {
|
||||||
})
|
})
|
||||||
.show_animated_inside(ui, open_wallet_panel, |ui| {
|
.show_animated_inside(ui, open_wallet_panel, |ui| {
|
||||||
// Do not draw content on zero width.
|
// Do not draw content on zero width.
|
||||||
if available_width_zero {
|
if content_width == 0.0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if create_wallet || !show_wallet {
|
if create_wallet || !show_wallet {
|
||||||
// Show wallet creation content.
|
// Show wallet creation content.
|
||||||
self.creation_content.ui(ui, frame, cb, |wallet| {
|
self.creation_content.ui(ui, frame, cb, |mut wallet| {
|
||||||
|
// Load the wallet.
|
||||||
|
Wallets::load(&mut wallet);
|
||||||
// Add created wallet to list.
|
// Add created wallet to list.
|
||||||
self.wallets.add(wallet);
|
self.wallets.add(wallet);
|
||||||
});
|
});
|
||||||
|
@ -148,7 +150,17 @@ impl WalletsContent {
|
||||||
for mut wallet in self.wallets.list.clone() {
|
for mut wallet in self.wallets.list.clone() {
|
||||||
// Show content for selected wallet.
|
// Show content for selected wallet.
|
||||||
if self.wallets.is_selected(wallet.config.id) {
|
if self.wallets.is_selected(wallet.config.id) {
|
||||||
|
// Setup wallet content width.
|
||||||
|
let mut rect = ui.available_rect_before_wrap();
|
||||||
|
let mut width = ui.available_width();
|
||||||
|
if dual_panel && self.show_list_at_dual_panel {
|
||||||
|
width = content_width - Root::SIDE_PANEL_WIDTH;
|
||||||
|
}
|
||||||
|
rect.set_width(width);
|
||||||
|
// Show wallet content.
|
||||||
|
ui.allocate_ui_at_rect(rect, |ui| {
|
||||||
self.wallet_content.ui(ui, frame, &mut wallet, cb);
|
self.wallet_content.ui(ui, frame, &mut wallet, cb);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +170,7 @@ impl WalletsContent {
|
||||||
// Show non-empty list if wallet is not creating.
|
// Show non-empty list if wallet is not creating.
|
||||||
if !empty_list && !create_wallet {
|
if !empty_list && !create_wallet {
|
||||||
// Flag to check if wallet list is hidden on the screen.
|
// Flag to check if wallet list is hidden on the screen.
|
||||||
let list_hidden = available_width_zero || (dual_panel && !self.show_list_at_dual_panel)
|
let list_hidden = content_width == 0.0 || (dual_panel && !self.show_list_at_dual_panel)
|
||||||
|| (!dual_panel && show_wallet);
|
|| (!dual_panel && show_wallet);
|
||||||
|
|
||||||
// Show wallet list panel.
|
// Show wallet list panel.
|
||||||
|
@ -194,7 +206,7 @@ impl WalletsContent {
|
||||||
= (!show_wallet && !dual_panel) || (dual_panel && show_wallet);
|
= (!show_wallet && !dual_panel) || (dual_panel && show_wallet);
|
||||||
|
|
||||||
// Show list of wallets.
|
// Show list of wallets.
|
||||||
let scroll = self.list_ui(ui, dual_panel, show_creation_btn, cb);
|
let scroll = self.wallet_list_ui(ui, dual_panel, show_creation_btn, cb);
|
||||||
|
|
||||||
if show_creation_btn {
|
if show_creation_btn {
|
||||||
// Setup right margin for button.
|
// Setup right margin for button.
|
||||||
|
@ -278,7 +290,7 @@ impl WalletsContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw list of wallets. Returns `true` if scroller is showing.
|
/// Draw list of wallets. Returns `true` if scroller is showing.
|
||||||
fn list_ui(&mut self,
|
fn wallet_list_ui(&mut self,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
dual_panel: bool,
|
dual_panel: bool,
|
||||||
show_creation_btn: bool,
|
show_creation_btn: bool,
|
||||||
|
|
|
@ -19,4 +19,4 @@ mod content;
|
||||||
pub use content::*;
|
pub use content::*;
|
||||||
|
|
||||||
mod wallet;
|
mod wallet;
|
||||||
use wallet::WalletContent;
|
use wallet::*;
|
|
@ -12,21 +12,26 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use egui::Margin;
|
use egui::{Margin, RichText};
|
||||||
use crate::gui::Colors;
|
|
||||||
|
|
||||||
|
use crate::gui::Colors;
|
||||||
|
use crate::gui::icons::{DOWNLOAD, UPLOAD, WALLET, WRENCH};
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::View;
|
use crate::gui::views::View;
|
||||||
use crate::wallet::Wallet;
|
use crate::gui::views::wallets::{WalletInfo, WalletReceive, WalletSend, WalletSettings};
|
||||||
|
use crate::gui::views::wallets::types::{WalletTab, WalletTabType};
|
||||||
|
use crate::node::Node;
|
||||||
|
use crate::wallet::{Wallet, Wallets};
|
||||||
|
|
||||||
/// Selected and opened wallet content.
|
/// Selected and opened wallet content.
|
||||||
pub struct WalletContent {
|
pub struct WalletContent {
|
||||||
|
/// Current tab content to show.
|
||||||
|
current_tab: Box<dyn WalletTab>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WalletContent {
|
impl Default for WalletContent {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {}
|
Self { current_tab: Box::new(WalletInfo::default()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +41,23 @@ impl WalletContent {
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
wallet: &mut Wallet,
|
wallet: &mut Wallet,
|
||||||
cb: &dyn PlatformCallbacks) {
|
cb: &dyn PlatformCallbacks) {
|
||||||
// Show wallet content.
|
// 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.
|
||||||
egui::CentralPanel::default()
|
egui::CentralPanel::default()
|
||||||
.frame(egui::Frame {
|
.frame(egui::Frame {
|
||||||
stroke: View::DEFAULT_STROKE,
|
stroke: View::DEFAULT_STROKE,
|
||||||
|
@ -50,10 +71,80 @@ impl WalletContent {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.show_inside(ui, |ui| {
|
.show_inside(ui, |ui| {
|
||||||
ui.label(&wallet.config.name);
|
});
|
||||||
//TODO: wallet content
|
|
||||||
|
// Refresh content after delay for loaded wallet.
|
||||||
|
if wallet.is_loaded() {
|
||||||
|
ui.ctx().request_repaint_after(Wallets::INFO_UPDATE_DELAY);
|
||||||
|
} 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| {
|
||||||
|
View::tab_button(ui, WRENCH, current_type == WalletTabType::Settings, || {
|
||||||
|
self.current_tab = Box::new(WalletSettings::default());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Content to draw when wallet is loading.
|
||||||
|
fn loading_ui(ui: &mut egui::Ui, wallet: &Wallet) {
|
||||||
|
if wallet.config.external_node_url.is_none() && !Node::is_running() {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if let Some(error) = &wallet.loading_error {
|
||||||
|
// View::center_content(ui, 162.0, |ui| {
|
||||||
|
// let text = t!("wallets.enable_node", "settings" => WRENCH);
|
||||||
|
// View::big_loading_spinner(ui);
|
||||||
|
// ui.add_space(18.0);
|
||||||
|
// let text = if wallet.loading_progress == 0 {
|
||||||
|
// t!("wallet_loading")
|
||||||
|
// } else {
|
||||||
|
// format!("{}: {}%", t!("wallet_loading"), wallet.loading_progress)
|
||||||
|
// };
|
||||||
|
// ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||||
|
// });
|
||||||
|
} else if !wallet.is_loaded() {
|
||||||
|
View::center_content(ui, 162.0, |ui| {
|
||||||
|
View::big_loading_spinner(ui);
|
||||||
|
ui.add_space(18.0);
|
||||||
|
let text = if wallet.loading_progress == 0 {
|
||||||
|
t!("wallets.wallet_loading")
|
||||||
|
} else {
|
||||||
|
format!("{}: {}%", t!("wallets.wallet_loading"), wallet.loading_progress)
|
||||||
|
};
|
||||||
|
ui.label(RichText::new(text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
30
src/gui/views/wallets/wallet/info.rs
Normal file
30
src/gui/views/wallets/wallet/info.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2023 The Grim Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
use crate::gui::views::wallets::types::WalletTab;
|
||||||
|
use crate::gui::views::wallets::wallet::types::WalletTabType;
|
||||||
|
|
||||||
|
/// Wallet info tab content.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WalletInfo;
|
||||||
|
|
||||||
|
impl WalletTab for WalletInfo {
|
||||||
|
fn get_type(&self) -> WalletTabType {
|
||||||
|
WalletTabType::Info
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,19 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
mod content;
|
pub mod types;
|
||||||
mod txs;
|
|
||||||
mod send;
|
|
||||||
mod settings;
|
|
||||||
mod receive;
|
|
||||||
|
|
||||||
|
mod info;
|
||||||
|
pub use info::WalletInfo;
|
||||||
|
|
||||||
|
mod receive;
|
||||||
|
pub use receive::WalletReceive;
|
||||||
|
|
||||||
|
mod send;
|
||||||
|
pub use send::WalletSend;
|
||||||
|
|
||||||
|
mod settings;
|
||||||
|
pub use settings::WalletSettings;
|
||||||
|
|
||||||
|
mod content;
|
||||||
pub use content::WalletContent;
|
pub use content::WalletContent;
|
|
@ -11,3 +11,19 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||||
|
|
||||||
|
/// Receive funds tab content.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WalletReceive;
|
||||||
|
|
||||||
|
impl WalletTab for WalletReceive {
|
||||||
|
fn get_type(&self) -> WalletTabType {
|
||||||
|
WalletTabType::Receive
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,3 +11,19 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||||
|
|
||||||
|
/// Send funds tab content.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WalletSend;
|
||||||
|
|
||||||
|
impl WalletTab for WalletSend {
|
||||||
|
fn get_type(&self) -> WalletTabType {
|
||||||
|
WalletTabType::Send
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,3 +11,19 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||||
|
|
||||||
|
/// Wallet settings tab content.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WalletSettings;
|
||||||
|
|
||||||
|
impl WalletTab for WalletSettings {
|
||||||
|
fn get_type(&self) -> WalletTabType {
|
||||||
|
WalletTabType::Settings
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,3 +11,20 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
|
||||||
|
/// Wallet tab content interface.
|
||||||
|
pub trait WalletTab {
|
||||||
|
fn get_type(&self) -> WalletTabType;
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Type of [`WalletTab`] content.
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum WalletTabType {
|
||||||
|
Info,
|
||||||
|
Receive,
|
||||||
|
Send,
|
||||||
|
Settings
|
||||||
|
}
|
|
@ -18,13 +18,13 @@ use lazy_static::lazy_static;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::Settings;
|
use crate::Settings;
|
||||||
use crate::wallet::{BASE_DIR_NAME, ExternalConnection};
|
use crate::wallet::ExternalConnection;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Static connections state to be accessible globally.
|
/// Static connections state to be accessible globally.
|
||||||
static ref CONNECTIONS_STATE: Arc<RwLock<ConnectionsConfig>> = Arc::new(
|
static ref CONNECTIONS_STATE: Arc<RwLock<ConnectionsConfig>> = Arc::new(
|
||||||
RwLock::new(
|
RwLock::new(
|
||||||
Settings::init_config(Settings::get_config_path(CONFIG_FILE_NAME, Some(BASE_DIR_NAME)))
|
Settings::init_config(Settings::get_config_path(CONFIG_FILE_NAME, None))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,13 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use grin_keychain::ExtKeychain;
|
||||||
|
use grin_wallet_impls::{DefaultLCProvider, HTTPNodeClient};
|
||||||
|
use grin_wallet_libwallet::WalletInst;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
/// Mnemonic phrase setup mode.
|
/// Mnemonic phrase setup mode.
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone)]
|
||||||
pub enum PhraseMode {
|
pub enum PhraseMode {
|
||||||
|
@ -56,3 +63,17 @@ impl PhraseSize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wallet instance type.
|
||||||
|
pub type WalletInstance = Arc<
|
||||||
|
Mutex<
|
||||||
|
Box<
|
||||||
|
dyn WalletInst<
|
||||||
|
'static,
|
||||||
|
DefaultLCProvider<'static, HTTPNodeClient, ExtKeychain>,
|
||||||
|
HTTPNodeClient,
|
||||||
|
ExtKeychain,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>;
|
|
@ -16,6 +16,7 @@ use std::{cmp, thread};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use grin_core::global;
|
use grin_core::global;
|
||||||
use grin_core::global::ChainTypes;
|
use grin_core::global::ChainTypes;
|
||||||
|
@ -33,6 +34,7 @@ use crate::node::NodeConfig;
|
||||||
use crate::wallet::{ConnectionsConfig, WalletConfig};
|
use crate::wallet::{ConnectionsConfig, WalletConfig};
|
||||||
use crate::wallet::selection::lock_tx_context;
|
use crate::wallet::selection::lock_tx_context;
|
||||||
use crate::wallet::tx::{add_inputs_to_slate, new_tx_slate};
|
use crate::wallet::tx::{add_inputs_to_slate, new_tx_slate};
|
||||||
|
use crate::wallet::types::WalletInstance;
|
||||||
use crate::wallet::updater::{cancel_tx, refresh_output_state, retrieve_txs};
|
use crate::wallet::updater::{cancel_tx, refresh_output_state, retrieve_txs};
|
||||||
|
|
||||||
/// [`Wallet`] list wrapper.
|
/// [`Wallet`] list wrapper.
|
||||||
|
@ -53,6 +55,12 @@ impl Default for Wallets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wallets {
|
impl Wallets {
|
||||||
|
/// Delay in seconds to update outputs after wallet opening.
|
||||||
|
pub const OUTPUTS_UPDATE_DELAY: Duration = Duration::from_millis(30 * 1000);
|
||||||
|
|
||||||
|
/// Delay in seconds to update wallet info.
|
||||||
|
pub const INFO_UPDATE_DELAY: Duration = Duration::from_millis(10 * 1000);
|
||||||
|
|
||||||
/// Initialize wallets from base directory for provided [`ChainType`].
|
/// Initialize wallets from base directory for provided [`ChainType`].
|
||||||
fn init(chain_type: ChainTypes) -> Vec<Wallet> {
|
fn init(chain_type: ChainTypes) -> Vec<Wallet> {
|
||||||
let mut wallets = Vec::new();
|
let mut wallets = Vec::new();
|
||||||
|
@ -121,21 +129,30 @@ impl Wallets {
|
||||||
// Get pmmr range output indexes.
|
// Get pmmr range output indexes.
|
||||||
match wallet.pmmr_range() {
|
match wallet.pmmr_range() {
|
||||||
Ok((mut lowest_index, highest_index)) => {
|
Ok((mut lowest_index, highest_index)) => {
|
||||||
println!("pmmr_range {} {}", lowest_index, highest_index);
|
println!("pmmr_range: {} {}", lowest_index, highest_index);
|
||||||
let mut from_index = lowest_index;
|
let mut from_index = lowest_index;
|
||||||
loop {
|
loop {
|
||||||
|
// Stop loop if wallet is not open.
|
||||||
|
if !wallet.is_open() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Scan outputs for last retrieved index.
|
// Scan outputs for last retrieved index.
|
||||||
println!("scan_outputs {} {}", from_index, highest_index);
|
println!("scan_outputs from {} to {}", from_index, highest_index);
|
||||||
match wallet.scan_outputs(from_index, highest_index) {
|
match wallet.scan_outputs(from_index, highest_index) {
|
||||||
Ok(last_index) => {
|
Ok(last_index) => {
|
||||||
println!("last_index {}", last_index);
|
println!("retrieved index: {}", last_index);
|
||||||
if lowest_index == 0 {
|
if lowest_index == 0 {
|
||||||
lowest_index = last_index;
|
lowest_index = last_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finish scanning or start new scan from last retrieved index.
|
||||||
if last_index == highest_index {
|
if last_index == highest_index {
|
||||||
|
println!("scan finished");
|
||||||
wallet.loading_progress = 100;
|
wallet.loading_progress = 100;
|
||||||
break;
|
wallet.is_loaded.store(true, Ordering::Relaxed);
|
||||||
} else {
|
} else {
|
||||||
|
println!("continue scan");
|
||||||
from_index = last_index;
|
from_index = last_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,17 +163,28 @@ impl Wallets {
|
||||||
(progress / range) as u8 * 100,
|
(progress / range) as u8 * 100,
|
||||||
99
|
99
|
||||||
);
|
);
|
||||||
println!("progress {}", wallet.loading_progress);
|
println!("progress: {}", wallet.loading_progress);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
if !wallet.is_loaded() {
|
||||||
wallet.loading_error = Some(e);
|
wallet.loading_error = Some(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wallet.is_loaded.store(true, Ordering::Relaxed);
|
|
||||||
|
// Stop loop if wallet is not open.
|
||||||
|
if !wallet.is_open() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan outputs at next cycle again.
|
||||||
|
println!("finished scanning, waiting");
|
||||||
|
thread::sleep(Self::OUTPUTS_UPDATE_DELAY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
wallet.loading_progress = 0;
|
||||||
wallet.loading_error = Some(e);
|
wallet.loading_error = Some(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,25 +207,11 @@ pub struct Wallet {
|
||||||
/// Flag to check if wallet is loaded and ready to use.
|
/// Flag to check if wallet is loaded and ready to use.
|
||||||
is_loaded: Arc<AtomicBool>,
|
is_loaded: Arc<AtomicBool>,
|
||||||
/// Error on wallet loading.
|
/// Error on wallet loading.
|
||||||
loading_error: Option<Error>,
|
pub loading_error: Option<Error>,
|
||||||
/// Loading progress in percents
|
/// Loading progress in percents
|
||||||
loading_progress: u8,
|
pub loading_progress: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wallet instance type.
|
|
||||||
type WalletInstance = Arc<
|
|
||||||
Mutex<
|
|
||||||
Box<
|
|
||||||
dyn WalletInst<
|
|
||||||
'static,
|
|
||||||
DefaultLCProvider<'static, HTTPNodeClient, ExtKeychain>,
|
|
||||||
HTTPNodeClient,
|
|
||||||
ExtKeychain,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
impl Wallet {
|
impl Wallet {
|
||||||
/// Create wallet from provided instance and config.
|
/// Create wallet from provided instance and config.
|
||||||
fn new(instance: WalletInstance, config: WalletConfig) -> Self {
|
fn new(instance: WalletInstance, config: WalletConfig) -> Self {
|
||||||
|
@ -326,6 +340,11 @@ impl Wallet {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if wallet is loaded and ready to use.
|
||||||
|
pub fn is_loaded(&self) -> bool {
|
||||||
|
self.is_loaded.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
/// Scan wallet outputs to check/repair the wallet.
|
/// Scan wallet outputs to check/repair the wallet.
|
||||||
fn scan_outputs(
|
fn scan_outputs(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Reference in a new issue