wallet + ui: add account to config, show account info, amounts, optimize wallet content panels, update translations
This commit is contained in:
parent
bc6f2623d9
commit
322adf66b4
8 changed files with 265 additions and 37 deletions
|
@ -9,6 +9,10 @@ change: Change
|
|||
show: Show
|
||||
delete: Delete
|
||||
wallets:
|
||||
await_conf_amount: Awaiting confirmation
|
||||
await_fin_amount: Awaiting finalization
|
||||
locked_amount: Locked
|
||||
txs_empty: 'To receive/send coins use %{receive}/%{send} buttons at the bottom of the screen, to change wallet settings press %{settings}.'
|
||||
title: Wallets
|
||||
create_desc: Create or import existing wallet from saved recovery phrase.
|
||||
add: Add wallet
|
||||
|
@ -47,6 +51,7 @@ wallets:
|
|||
wallet_closing: Closing wallet
|
||||
wallet_checking: Checking wallet
|
||||
tx_loading: Loading transactions
|
||||
default_account: Default account
|
||||
recovery: Recovery
|
||||
repair_wallet: Repair wallet
|
||||
repair_desc: Check a wallet, repairing and restoring missing outputs if required. This operation will take time.
|
||||
|
@ -132,7 +137,7 @@ network_mining:
|
|||
disconnected: Disconnected
|
||||
network_settings:
|
||||
change_value: Change value
|
||||
stratum_ip: 'Stratum IP Address:'
|
||||
stratum_ip: 'Stratum IP address:'
|
||||
stratum_port: 'Stratum port:'
|
||||
port_unavailable: Specified port is unavailable
|
||||
restart_node_required: Node restart is required to apply changes.
|
||||
|
@ -140,8 +145,8 @@ network_settings:
|
|||
disable: Disable
|
||||
restart: Restart
|
||||
server: Server
|
||||
api_ip: 'API IP Address:'
|
||||
api_port: 'API Port:'
|
||||
api_ip: 'API IP address:'
|
||||
api_port: 'API port:'
|
||||
api_secret: 'Rest API and V2 Owner API token:'
|
||||
foreign_api_secret: 'Foreign API token:'
|
||||
disabled: Disabled
|
||||
|
|
|
@ -9,6 +9,10 @@ change: Изменить
|
|||
show: Показать
|
||||
delete: Удалить
|
||||
wallets:
|
||||
await_conf_amount: Ожидает подтверждения
|
||||
await_fin_amount: Ожидает завершения
|
||||
locked_amount: Заблокировано
|
||||
txs_empty: 'Для получения/отправки монет используйте кнопки %{receive}/%{send} внизу экрана, для изменения настроек кошелька нажмите %{settings}.'
|
||||
title: Кошельки
|
||||
create_desc: Создайте или импортируйте существующий кошелёк из сохранённой фразы восстановления.
|
||||
add: Добавить кошелёк
|
||||
|
@ -47,6 +51,7 @@ wallets:
|
|||
wallet_closing: Закрытие кошелька
|
||||
wallet_checking: Проверка кошелька
|
||||
tx_loading: Загрузка транзакций
|
||||
default_account: Стандартный аккаунт
|
||||
recovery: Восстановление
|
||||
repair_wallet: Починить кошелёк
|
||||
repair_desc: Проверить кошелёк, исправляя и восстанавливая недостающие выходы, если это необходимо. Эта операция займёт время.
|
||||
|
@ -132,7 +137,7 @@ network_mining:
|
|||
disconnected: Отключен
|
||||
network_settings:
|
||||
change_value: Изменить значение
|
||||
stratum_ip: 'Stratum IP Адрес:'
|
||||
stratum_ip: 'Stratum IP адрес:'
|
||||
stratum_port: 'Порт Stratum:'
|
||||
port_unavailable: Указанный порт недоступен
|
||||
restart_node_required: Для применения изменений требуется перезапуск узла.
|
||||
|
@ -140,8 +145,8 @@ network_settings:
|
|||
disable: Выключить
|
||||
restart: Перезапуск
|
||||
server: Сервер
|
||||
api_ip: 'API IP Адрес:'
|
||||
api_port: 'API Порт:'
|
||||
api_ip: 'API IP адрес:'
|
||||
api_port: 'API порт:'
|
||||
api_secret: 'Rest и V2 Owner API токен:'
|
||||
foreign_api_secret: 'Foreign API токен:'
|
||||
disabled: Отключен
|
||||
|
|
|
@ -14,17 +14,19 @@
|
|||
|
||||
use std::time::Duration;
|
||||
|
||||
use egui::{Margin, RichText};
|
||||
use egui::{Align, Layout, Margin, RichText, Rounding};
|
||||
use grin_chain::SyncStatus;
|
||||
use grin_core::core::amount_to_hr_string;
|
||||
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{DOWNLOAD, GEAR_FINE, POWER, REPEAT, UPLOAD, WALLET};
|
||||
use crate::gui::icons::{DOWNLOAD, FILE_ARCHIVE, GEAR_FINE, LIST, PACKAGE, PLUS, POWER, REPEAT, UPLOAD, WALLET};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Root, View};
|
||||
use crate::gui::views::wallets::{WalletInfo, WalletReceive, WalletSend, WalletSettings};
|
||||
use crate::gui::views::wallets::types::{WalletTab, WalletTabType};
|
||||
use crate::node::Node;
|
||||
use crate::wallet::types::WalletData;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Selected and opened wallet content.
|
||||
|
@ -45,9 +47,36 @@ impl WalletContent {
|
|||
frame: &mut eframe::Frame,
|
||||
wallet: &mut Wallet,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
let data = wallet.get_data();
|
||||
let data_empty = data.is_none();
|
||||
|
||||
// Show wallet balance panel when data is not empty and current tab is not Settings.
|
||||
let show_balance = self.current_tab.get_type() != WalletTabType::Settings && !data_empty;
|
||||
egui::TopBottomPanel::top("wallet_balance")
|
||||
.frame(egui::Frame {
|
||||
fill: Colors::FILL,
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
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_animated_inside(ui, show_balance, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
// Draw wallet tabs.
|
||||
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
Self::account_balance_ui(ui, data.as_ref().unwrap(), &wallet.config.account);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Show wallet tabs panel.
|
||||
egui::TopBottomPanel::bottom("wallet_tabs")
|
||||
.frame(egui::Frame {
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
fill: Colors::FILL,
|
||||
inner_margin: Margin {
|
||||
left: View::far_left_inset_margin(ui) + 4.0,
|
||||
|
@ -69,14 +98,8 @@ impl WalletContent {
|
|||
// Show tab content panel.
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
fill: Colors::WHITE,
|
||||
inner_margin: Margin {
|
||||
left: View::far_left_inset_margin(ui) + 4.0,
|
||||
right: View::get_right_inset() + 4.0,
|
||||
top: 3.0,
|
||||
bottom: 4.0,
|
||||
},
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
|
@ -84,13 +107,67 @@ impl WalletContent {
|
|||
});
|
||||
|
||||
// Refresh content after 1 second for synced wallet.
|
||||
if wallet.get_data().is_some() {
|
||||
if !data_empty {
|
||||
ui.ctx().request_repaint_after(Duration::from_millis(1000));
|
||||
} else {
|
||||
ui.ctx().request_repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw wallet account balance.
|
||||
fn account_balance_ui(ui: &mut egui::Ui, data: &WalletData, account: &Option<String>) {
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
rect.set_height(76.0);
|
||||
// Draw round background.
|
||||
let rounding = View::item_rounding(0, 1, false);
|
||||
ui.painter().rect(rect, rounding, Colors::BUTTON, View::ITEM_STROKE);
|
||||
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Setup padding for item buttons.
|
||||
ui.style_mut().spacing.button_padding = egui::vec2(14.0, 0.0);
|
||||
// Setup rounding for item buttons.
|
||||
ui.style_mut().visuals.widgets.inactive.rounding = Rounding::same(8.0);
|
||||
ui.style_mut().visuals.widgets.hovered.rounding = Rounding::same(8.0);
|
||||
ui.style_mut().visuals.widgets.active.rounding = Rounding::same(8.0);
|
||||
|
||||
// Draw button to add new account.
|
||||
View::item_button(ui, View::item_rounding(0, 1, true), PLUS, None, || {
|
||||
//TODO add account modal.
|
||||
});
|
||||
|
||||
// Draw button to show list of accounts.
|
||||
View::item_button(ui, Rounding::none(), LIST, None, || {
|
||||
//TODO: accounts list modal
|
||||
});
|
||||
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(6.0);
|
||||
ui.vertical(|ui| {
|
||||
ui.add_space(3.0);
|
||||
// Show spendable amount.
|
||||
let amount = amount_to_hr_string(data.info.amount_currently_spendable, false);
|
||||
let amount_text = format!("1234567{} ツ", amount);
|
||||
ui.label(RichText::new(amount_text).size(18.0).color(Colors::BLACK));
|
||||
|
||||
// Show account name.
|
||||
let account_name = match account {
|
||||
None => t!("wallets.default_account"),
|
||||
Some(name) => name.to_owned()
|
||||
};
|
||||
let account_text = format!("{} {}", FILE_ARCHIVE, account_name);
|
||||
ui.add_space(-1.0);
|
||||
View::ellipsize_text(ui, account_text, 15.0, Colors::TEXT);
|
||||
ui.add_space(1.0);
|
||||
|
||||
// Show confirmed height.
|
||||
let height_text = format!("{} {}", PACKAGE, data.info.last_confirmed_height);
|
||||
ui.label(RichText::new(height_text).size(15.0).color(Colors::GRAY));
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw tab buttons in the bottom of the screen.
|
||||
fn tabs_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.scope(|ui| {
|
||||
|
|
|
@ -12,10 +12,17 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::{Margin, RichText};
|
||||
use grin_core::core::amount_to_hr_string;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{DOWNLOAD, GEAR_FINE, UPLOAD};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Root, View};
|
||||
use crate::gui::views::wallets::types::WalletTab;
|
||||
use crate::gui::views::wallets::wallet::types::WalletTabType;
|
||||
use crate::gui::views::wallets::wallet::WalletContent;
|
||||
use crate::wallet::types::WalletData;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Wallet info tab content.
|
||||
|
@ -35,5 +42,65 @@ impl WalletTab for WalletInfo {
|
|||
if WalletContent::sync_ui(ui, frame, wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = wallet.get_data().unwrap();
|
||||
|
||||
// Show wallet transactions panel.
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
stroke: View::ITEM_STROKE,
|
||||
fill: Colors::BUTTON,
|
||||
inner_margin: Margin {
|
||||
left: View::far_left_inset_margin(ui) + 4.0,
|
||||
right: View::get_right_inset() + 4.0,
|
||||
top: 0.0,
|
||||
bottom: 4.0,
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
self.txs_ui(ui, &data);
|
||||
});
|
||||
});
|
||||
if data.txs.is_empty() {
|
||||
View::center_content(ui, 96.0, |ui| {
|
||||
let empty_text = t!(
|
||||
"wallets.txs_empty",
|
||||
"receive" => DOWNLOAD,
|
||||
"send" => UPLOAD,
|
||||
"settings" => GEAR_FINE
|
||||
);
|
||||
ui.label(RichText::new(empty_text).size(16.0).color(Colors::INACTIVE_TEXT));
|
||||
});
|
||||
} else {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl WalletInfo {
|
||||
/// Draw transactions content.
|
||||
fn txs_ui(&self, ui: &mut egui::Ui, data: &WalletData) {
|
||||
// Show awaiting confirmation amount.
|
||||
let awaiting_conf = amount_to_hr_string(data.info.amount_awaiting_confirmation, false);
|
||||
View::rounded_box(ui,
|
||||
format!("{} ツ", awaiting_conf),
|
||||
t!("wallets.await_conf_amount"),
|
||||
[false, false, false, false]);
|
||||
// Show awaiting finalization amount.
|
||||
let awaiting_conf = amount_to_hr_string(data.info.amount_awaiting_finalization, false);
|
||||
View::rounded_box(ui,
|
||||
format!("{} ツ", awaiting_conf),
|
||||
t!("wallets.await_fin_amount"),
|
||||
[false, false, false, false]);
|
||||
// Show locked amount.
|
||||
let awaiting_conf = amount_to_hr_string(data.info.amount_locked, false);
|
||||
View::rounded_box(ui,
|
||||
format!("{} ツ", awaiting_conf),
|
||||
t!("wallets.locked_amount"),
|
||||
[false, false, true, true]);
|
||||
}
|
||||
}
|
|
@ -12,12 +12,16 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::Margin;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::View;
|
||||
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||
use crate::gui::views::wallets::wallet::WalletContent;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Receive funds tab content.
|
||||
/// Receiving tab content.
|
||||
#[derive(Default)]
|
||||
pub struct WalletReceive;
|
||||
|
||||
|
@ -34,5 +38,29 @@ impl WalletTab for WalletReceive {
|
|||
if WalletContent::sync_ui(ui, frame, wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show receiving content panel.
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
fill: Colors::WHITE,
|
||||
inner_margin: Margin {
|
||||
left: View::far_left_inset_margin(ui) + 4.0,
|
||||
right: View::get_right_inset() + 4.0,
|
||||
top: 3.0,
|
||||
bottom: 4.0,
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
self.receive_ui(ui, wallet);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl WalletReceive {
|
||||
/// Draw receiving content.
|
||||
pub fn receive_ui(&self, ui: &mut egui::Ui, wallet: &mut Wallet) {
|
||||
|
||||
}
|
||||
}
|
|
@ -12,12 +12,15 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::Margin;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::View;
|
||||
use crate::gui::views::wallets::wallet::types::{WalletTab, WalletTabType};
|
||||
use crate::gui::views::wallets::wallet::WalletContent;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
/// Send funds tab content.
|
||||
/// Sending tab content.
|
||||
#[derive(Default)]
|
||||
pub struct WalletSend;
|
||||
|
||||
|
@ -30,9 +33,33 @@ impl WalletTab for WalletSend {
|
|||
ui: &mut egui::Ui,
|
||||
frame: &mut eframe::Frame,
|
||||
wallet: &mut Wallet,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
_: &dyn PlatformCallbacks) {
|
||||
if WalletContent::sync_ui(ui, frame, wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show sending content panel.
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
fill: Colors::WHITE,
|
||||
inner_margin: Margin {
|
||||
left: View::far_left_inset_margin(ui) + 4.0,
|
||||
right: View::get_right_inset() + 4.0,
|
||||
top: 3.0,
|
||||
bottom: 4.0,
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
self.send_ui(ui, wallet);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl WalletSend {
|
||||
/// Draw sending content.
|
||||
pub fn send_ui(&self, ui: &mut egui::Ui, wallet: &mut Wallet) {
|
||||
|
||||
}
|
||||
}
|
|
@ -12,8 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::{Id, ScrollArea};
|
||||
use egui::{Id, Margin, ScrollArea};
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Root, View};
|
||||
use crate::gui::views::wallets::setup::{CommonSetup, ConnectionSetup, RecoverySetup};
|
||||
|
@ -59,20 +60,35 @@ impl WalletTab for WalletSettings {
|
|||
return;
|
||||
}
|
||||
|
||||
ScrollArea::vertical()
|
||||
.id_source(Id::from("wallet_settings_scroll").with(wallet.config.id))
|
||||
.auto_shrink([false; 2])
|
||||
.show(ui, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
// Show common wallet setup.
|
||||
self.common_setup.ui(ui, frame, wallet, cb);
|
||||
// Show wallet connections setup.
|
||||
self.conn_setup.wallet_ui(ui, frame, wallet, cb);
|
||||
// Show wallet recovery setup.
|
||||
self.recovery_setup.ui(ui, frame, wallet, cb);
|
||||
// Show settings content panel.
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
fill: Colors::WHITE,
|
||||
inner_margin: Margin {
|
||||
left: View::far_left_inset_margin(ui) + 4.0,
|
||||
right: View::get_right_inset() + 4.0,
|
||||
top: 3.0,
|
||||
bottom: 4.0,
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
ScrollArea::vertical()
|
||||
.id_source(Id::from("wallet_settings_scroll").with(wallet.config.id))
|
||||
.auto_shrink([false; 2])
|
||||
.show(ui, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
// Show common wallet setup.
|
||||
self.common_setup.ui(ui, frame, wallet, cb);
|
||||
// Show wallet connections setup.
|
||||
self.conn_setup.wallet_ui(ui, frame, wallet, cb);
|
||||
// Show wallet recovery setup.
|
||||
self.recovery_setup.ui(ui, frame, wallet, cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -24,11 +24,13 @@ use crate::wallet::types::ConnectionMethod;
|
|||
/// Wallet configuration.
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct WalletConfig {
|
||||
/// Last chosen wallet account label.
|
||||
pub account: Option<String>,
|
||||
/// Chain type for current wallet.
|
||||
pub chain_type: ChainTypes,
|
||||
/// Identifier for a wallet.
|
||||
pub id: i64,
|
||||
/// Human-readable wallet name for ui.
|
||||
/// Wallet name.
|
||||
pub name: String,
|
||||
/// External connection identifier.
|
||||
pub ext_conn_id: Option<i64>,
|
||||
|
@ -41,11 +43,11 @@ pub const BASE_DIR_NAME: &'static str = "wallets";
|
|||
/// Wallet configuration file name.
|
||||
const CONFIG_FILE_NAME: &'static str = "grim-wallet.toml";
|
||||
|
||||
/// Minimal amount of confirmations default value.
|
||||
/// Default value of minimal amount of confirmations.
|
||||
const MIN_CONFIRMATIONS_DEFAULT: u64 = 10;
|
||||
|
||||
impl WalletConfig {
|
||||
/// Create wallet config.
|
||||
/// Create new wallet config.
|
||||
pub fn create(name: String, conn_method: &ConnectionMethod) -> WalletConfig {
|
||||
// Setup configuration path.
|
||||
let id = chrono::Utc::now().timestamp();
|
||||
|
@ -53,6 +55,7 @@ impl WalletConfig {
|
|||
let config_path = Self::get_config_file_path(chain_type, id);
|
||||
// Write configuration to the file.
|
||||
let config = WalletConfig {
|
||||
account: None,
|
||||
chain_type,
|
||||
id,
|
||||
name,
|
||||
|
@ -60,7 +63,7 @@ impl WalletConfig {
|
|||
ConnectionMethod::Integrated => None,
|
||||
ConnectionMethod::External(id) => Some(*id)
|
||||
},
|
||||
min_confirmations: MIN_CONFIRMATIONS_DEFAULT,
|
||||
min_confirmations: MIN_CONFIRMATIONS_DEFAULT
|
||||
};
|
||||
Settings::write_to_file(&config, config_path);
|
||||
config
|
||||
|
|
Loading…
Reference in a new issue