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;
|
2024-05-15 20:51:14 +03:00
|
|
|
use egui::{Align, Id, Layout, Margin, RichText, ScrollArea};
|
2024-05-17 21:37:29 +03:00
|
|
|
use egui::scroll_area::ScrollBarVisibility;
|
2023-08-09 20:11:44 +03:00
|
|
|
use grin_chain::SyncStatus;
|
2023-08-16 04:42:05 +03:00
|
|
|
use grin_core::core::amount_to_hr_string;
|
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;
|
2024-05-17 23:12:17 +03:00
|
|
|
use crate::gui::icons::{ARROWS_CLOCKWISE, BRIDGE, CHAT_CIRCLE_TEXT, CHECK, CHECK_FAT, COPY, FOLDER_USER, GEAR_FINE, GRAPH, PACKAGE, PATH, POWER, SCAN, USERS_THREE};
|
2023-04-27 01:28:55 +03:00
|
|
|
use crate::gui::platform::PlatformCallbacks;
|
2024-05-03 19:51:57 +03:00
|
|
|
use crate::gui::views::{CameraContent, Modal, Root, View};
|
2024-05-04 12:20:35 +03:00
|
|
|
use crate::gui::views::types::{ModalPosition, QrScanResult, TextEditOptions};
|
2024-04-24 01:42:56 +03:00
|
|
|
use crate::gui::views::wallets::{WalletTransactions, WalletMessages, WalletTransport, WalletSettings};
|
2024-04-13 20:38:52 +03:00
|
|
|
use crate::gui::views::wallets::types::{GRIN, WalletTab, WalletTabType};
|
2023-08-03 23:49:11 +03:00
|
|
|
use crate::node::Node;
|
2023-08-21 10:53:23 +03:00
|
|
|
use crate::wallet::{Wallet, WalletConfig};
|
2024-04-13 20:38:52 +03:00
|
|
|
use crate::wallet::types::{WalletAccount, WalletData};
|
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-10-18 02:26:22 +03:00
|
|
|
/// List of wallet accounts for [`Modal`].
|
|
|
|
accounts: Vec<WalletAccount>,
|
|
|
|
|
2024-04-22 04:20:37 +03:00
|
|
|
/// Flag to check if account is creating.
|
|
|
|
account_creating: bool,
|
2023-08-21 10:53:23 +03:00
|
|
|
/// Account label [`Modal`] value.
|
2023-10-18 02:26:22 +03:00
|
|
|
account_label_edit: String,
|
2023-08-21 10:53:23 +03:00
|
|
|
/// Flag to check if error occurred during account creation at [`Modal`].
|
2023-10-18 02:26:22 +03:00
|
|
|
account_creation_error: bool,
|
2023-08-21 10:53:23 +03:00
|
|
|
|
2024-05-03 19:51:57 +03:00
|
|
|
/// Camera content for QR scan [`Modal`].
|
|
|
|
camera_content: CameraContent,
|
|
|
|
/// QR code scan result
|
2024-05-04 12:20:35 +03:00
|
|
|
qr_scan_result: Option<QrScanResult>,
|
2024-05-03 19:51:57 +03:00
|
|
|
|
2023-08-03 23:49:11 +03:00
|
|
|
/// Current tab content to show.
|
2024-05-03 19:51:57 +03:00
|
|
|
pub 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-21 10:53:23 +03:00
|
|
|
Self {
|
2023-10-18 02:26:22 +03:00
|
|
|
accounts: vec![],
|
2024-04-22 04:20:37 +03:00
|
|
|
account_creating: false,
|
2023-08-21 10:53:23 +03:00
|
|
|
account_label_edit: "".to_string(),
|
|
|
|
account_creation_error: false,
|
2024-05-03 19:51:57 +03:00
|
|
|
camera_content: CameraContent::default(),
|
|
|
|
qr_scan_result: None,
|
2024-04-24 01:42:56 +03:00
|
|
|
current_tab: Box::new(WalletTransactions::default())
|
2023-08-21 10:53:23 +03:00
|
|
|
}
|
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-10-18 02:26:22 +03:00
|
|
|
/// Identifier for account list [`Modal`].
|
|
|
|
const ACCOUNT_LIST_MODAL: &'static str = "account_list_modal";
|
2023-08-21 10:53:23 +03:00
|
|
|
|
2024-05-03 19:51:57 +03:00
|
|
|
/// Identifier for QR code scan [`Modal`].
|
|
|
|
const QR_CODE_SCAN_MODAL: &'static str = "qr_code_scan_modal";
|
|
|
|
|
2023-07-21 04:17:57 +03:00
|
|
|
impl WalletContent {
|
2024-05-29 12:26:45 +03:00
|
|
|
/// Draw wallet content.
|
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-21 10:53:23 +03:00
|
|
|
// Show modal content for this ui container.
|
|
|
|
self.modal_content_ui(ui, wallet, cb);
|
|
|
|
|
2023-08-16 04:42:05 +03:00
|
|
|
let data = wallet.get_data();
|
|
|
|
let data_empty = data.is_none();
|
|
|
|
|
2024-05-29 12:26:45 +03:00
|
|
|
// Show wallet balance panel not on Settings tab with selected non-repairing
|
|
|
|
// wallet, when there is no error and data is not empty.
|
2024-05-17 23:12:17 +03:00
|
|
|
let show_balance = self.current_tab.get_type() != WalletTabType::Settings && !data_empty
|
2024-05-18 10:20:38 +03:00
|
|
|
&& !wallet.sync_error() && !wallet.is_repairing();
|
2024-05-29 12:26:45 +03:00
|
|
|
egui::TopBottomPanel::top(Id::from("wallet_balance").with(wallet.identifier()))
|
2023-08-16 04:42:05 +03:00
|
|
|
.frame(egui::Frame {
|
2024-05-29 22:47:17 +03:00
|
|
|
fill: Colors::fill(),
|
2024-05-30 12:02:52 +03:00
|
|
|
stroke: View::item_stroke(),
|
2023-08-16 04:42:05 +03:00
|
|
|
inner_margin: Margin {
|
|
|
|
left: View::far_left_inset_margin(ui) + 4.0,
|
|
|
|
right: View::get_right_inset() + 4.0,
|
|
|
|
top: 4.0,
|
2023-08-16 05:15:35 +03:00
|
|
|
bottom: 0.0,
|
|
|
|
},
|
|
|
|
outer_margin: Margin {
|
|
|
|
left: 0.0,
|
|
|
|
right: 0.0,
|
|
|
|
top: 0.0,
|
2024-05-30 12:02:52 +03:00
|
|
|
bottom: if !Root::is_dual_panel_mode(ui) {
|
|
|
|
0.0
|
|
|
|
} else {
|
|
|
|
-1.0
|
|
|
|
},
|
2023-08-16 04:42:05 +03:00
|
|
|
},
|
|
|
|
..Default::default()
|
|
|
|
})
|
|
|
|
.show_animated_inside(ui, show_balance, |ui| {
|
|
|
|
ui.vertical_centered(|ui| {
|
2024-04-22 04:20:37 +03:00
|
|
|
// Draw account info.
|
2024-04-22 23:32:29 +03:00
|
|
|
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
2023-10-18 02:26:22 +03:00
|
|
|
self.account_ui(ui, wallet, data.unwrap(), cb);
|
2023-08-16 04:42:05 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-08-11 04:36:15 +03:00
|
|
|
// Show wallet tabs panel.
|
2023-08-03 23:49:11 +03:00
|
|
|
egui::TopBottomPanel::bottom("wallet_tabs")
|
|
|
|
.frame(egui::Frame {
|
2024-05-29 22:47:17 +03:00
|
|
|
fill: Colors::fill(),
|
2023-08-03 23:49:11 +03:00
|
|
|
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()
|
|
|
|
})
|
2023-08-13 21:09:04 +03:00
|
|
|
.show_animated_inside(ui, !Self::block_navigation_on_sync(wallet), |ui| {
|
2023-08-11 04:36:15 +03:00
|
|
|
ui.vertical_centered(|ui| {
|
|
|
|
// Draw wallet tabs.
|
2023-08-15 21:20:20 +03:00
|
|
|
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
2024-04-20 16:59:54 +03:00
|
|
|
self.tabs_ui(ui, wallet);
|
2023-08-11 04:36:15 +03:00
|
|
|
});
|
|
|
|
});
|
2023-08-03 23:49:11 +03:00
|
|
|
});
|
|
|
|
|
2023-08-11 04:36:15 +03:00
|
|
|
// Show tab content panel.
|
2023-06-02 02:05:34 +03:00
|
|
|
egui::CentralPanel::default()
|
2023-07-13 03:54:27 +03:00
|
|
|
.frame(egui::Frame {
|
2024-05-29 22:47:17 +03:00
|
|
|
fill: Colors::white_or_black(false),
|
2023-06-02 02:05:34 +03:00
|
|
|
..Default::default()
|
|
|
|
})
|
|
|
|
.show_inside(ui, |ui| {
|
2023-08-13 21:09:04 +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-13 21:09:04 +03:00
|
|
|
// Refresh content after 1 second for synced wallet.
|
2023-08-16 04:42:05 +03:00
|
|
|
if !data_empty {
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-21 10:53:23 +03:00
|
|
|
/// Draw [`Modal`] content for this ui container.
|
|
|
|
fn modal_content_ui(&mut self,
|
|
|
|
ui: &mut egui::Ui,
|
|
|
|
wallet: &mut Wallet,
|
|
|
|
cb: &dyn PlatformCallbacks) {
|
|
|
|
match Modal::opened() {
|
|
|
|
None => {}
|
|
|
|
Some(id) => {
|
|
|
|
match id {
|
2023-10-18 02:26:22 +03:00
|
|
|
ACCOUNT_LIST_MODAL => {
|
|
|
|
Modal::ui(ui.ctx(), |ui, modal| {
|
2024-04-22 04:20:37 +03:00
|
|
|
self.account_list_modal_ui(ui, wallet, modal, cb);
|
2023-10-18 02:26:22 +03:00
|
|
|
});
|
2023-08-21 10:53:23 +03:00
|
|
|
}
|
2024-05-03 19:51:57 +03:00
|
|
|
QR_CODE_SCAN_MODAL => {
|
|
|
|
Modal::ui(ui.ctx(), |ui, modal| {
|
|
|
|
self.scan_qr_modal_ui(ui, wallet, modal, cb);
|
|
|
|
});
|
|
|
|
}
|
2023-08-21 10:53:23 +03:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-21 08:30:50 +03:00
|
|
|
/// Draw wallet account content.
|
2023-10-18 02:26:22 +03:00
|
|
|
fn account_ui(&mut self,
|
|
|
|
ui: &mut egui::Ui,
|
|
|
|
wallet: &Wallet,
|
|
|
|
data: WalletData,
|
2023-08-21 10:53:23 +03:00
|
|
|
cb: &dyn PlatformCallbacks) {
|
2023-08-16 04:42:05 +03:00
|
|
|
let mut rect = ui.available_rect_before_wrap();
|
2023-08-16 05:15:35 +03:00
|
|
|
rect.set_height(75.0);
|
2023-08-16 04:42:05 +03:00
|
|
|
// Draw round background.
|
2023-08-16 05:15:35 +03:00
|
|
|
let rounding = View::item_rounding(0, 2, false);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.painter().rect(rect, rounding, Colors::button(), View::hover_stroke());
|
2023-08-16 04:42:05 +03:00
|
|
|
|
|
|
|
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
2024-04-22 04:20:37 +03:00
|
|
|
// Draw button to scan QR code.
|
2024-04-30 18:15:03 +03:00
|
|
|
View::item_button(ui, View::item_rounding(0, 2, true), SCAN, None, || {
|
2024-05-03 19:51:57 +03:00
|
|
|
self.qr_scan_result = None;
|
2024-05-18 14:29:33 +03:00
|
|
|
self.camera_content.clear_state();
|
2024-05-05 17:09:33 +03:00
|
|
|
// Show QR code scan modal.
|
2024-05-03 19:51:57 +03:00
|
|
|
Modal::new(QR_CODE_SCAN_MODAL)
|
|
|
|
.position(ModalPosition::CenterTop)
|
|
|
|
.title(t!("scan_qr"))
|
|
|
|
.closeable(false)
|
|
|
|
.show();
|
|
|
|
cb.start_camera();
|
2023-08-16 04:42:05 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
// Draw button to show list of accounts.
|
2024-04-22 04:20:37 +03:00
|
|
|
View::item_button(ui, View::item_rounding(1, 3, true), USERS_THREE, None, || {
|
2023-10-18 02:26:22 +03:00
|
|
|
// Load accounts.
|
2024-04-22 04:20:37 +03:00
|
|
|
self.account_label_edit = "".to_string();
|
2023-10-18 02:26:22 +03:00
|
|
|
self.accounts = wallet.accounts();
|
2024-04-22 04:20:37 +03:00
|
|
|
self.account_creating = false;
|
2023-10-18 02:26:22 +03:00
|
|
|
// Show account list modal.
|
|
|
|
Modal::new(ACCOUNT_LIST_MODAL)
|
2024-04-22 04:20:37 +03:00
|
|
|
.position(ModalPosition::CenterTop)
|
2023-10-18 02:26:22 +03:00
|
|
|
.title(t!("wallets.accounts"))
|
|
|
|
.show();
|
2023-08-16 04:42:05 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
let layout_size = ui.available_size();
|
|
|
|
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
2024-04-22 04:20:37 +03:00
|
|
|
ui.add_space(8.0);
|
2023-08-16 04:42:05 +03:00
|
|
|
ui.vertical(|ui| {
|
|
|
|
ui.add_space(3.0);
|
|
|
|
// Show spendable amount.
|
2024-04-17 01:30:28 +03:00
|
|
|
let amount = amount_to_hr_string(data.info.amount_currently_spendable, true);
|
2023-10-18 02:26:22 +03:00
|
|
|
let amount_text = format!("{} {}", amount, GRIN);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(amount_text)
|
|
|
|
.size(18.0)
|
|
|
|
.color(Colors::white_or_black(true)));
|
2023-10-18 02:26:22 +03:00
|
|
|
ui.add_space(-2.0);
|
2023-08-16 04:42:05 +03:00
|
|
|
|
2023-08-21 10:53:23 +03:00
|
|
|
// Show account label.
|
2023-10-18 02:26:22 +03:00
|
|
|
let account = wallet.get_config().account;
|
|
|
|
let default_acc_label = WalletConfig::DEFAULT_ACCOUNT_LABEL.to_string();
|
2023-08-21 10:53:23 +03:00
|
|
|
let acc_label = if account == default_acc_label {
|
|
|
|
t!("wallets.default_account")
|
|
|
|
} else {
|
|
|
|
account.to_owned()
|
2023-08-16 04:42:05 +03:00
|
|
|
};
|
2024-04-22 04:20:37 +03:00
|
|
|
let acc_text = format!("{} {}", FOLDER_USER, acc_label);
|
2024-05-29 22:47:17 +03:00
|
|
|
View::ellipsize_text(ui, acc_text, 15.0, Colors::text(false));
|
2023-08-16 04:42:05 +03:00
|
|
|
|
|
|
|
// Show confirmed height.
|
|
|
|
let height_text = format!("{} {}", PACKAGE, data.info.last_confirmed_height);
|
2024-05-29 22:47:17 +03:00
|
|
|
View::animate_text(ui, height_text, 15.0, Colors::gray(), wallet.syncing());
|
2023-08-16 04:42:05 +03:00
|
|
|
})
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-10-18 02:26:22 +03:00
|
|
|
/// Draw account list [`Modal`] content.
|
2024-04-22 04:20:37 +03:00
|
|
|
fn account_list_modal_ui(&mut self,
|
|
|
|
ui: &mut egui::Ui,
|
|
|
|
wallet: &mut Wallet,
|
|
|
|
modal: &Modal,
|
|
|
|
cb: &dyn PlatformCallbacks) {
|
|
|
|
if self.account_creating {
|
2023-10-18 02:26:22 +03:00
|
|
|
ui.add_space(6.0);
|
2024-04-22 04:20:37 +03:00
|
|
|
ui.vertical_centered(|ui| {
|
|
|
|
ui.label(RichText::new(t!("wallets.new_account_desc"))
|
2023-10-18 02:26:22 +03:00
|
|
|
.size(17.0)
|
2024-05-29 22:47:17 +03:00
|
|
|
.color(Colors::gray()));
|
2024-04-22 04:20:37 +03:00
|
|
|
ui.add_space(8.0);
|
|
|
|
|
|
|
|
// Draw account name edit.
|
|
|
|
let text_edit_id = Id::from(modal.id).with(wallet.get_config().id);
|
2024-05-21 13:31:46 +03:00
|
|
|
let mut text_edit_opts = TextEditOptions::new(text_edit_id);
|
|
|
|
View::text_edit(ui, cb, &mut self.account_label_edit, &mut text_edit_opts);
|
2024-04-22 04:20:37 +03:00
|
|
|
|
|
|
|
// Show error occurred during account creation..
|
|
|
|
if self.account_creation_error {
|
|
|
|
ui.add_space(12.0);
|
|
|
|
ui.label(RichText::new(t!("error"))
|
|
|
|
.size(17.0)
|
2024-05-29 22:47:17 +03:00
|
|
|
.color(Colors::red()));
|
2024-04-22 04:20:37 +03:00
|
|
|
}
|
|
|
|
ui.add_space(12.0);
|
|
|
|
});
|
2023-08-21 10:53:23 +03:00
|
|
|
|
|
|
|
// Setup spacing between buttons.
|
2024-04-22 04:20:37 +03:00
|
|
|
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
2023-08-21 10:53:23 +03:00
|
|
|
|
2024-04-22 04:20:37 +03:00
|
|
|
// Show modal buttons.
|
2023-08-21 10:53:23 +03:00
|
|
|
ui.columns(2, |columns| {
|
|
|
|
columns[0].vertical_centered_justified(|ui| {
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
2023-08-21 10:53:23 +03:00
|
|
|
// Close modal.
|
|
|
|
cb.hide_keyboard();
|
|
|
|
modal.close();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[1].vertical_centered_justified(|ui| {
|
|
|
|
// Create button callback.
|
|
|
|
let mut on_create = || {
|
|
|
|
if !self.account_label_edit.is_empty() {
|
|
|
|
let label = &self.account_label_edit;
|
|
|
|
match wallet.create_account(label) {
|
2023-10-18 02:26:22 +03:00
|
|
|
Ok(_) => {
|
|
|
|
let _ = wallet.set_active_account(label);
|
|
|
|
cb.hide_keyboard();
|
|
|
|
modal.close();
|
2023-08-21 10:53:23 +03:00
|
|
|
},
|
|
|
|
Err(_) => self.account_creation_error = true
|
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
View::on_enter_key(ui, || {
|
|
|
|
(on_create)();
|
|
|
|
});
|
|
|
|
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("create"), Colors::white_or_black(false), on_create);
|
2023-08-21 10:53:23 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
ui.add_space(6.0);
|
2024-04-22 04:20:37 +03:00
|
|
|
} else {
|
|
|
|
ui.add_space(3.0);
|
|
|
|
|
|
|
|
// Show list of accounts.
|
|
|
|
let size = self.accounts.len();
|
|
|
|
ScrollArea::vertical()
|
|
|
|
.id_source("account_list_modal_scroll")
|
2024-05-17 21:37:29 +03:00
|
|
|
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
|
|
|
.max_height(266.0)
|
2024-04-22 04:20:37 +03:00
|
|
|
.auto_shrink([true; 2])
|
|
|
|
.show_rows(ui, ACCOUNT_ITEM_HEIGHT, size, |ui, row_range| {
|
|
|
|
for index in row_range {
|
|
|
|
// Add space before the first item.
|
|
|
|
if index == 0 {
|
|
|
|
ui.add_space(4.0);
|
|
|
|
}
|
|
|
|
let acc = self.accounts.get(index).unwrap();
|
|
|
|
account_item_ui(ui, modal, wallet, acc, index, size);
|
|
|
|
if index == size - 1 {
|
|
|
|
ui.add_space(4.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
ui.add_space(2.0);
|
2024-05-29 22:47:17 +03:00
|
|
|
View::horizontal_line(ui, Colors::stroke());
|
2024-04-22 04:20:37 +03:00
|
|
|
ui.add_space(6.0);
|
|
|
|
|
|
|
|
// Setup spacing between buttons.
|
|
|
|
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
|
|
|
|
|
|
|
// Show modal buttons.
|
|
|
|
ui.columns(2, |columns| {
|
|
|
|
columns[0].vertical_centered_justified(|ui| {
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
2024-04-22 04:20:37 +03:00
|
|
|
modal.close();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[1].vertical_centered_justified(|ui| {
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("create"), Colors::white_or_black(false), || {
|
2024-04-22 04:20:37 +03:00
|
|
|
self.account_creating = true;
|
|
|
|
cb.show_keyboard();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
ui.add_space(6.0);
|
|
|
|
}
|
2023-08-21 10:53:23 +03:00
|
|
|
}
|
|
|
|
|
2024-05-05 17:09:33 +03:00
|
|
|
/// Draw QR code scan [`Modal`] content.
|
2024-05-03 19:51:57 +03:00
|
|
|
fn scan_qr_modal_ui(&mut self,
|
|
|
|
ui: &mut egui::Ui,
|
|
|
|
wallet: &mut Wallet,
|
|
|
|
modal: &Modal,
|
|
|
|
cb: &dyn PlatformCallbacks) {
|
2024-05-04 13:37:37 +03:00
|
|
|
// Show scan result if exists or show camera content while scanning.
|
2024-05-03 19:51:57 +03:00
|
|
|
if let Some(result) = &self.qr_scan_result {
|
2024-05-27 00:20:16 +03:00
|
|
|
let mut result_text = result.text();
|
2024-05-29 22:47:17 +03:00
|
|
|
View::horizontal_line(ui, Colors::item_stroke());
|
2024-05-04 13:37:37 +03:00
|
|
|
ui.add_space(3.0);
|
|
|
|
ScrollArea::vertical()
|
|
|
|
.id_source(Id::from("qr_scan_result_input").with(wallet.get_config().id))
|
2024-05-17 21:37:29 +03:00
|
|
|
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
|
|
|
.max_height(128.0)
|
2024-05-04 13:37:37 +03:00
|
|
|
.auto_shrink([false; 2])
|
|
|
|
.show(ui, |ui| {
|
|
|
|
ui.add_space(7.0);
|
|
|
|
egui::TextEdit::multiline(&mut result_text)
|
|
|
|
.font(egui::TextStyle::Small)
|
|
|
|
.desired_rows(5)
|
|
|
|
.interactive(false)
|
|
|
|
.desired_width(f32::INFINITY)
|
|
|
|
.show(ui);
|
|
|
|
ui.add_space(6.0);
|
|
|
|
});
|
|
|
|
ui.add_space(2.0);
|
2024-05-29 22:47:17 +03:00
|
|
|
View::horizontal_line(ui, Colors::item_stroke());
|
2024-05-04 14:47:42 +03:00
|
|
|
ui.add_space(6.0);
|
2024-05-04 13:37:37 +03:00
|
|
|
|
|
|
|
// Show copy button.
|
2024-05-03 19:51:57 +03:00
|
|
|
ui.vertical_centered(|ui| {
|
2024-05-04 13:37:37 +03:00
|
|
|
let copy_text = format!("{} {}", COPY, t!("copy"));
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, copy_text, Colors::button(), || {
|
2024-05-05 17:09:33 +03:00
|
|
|
cb.copy_string_to_buffer(result_text.to_string());
|
2024-05-04 13:37:37 +03:00
|
|
|
self.qr_scan_result = None;
|
|
|
|
modal.close();
|
|
|
|
});
|
2024-05-03 19:51:57 +03:00
|
|
|
});
|
2024-05-04 13:37:37 +03:00
|
|
|
ui.add_space(6.0);
|
2024-05-29 22:47:17 +03:00
|
|
|
View::horizontal_line(ui, Colors::item_stroke());
|
2024-05-27 16:53:18 +03:00
|
|
|
ui.add_space(6.0);
|
2024-05-03 19:51:57 +03:00
|
|
|
} else if let Some(result) = self.camera_content.qr_scan_result() {
|
|
|
|
cb.stop_camera();
|
|
|
|
self.camera_content.clear_state();
|
2024-05-04 12:20:35 +03:00
|
|
|
match &result {
|
|
|
|
QrScanResult::Slatepack(message) => {
|
2024-05-04 13:37:37 +03:00
|
|
|
// Redirect to messages to handle parsed message.
|
2024-05-04 12:20:35 +03:00
|
|
|
let mut messages =
|
2024-05-05 17:09:33 +03:00
|
|
|
WalletMessages::new(wallet.can_use_dandelion(), Some(message.to_string()));
|
2024-05-04 12:20:35 +03:00
|
|
|
messages.parse_message(wallet);
|
|
|
|
modal.close();
|
2024-05-04 13:37:37 +03:00
|
|
|
self.current_tab = Box::new(messages);
|
|
|
|
return;
|
2024-05-04 12:20:35 +03:00
|
|
|
}
|
|
|
|
QrScanResult::Address(receiver) => {
|
|
|
|
if wallet.get_data().unwrap().info.amount_currently_spendable > 0 {
|
2024-05-04 13:37:37 +03:00
|
|
|
// Redirect to send amount with Tor.
|
2024-05-04 12:20:35 +03:00
|
|
|
let addr = wallet.slatepack_address().unwrap();
|
|
|
|
let mut transport = WalletTransport::new(addr.clone());
|
2024-05-04 13:37:37 +03:00
|
|
|
modal.close();
|
2024-05-16 22:50:42 +03:00
|
|
|
transport.show_send_tor_modal(cb, Some(receiver.to_string()));
|
2024-05-04 12:20:35 +03:00
|
|
|
self.current_tab = Box::new(transport);
|
2024-05-04 13:37:37 +03:00
|
|
|
return;
|
2024-05-04 12:20:35 +03:00
|
|
|
}
|
|
|
|
}
|
2024-05-25 11:59:39 +03:00
|
|
|
_ => {}
|
2024-05-04 12:20:35 +03:00
|
|
|
}
|
2024-05-04 13:37:37 +03:00
|
|
|
|
|
|
|
// Set result and rename modal title.
|
|
|
|
self.qr_scan_result = Some(result);
|
|
|
|
Modal::set_title(t!("scan_result"));
|
2024-05-03 19:51:57 +03:00
|
|
|
} else {
|
2024-05-04 14:47:42 +03:00
|
|
|
ui.add_space(6.0);
|
2024-05-03 19:51:57 +03:00
|
|
|
self.camera_content.ui(ui, cb);
|
2024-05-04 13:37:37 +03:00
|
|
|
ui.add_space(6.0);
|
2024-05-03 19:51:57 +03:00
|
|
|
}
|
2024-05-04 13:37:37 +03:00
|
|
|
|
|
|
|
if self.qr_scan_result.is_some() {
|
|
|
|
// Setup spacing between buttons.
|
|
|
|
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
|
|
|
|
|
|
|
ui.columns(2, |columns| {
|
|
|
|
columns[0].vertical_centered_justified(|ui| {
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("close"), Colors::white_or_black(false), || {
|
2024-05-04 13:37:37 +03:00
|
|
|
self.qr_scan_result = None;
|
|
|
|
modal.close();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[1].vertical_centered_justified(|ui| {
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("repeat"), Colors::white_or_black(false), || {
|
2024-05-04 13:37:37 +03:00
|
|
|
Modal::set_title(t!("scan_qr"));
|
|
|
|
self.qr_scan_result = None;
|
2024-05-04 14:47:42 +03:00
|
|
|
cb.start_camera();
|
2024-05-04 13:37:37 +03:00
|
|
|
});
|
|
|
|
});
|
2024-05-03 19:51:57 +03:00
|
|
|
});
|
2024-05-04 13:37:37 +03:00
|
|
|
} else {
|
|
|
|
ui.vertical_centered_justified(|ui| {
|
2024-05-29 22:47:17 +03:00
|
|
|
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
2024-05-04 13:37:37 +03:00
|
|
|
cb.stop_camera();
|
|
|
|
modal.close();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2024-05-03 19:51:57 +03:00
|
|
|
ui.add_space(6.0);
|
|
|
|
}
|
|
|
|
|
2023-08-03 23:49:11 +03:00
|
|
|
/// Draw tab buttons in the bottom of the screen.
|
2024-04-20 16:59:54 +03:00
|
|
|
fn tabs_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet) {
|
2023-08-03 23:49:11 +03:00
|
|
|
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.
|
2023-10-18 02:26:22 +03:00
|
|
|
ui.style_mut().spacing.button_padding = egui::vec2(0.0, 4.0);
|
2023-08-03 23:49:11 +03:00
|
|
|
|
|
|
|
// Draw tab buttons.
|
|
|
|
let current_type = self.current_tab.get_type();
|
|
|
|
ui.columns(4, |columns| {
|
|
|
|
columns[0].vertical_centered_justified(|ui| {
|
2024-04-22 14:34:19 +03:00
|
|
|
View::tab_button(ui, GRAPH, current_type == WalletTabType::Txs, || {
|
2024-04-24 01:42:56 +03:00
|
|
|
self.current_tab = Box::new(WalletTransactions::default());
|
2023-08-03 23:49:11 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[1].vertical_centered_justified(|ui| {
|
2024-04-20 16:59:54 +03:00
|
|
|
let is_messages = current_type == WalletTabType::Messages;
|
2024-04-22 14:34:19 +03:00
|
|
|
View::tab_button(ui, CHAT_CIRCLE_TEXT, is_messages, || {
|
2024-04-21 19:59:12 +03:00
|
|
|
self.current_tab = Box::new(
|
2024-05-04 12:20:35 +03:00
|
|
|
WalletMessages::new(wallet.can_use_dandelion(), None)
|
2024-04-21 19:59:12 +03:00
|
|
|
);
|
2023-08-03 23:49:11 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
columns[2].vertical_centered_justified(|ui| {
|
2024-04-18 05:20:49 +03:00
|
|
|
View::tab_button(ui, BRIDGE, current_type == WalletTabType::Transport, || {
|
2024-05-04 12:20:35 +03:00
|
|
|
let addr = wallet.slatepack_address().unwrap();
|
|
|
|
self.current_tab = Box::new(WalletTransport::new(addr));
|
2023-08-03 23:49:11 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
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-13 21:09:04 +03:00
|
|
|
/// Draw content when wallet is syncing and not ready to use, returns `true` at this case.
|
2024-04-16 15:24:22 +03:00
|
|
|
pub fn sync_ui(ui: &mut egui::Ui, wallet: &Wallet) -> bool {
|
2023-08-13 21:09:04 +03:00
|
|
|
if wallet.is_repairing() && !wallet.sync_error() {
|
|
|
|
Self::sync_progress_ui(ui, wallet);
|
|
|
|
return true;
|
|
|
|
} else if wallet.is_closing() {
|
|
|
|
Self::sync_progress_ui(ui, wallet);
|
2023-08-11 01:20:41 +03:00
|
|
|
return true;
|
2024-05-24 13:35:59 +03:00
|
|
|
} else if wallet.get_current_ext_conn().is_none() {
|
2023-08-09 20:11:44 +03:00
|
|
|
if !Node::is_running() || Node::is_stopping() {
|
2023-08-11 01:20:41 +03:00
|
|
|
View::center_content(ui, 108.0, |ui| {
|
2024-04-19 04:33:41 +03:00
|
|
|
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.5, |ui| {
|
|
|
|
let text = t!("wallets.enable_node", "settings" => GEAR_FINE);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(text).size(16.0).color(Colors::inactive_text()));
|
2024-04-19 04:33:41 +03:00
|
|
|
ui.add_space(8.0);
|
|
|
|
// Show button to enable integrated node at non-dual root panel mode
|
|
|
|
// or when network connections are not showing and node is not stopping
|
|
|
|
let dual_panel_root = Root::is_dual_panel_mode(ui);
|
|
|
|
if (!dual_panel_root || AppConfig::show_connections_network_panel())
|
|
|
|
&& !Node::is_stopping() {
|
|
|
|
let enable_text = format!("{} {}", POWER, t!("network.enable_node"));
|
2024-05-29 22:47:17 +03:00
|
|
|
View::action_button(ui, enable_text, || {
|
2024-04-19 04:33:41 +03:00
|
|
|
Node::start();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-08-09 20:11:44 +03:00
|
|
|
});
|
|
|
|
return true
|
2023-08-13 21:09:04 +03:00
|
|
|
} else if wallet.sync_error()
|
2023-08-11 01:20:41 +03:00
|
|
|
&& Node::get_sync_status() == Some(SyncStatus::NoSync) {
|
2023-08-13 21:09:04 +03:00
|
|
|
Self::sync_error_ui(ui, wallet);
|
2023-08-11 01:20:41 +03:00
|
|
|
return true;
|
|
|
|
} else if wallet.get_data().is_none() {
|
2023-08-13 21:09:04 +03:00
|
|
|
Self::sync_progress_ui(ui, wallet);
|
2023-08-09 02:22:16 +03:00
|
|
|
return true;
|
2023-08-09 20:11:44 +03:00
|
|
|
}
|
2023-08-13 21:09:04 +03:00
|
|
|
} else if wallet.sync_error() {
|
|
|
|
Self::sync_error_ui(ui, wallet);
|
|
|
|
return true;
|
2023-08-11 01:20:41 +03:00
|
|
|
} else if wallet.get_data().is_none() {
|
2023-08-13 21:09:04 +03:00
|
|
|
Self::sync_progress_ui(ui, wallet);
|
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-13 21:09:04 +03:00
|
|
|
/// Draw wallet sync error content.
|
|
|
|
fn sync_error_ui(ui: &mut egui::Ui, wallet: &Wallet) {
|
2023-08-11 01:20:41 +03:00
|
|
|
View::center_content(ui, 108.0, |ui| {
|
|
|
|
let text = t!("wallets.wallet_loading_err", "settings" => GEAR_FINE);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(text).size(16.0).color(Colors::inactive_text()));
|
2023-08-11 01:20:41 +03:00
|
|
|
ui.add_space(8.0);
|
2024-05-17 23:12:17 +03:00
|
|
|
let retry_text = format!("{} {}", ARROWS_CLOCKWISE, t!("retry"));
|
2024-05-29 22:47:17 +03:00
|
|
|
View::action_button(ui, retry_text, || {
|
2023-11-09 00:28:28 +03:00
|
|
|
wallet.set_sync_error(false);
|
2023-08-11 01:20:41 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-08-13 21:09:04 +03:00
|
|
|
/// Check when to block tabs navigation on sync progress.
|
|
|
|
pub fn block_navigation_on_sync(wallet: &Wallet) -> bool {
|
|
|
|
let sync_error = wallet.sync_error();
|
2024-05-24 13:35:59 +03:00
|
|
|
let integrated_node = wallet.get_current_ext_conn().is_none();
|
2023-08-13 21:09:04 +03:00
|
|
|
let integrated_node_ready = Node::get_sync_status() == Some(SyncStatus::NoSync);
|
|
|
|
let sync_after_opening = wallet.get_data().is_none() && !wallet.sync_error();
|
2023-08-14 03:17:54 +03:00
|
|
|
// Block navigation if wallet is repairing and integrated node is not launching
|
|
|
|
// and if wallet is closing or syncing after opening when there is no data to show.
|
2023-08-13 21:09:04 +03:00
|
|
|
(wallet.is_repairing() && (integrated_node_ready || !integrated_node) && !sync_error)
|
|
|
|
|| wallet.is_closing() || (sync_after_opening && !integrated_node)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Draw wallet sync progress content.
|
|
|
|
pub fn sync_progress_ui(ui: &mut egui::Ui, wallet: &Wallet) {
|
2023-08-09 20:11:44 +03:00
|
|
|
View::center_content(ui, 162.0, |ui| {
|
2024-04-19 04:33:41 +03:00
|
|
|
View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.5, |ui| {
|
|
|
|
View::big_loading_spinner(ui);
|
|
|
|
ui.add_space(18.0);
|
|
|
|
// Setup sync progress text.
|
|
|
|
let text = {
|
2024-05-24 13:35:59 +03:00
|
|
|
let integrated_node = wallet.get_current_ext_conn().is_none();
|
2024-04-19 04:33:41 +03:00
|
|
|
let integrated_node_ready = Node::get_sync_status() == Some(SyncStatus::NoSync);
|
|
|
|
let info_progress = wallet.info_sync_progress();
|
|
|
|
|
|
|
|
if wallet.is_closing() {
|
|
|
|
t!("wallets.wallet_closing")
|
|
|
|
} else if integrated_node && !integrated_node_ready {
|
|
|
|
t!("wallets.node_loading", "settings" => GEAR_FINE)
|
|
|
|
} else if wallet.is_repairing() {
|
|
|
|
let repair_progress = wallet.repairing_progress();
|
|
|
|
if repair_progress == 0 {
|
|
|
|
t!("wallets.wallet_checking")
|
|
|
|
} else {
|
|
|
|
format!("{}: {}%", t!("wallets.wallet_checking"), repair_progress)
|
|
|
|
}
|
|
|
|
} else if info_progress != 100 {
|
|
|
|
if info_progress == 0 {
|
|
|
|
t!("wallets.wallet_loading")
|
|
|
|
} else {
|
|
|
|
format!("{}: {}%", t!("wallets.wallet_loading"), info_progress)
|
|
|
|
}
|
2023-08-11 01:20:41 +03:00
|
|
|
} else {
|
2024-04-19 04:33:41 +03:00
|
|
|
let tx_progress = wallet.txs_sync_progress();
|
|
|
|
if tx_progress == 0 {
|
|
|
|
t!("wallets.tx_loading")
|
|
|
|
} else {
|
|
|
|
format!("{}: {}%", t!("wallets.tx_loading"), tx_progress)
|
|
|
|
}
|
2023-08-11 01:20:41 +03:00
|
|
|
}
|
2024-04-19 04:33:41 +03:00
|
|
|
};
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(text).size(16.0).color(Colors::inactive_text()));
|
2024-04-19 04:33:41 +03:00
|
|
|
});
|
2023-08-09 20:11:44 +03:00
|
|
|
});
|
|
|
|
}
|
2023-10-18 02:26:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const ACCOUNT_ITEM_HEIGHT: f32 = 75.0;
|
|
|
|
|
|
|
|
/// Draw account item.
|
|
|
|
fn account_item_ui(ui: &mut egui::Ui,
|
|
|
|
modal: &Modal,
|
|
|
|
wallet: &mut Wallet,
|
|
|
|
acc: &WalletAccount,
|
|
|
|
index: usize,
|
|
|
|
size: usize) {
|
|
|
|
// Setup layout size.
|
|
|
|
let mut rect = ui.available_rect_before_wrap();
|
|
|
|
rect.set_height(ACCOUNT_ITEM_HEIGHT);
|
|
|
|
|
|
|
|
// Draw round background.
|
|
|
|
let bg_rect = rect.clone();
|
|
|
|
let item_rounding = View::item_rounding(index, size, false);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.painter().rect(bg_rect, item_rounding, Colors::fill(), View::item_stroke());
|
2023-10-18 02:26:22 +03:00
|
|
|
|
|
|
|
ui.vertical(|ui| {
|
|
|
|
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
|
|
|
// Draw button to select account.
|
|
|
|
let is_current_account = wallet.get_config().account == acc.label;
|
|
|
|
if !is_current_account {
|
|
|
|
let button_rounding = View::item_rounding(index, size, true);
|
|
|
|
View::item_button(ui, button_rounding, CHECK, None, || {
|
|
|
|
let _ = wallet.set_active_account(&acc.label);
|
|
|
|
modal.close();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
ui.add_space(12.0);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(CHECK_FAT).size(20.0).color(Colors::green()));
|
2023-10-18 02:26:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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(4.0);
|
|
|
|
// Show spendable amount.
|
2024-04-22 14:34:19 +03:00
|
|
|
let amount = amount_to_hr_string(acc.spendable_amount, true);
|
2023-10-18 02:26:22 +03:00
|
|
|
let amount_text = format!("{} {}", amount, GRIN);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(amount_text).size(18.0).color(Colors::white_or_black(true)));
|
2023-10-18 02:26:22 +03:00
|
|
|
ui.add_space(-2.0);
|
|
|
|
|
|
|
|
// Show account name.
|
|
|
|
let default_acc_label = WalletConfig::DEFAULT_ACCOUNT_LABEL.to_string();
|
|
|
|
let acc_label = if acc.label == default_acc_label {
|
|
|
|
t!("wallets.default_account")
|
|
|
|
} else {
|
|
|
|
acc.label.to_owned()
|
|
|
|
};
|
2024-04-22 04:20:37 +03:00
|
|
|
let acc_name = format!("{} {}", FOLDER_USER, acc_label);
|
2024-05-29 22:47:17 +03:00
|
|
|
View::ellipsize_text(ui, acc_name, 15.0, Colors::text(false));
|
2023-10-18 02:26:22 +03:00
|
|
|
|
|
|
|
// Show account BIP32 derivation path.
|
2024-04-22 14:34:19 +03:00
|
|
|
let acc_path = format!("{} {}", PATH, acc.path);
|
2024-05-29 22:47:17 +03:00
|
|
|
ui.label(RichText::new(acc_path).size(15.0).color(Colors::gray()));
|
2023-10-18 02:26:22 +03:00
|
|
|
ui.add_space(3.0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2023-04-27 01:28:55 +03:00
|
|
|
}
|