fix: hide account list panel on wallet change, do not store account list at content
This commit is contained in:
@@ -160,9 +160,9 @@ impl ContentContainer for WalletsContent {
|
||||
}
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
let is_android = OperatingSystem::from_target_os() == OperatingSystem::Android;
|
||||
let account_list_showing = self.wallet_content.account_content.list_content.is_some();
|
||||
// Small repaint delay is needed for Android back navigation and account list opening.
|
||||
let is_android = OperatingSystem::from_target_os() == OperatingSystem::Android;
|
||||
let account_list_showing = self.wallet_content.account_content.show_list;
|
||||
ui.ctx().request_repaint_after(Duration::from_millis(if account_list_showing {
|
||||
10
|
||||
} else if is_android {
|
||||
@@ -753,7 +753,7 @@ impl WalletsContent {
|
||||
|
||||
/// Select wallet to make some actions on it.
|
||||
fn select_wallet(&mut self, w: &Wallet, data: Option<String>, cb: &dyn PlatformCallbacks) {
|
||||
self.wallet_content.account_content.close_qr_scan(cb);
|
||||
self.wallet_content.back(cb);
|
||||
if let Some(data) = data {
|
||||
w.task(WalletTask::OpenMessage(data));
|
||||
}
|
||||
|
||||
@@ -7,29 +7,29 @@
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distr1ibuted on an "AS IS" BASIS,
|
||||
// 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 egui::{Align, Layout, RichText, StrokeKind};
|
||||
use egui::{Align, Layout, RichText, ScrollArea, StrokeKind};
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use grin_core::core::amount_to_hr_string;
|
||||
|
||||
use crate::gui::icons::{FOLDER_USER, PACKAGE, SCAN, SPINNER, USERS_THREE, USER_PLUS};
|
||||
use crate::gui::icons::{CHECK, FOLDER_USER, PACKAGE, PATH, SCAN, SPINNER, USERS_THREE, USER_PLUS};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::types::{ModalPosition, QrScanResult};
|
||||
use crate::gui::views::wallets::wallet::account::create::CreateAccountContent;
|
||||
use crate::gui::views::wallets::wallet::account::list::WalletAccountsContent;
|
||||
use crate::gui::views::wallets::wallet::types::{WalletContentContainer, GRIN};
|
||||
use crate::gui::views::{CameraContent, CameraScanContent, Content, Modal, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::wallet::{Wallet, WalletConfig};
|
||||
use crate::wallet::types::WalletTask;
|
||||
use crate::wallet::types::{WalletAccount, WalletTask};
|
||||
|
||||
/// Wallet account panel content.
|
||||
pub struct AccountContent {
|
||||
/// Account list content.
|
||||
pub list_content: Option<WalletAccountsContent>,
|
||||
pub struct WalletAccountContent {
|
||||
/// Flag to show account list content.
|
||||
pub show_list: bool,
|
||||
/// Account creation [`Modal`] content.
|
||||
create_account_content: CreateAccountContent,
|
||||
|
||||
@@ -42,7 +42,7 @@ pub struct AccountContent {
|
||||
/// Account creation [`Modal`] identifier.
|
||||
const CREATE_MODAL_ID: &'static str = "create_account_modal";
|
||||
|
||||
impl WalletContentContainer for AccountContent {
|
||||
impl WalletContentContainer for WalletAccountContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
CREATE_MODAL_ID
|
||||
@@ -65,7 +65,7 @@ impl WalletContentContainer for AccountContent {
|
||||
self.qr_scan_ui(ui, wallet, cb);
|
||||
} else {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
if self.list_content.is_some() {
|
||||
if self.show_list {
|
||||
self.list_ui(ui, wallet);
|
||||
} else {
|
||||
// Show account content.
|
||||
@@ -76,10 +76,10 @@ impl WalletContentContainer for AccountContent {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AccountContent {
|
||||
impl Default for WalletAccountContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
list_content: None,
|
||||
show_list: false,
|
||||
create_account_content: CreateAccountContent::default(),
|
||||
qr_scan_content: None,
|
||||
qr_scan_result: None,
|
||||
@@ -87,7 +87,9 @@ impl Default for AccountContent {
|
||||
}
|
||||
}
|
||||
|
||||
impl AccountContent {
|
||||
const ACCOUNT_ITEM_HEIGHT: f32 = 75.0;
|
||||
|
||||
impl WalletAccountContent {
|
||||
/// Check if QR code scanner was opened.
|
||||
pub fn qr_scan_showing(&self) -> bool {
|
||||
self.qr_scan_content.is_some() || self.qr_scan_result.is_some()
|
||||
@@ -105,15 +107,15 @@ impl AccountContent {
|
||||
|
||||
/// Check if it's possible to go back at navigation stack.
|
||||
pub fn can_back(&self) -> bool {
|
||||
self.qr_scan_showing() || self.list_content.is_some()
|
||||
self.qr_scan_showing() || self.show_list
|
||||
}
|
||||
|
||||
/// Navigate back on navigation stack.
|
||||
pub fn back(&mut self, cb: &dyn PlatformCallbacks) {
|
||||
if self.qr_scan_showing() {
|
||||
self.close_qr_scan(cb);
|
||||
} else if self.list_content.is_some() {
|
||||
self.list_content = None;
|
||||
} else if self.show_list {
|
||||
self.show_list = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,9 +172,7 @@ impl AccountContent {
|
||||
.title(t!("wallets.accounts"))
|
||||
.show();
|
||||
} else {
|
||||
self.list_content = Some(
|
||||
WalletAccountsContent::new(accounts, wallet.get_config().account)
|
||||
);
|
||||
self.show_list = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -240,19 +240,26 @@ impl AccountContent {
|
||||
|
||||
/// Draw account list content.
|
||||
fn list_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet) {
|
||||
if let Some(accounts) = self.list_content.as_mut() {
|
||||
let mut selected = false;
|
||||
accounts.ui(ui, |acc| {
|
||||
let _ = wallet.set_active_account(&acc.label);
|
||||
selected = true;
|
||||
let accounts = wallet.accounts();
|
||||
let size = accounts.len();
|
||||
ScrollArea::vertical()
|
||||
.id_salt("account_list_scroll")
|
||||
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
||||
.max_height(411.0)
|
||||
.auto_shrink([true; 2])
|
||||
.show_rows(ui, ACCOUNT_ITEM_HEIGHT, size, |ui, row_range| {
|
||||
for index in row_range {
|
||||
let acc = accounts.get(index).unwrap().clone();
|
||||
let current = wallet.get_config().account == acc.label;
|
||||
account_item_ui(ui, &acc, current, index, size, || {
|
||||
let _ = wallet.set_active_account(&acc.label);
|
||||
self.show_list = false;
|
||||
});
|
||||
if index == size - 1 {
|
||||
ui.add_space(4.0);
|
||||
}
|
||||
}
|
||||
});
|
||||
if selected {
|
||||
self.list_content = None;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
ui.add_space(2.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -265,12 +272,12 @@ impl AccountContent {
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || {
|
||||
self.list_content = None;
|
||||
self.show_list = false;
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.add"), Colors::white_or_black(false), || {
|
||||
self.list_content = None;
|
||||
self.show_list = false;
|
||||
self.create_account_content = CreateAccountContent::default();
|
||||
Modal::new(CREATE_MODAL_ID)
|
||||
.position(ModalPosition::CenterTop)
|
||||
@@ -321,4 +328,72 @@ impl AccountContent {
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw account item.
|
||||
fn account_item_ui(ui: &mut egui::Ui,
|
||||
acc: &WalletAccount,
|
||||
current: bool,
|
||||
index: usize,
|
||||
size: usize,
|
||||
mut on_select: impl FnMut()) {
|
||||
// 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);
|
||||
ui.painter().rect(bg_rect,
|
||||
item_rounding,
|
||||
Colors::fill(),
|
||||
View::item_stroke(),
|
||||
StrokeKind::Outside);
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Draw button to select account.
|
||||
if current {
|
||||
View::selected_item_check(ui);
|
||||
} else {
|
||||
let button_rounding = View::item_rounding(index, size, true);
|
||||
View::item_button(ui, button_rounding, CHECK, None, || {
|
||||
on_select();
|
||||
});
|
||||
}
|
||||
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(8.0);
|
||||
ui.vertical(|ui| {
|
||||
ui.add_space(3.0);
|
||||
// Show spendable amount.
|
||||
let amount = amount_to_hr_string(acc.spendable_amount, true);
|
||||
let amount_text = format!("{} {}", amount, GRIN);
|
||||
ui.with_layout(Layout::left_to_right(Align::Min), |ui| {
|
||||
ui.add_space(1.0);
|
||||
ui.label(RichText::new(amount_text)
|
||||
.size(18.0)
|
||||
.color(Colors::white_or_black(true)));
|
||||
});
|
||||
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").into()
|
||||
} else {
|
||||
acc.label.to_owned()
|
||||
};
|
||||
let acc_name = format!("{} {}", FOLDER_USER, acc_label);
|
||||
View::ellipsize_text(ui, acc_name, 15.0, Colors::text(false));
|
||||
|
||||
// Show account BIP32 derivation path.
|
||||
let acc_path = format!("{} {}", PATH, acc.path);
|
||||
ui.label(RichText::new(acc_path).size(15.0).color(Colors::gray()));
|
||||
ui.add_space(3.0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
// Copyright 2025 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 egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Align, Layout, RichText, ScrollArea, StrokeKind};
|
||||
use grin_core::core::amount_to_hr_string;
|
||||
|
||||
use crate::gui::icons::{CHECK, FOLDER_USER, PATH};
|
||||
use crate::gui::views::wallets::wallet::types::GRIN;
|
||||
use crate::gui::views::View;
|
||||
use crate::gui::Colors;
|
||||
use crate::wallet::types::WalletAccount;
|
||||
use crate::wallet::WalletConfig;
|
||||
|
||||
/// Wallet account list content.
|
||||
pub struct WalletAccountsContent {
|
||||
/// List of wallet accounts.
|
||||
accounts: Vec<WalletAccount>,
|
||||
/// Current wallet account label.
|
||||
current_label: String,
|
||||
}
|
||||
|
||||
const ACCOUNT_ITEM_HEIGHT: f32 = 75.0;
|
||||
|
||||
impl WalletAccountsContent {
|
||||
/// Create new accounts content.
|
||||
pub fn new(accounts: Vec<WalletAccount>, current: String) -> Self {
|
||||
Self { accounts, current_label: current }
|
||||
}
|
||||
|
||||
/// Draw account list content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, mut on_select: impl FnMut(WalletAccount)) {
|
||||
let size = self.accounts.len();
|
||||
ScrollArea::vertical()
|
||||
.id_salt("account_list_scroll")
|
||||
.scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden)
|
||||
.max_height(411.0)
|
||||
.auto_shrink([true; 2])
|
||||
.show_rows(ui, ACCOUNT_ITEM_HEIGHT, size, |ui, row_range| {
|
||||
for index in row_range {
|
||||
let acc = self.accounts.get(index).unwrap().clone();
|
||||
self.account_item_ui(ui, &acc, index, size, || {
|
||||
on_select(acc.clone());
|
||||
});
|
||||
if index == size - 1 {
|
||||
ui.add_space(4.0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw account item.
|
||||
fn account_item_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
acc: &WalletAccount,
|
||||
index: usize,
|
||||
size: usize,
|
||||
mut on_select: impl FnMut()) {
|
||||
// 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);
|
||||
ui.painter().rect(bg_rect,
|
||||
item_rounding,
|
||||
Colors::fill(),
|
||||
View::item_stroke(),
|
||||
StrokeKind::Outside);
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Draw button to select account.
|
||||
if self.current_label == acc.label {
|
||||
View::selected_item_check(ui);
|
||||
} else {
|
||||
let button_rounding = View::item_rounding(index, size, true);
|
||||
View::item_button(ui, button_rounding, CHECK, None, || {
|
||||
on_select();
|
||||
});
|
||||
}
|
||||
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(8.0);
|
||||
ui.vertical(|ui| {
|
||||
ui.add_space(3.0);
|
||||
// Show spendable amount.
|
||||
let amount = amount_to_hr_string(acc.spendable_amount, true);
|
||||
let amount_text = format!("{} {}", amount, GRIN);
|
||||
ui.with_layout(Layout::left_to_right(Align::Min), |ui| {
|
||||
ui.add_space(1.0);
|
||||
ui.label(RichText::new(amount_text)
|
||||
.size(18.0)
|
||||
.color(Colors::white_or_black(true)));
|
||||
});
|
||||
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").into()
|
||||
} else {
|
||||
acc.label.to_owned()
|
||||
};
|
||||
let acc_name = format!("{} {}", FOLDER_USER, acc_label);
|
||||
View::ellipsize_text(ui, acc_name, 15.0, Colors::text(false));
|
||||
|
||||
// Show account BIP32 derivation path.
|
||||
let acc_path = format!("{} {}", PATH, acc.path);
|
||||
ui.label(RichText::new(acc_path).size(15.0).color(Colors::gray()));
|
||||
ui.add_space(3.0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
mod content;
|
||||
mod list;
|
||||
mod create;
|
||||
pub use content::*;
|
||||
|
||||
pub use content::*;
|
||||
mod create;
|
||||
@@ -19,7 +19,7 @@ use grin_chain::SyncStatus;
|
||||
use crate::gui::icons::{ARROWS_CLOCKWISE, FILE_ARROW_DOWN, FILE_ARROW_UP, FILE_TEXT, GEAR_FINE, POWER, STACK};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::types::{LinePosition, ModalPosition};
|
||||
use crate::gui::views::wallets::wallet::account::AccountContent;
|
||||
use crate::gui::views::wallets::wallet::account::WalletAccountContent;
|
||||
use crate::gui::views::wallets::wallet::message::MessageInputContent;
|
||||
use crate::gui::views::wallets::wallet::request::{InvoiceRequestContent, SendRequestContent};
|
||||
use crate::gui::views::wallets::wallet::transport::WalletTransportContent;
|
||||
@@ -42,7 +42,7 @@ pub struct WalletContent {
|
||||
pub settings_content: Option<WalletSettingsContent>,
|
||||
|
||||
/// Account panel content.
|
||||
pub account_content: AccountContent,
|
||||
pub account_content: WalletAccountContent,
|
||||
/// Transport panel content.
|
||||
pub transport_content: WalletTransportContent,
|
||||
|
||||
@@ -150,9 +150,13 @@ impl WalletContentContainer for WalletContent {
|
||||
}
|
||||
});
|
||||
|
||||
// Close scanner when account panel got hidden.
|
||||
if !show_account && self.account_content.qr_scan_showing() {
|
||||
self.account_content.close_qr_scan(cb);
|
||||
// Close scanner or account list when account panel got hidden.
|
||||
if !show_account {
|
||||
if self.account_content.qr_scan_showing() {
|
||||
self.account_content.close_qr_scan(cb);
|
||||
} else {
|
||||
self.account_content.show_list = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Flag to check if account panel is opened.
|
||||
@@ -302,7 +306,7 @@ impl Default for WalletContent {
|
||||
Self {
|
||||
txs_content: Some(WalletTransactionsContent::new(None)),
|
||||
settings_content: None,
|
||||
account_content: AccountContent::default(),
|
||||
account_content: WalletAccountContent::default(),
|
||||
transport_content: WalletTransportContent::default(),
|
||||
invoice_content: None,
|
||||
send_content: None,
|
||||
@@ -316,7 +320,7 @@ impl WalletContent {
|
||||
pub fn title(&self) -> impl Into<String> {
|
||||
if self.account_content.qr_scan_showing() {
|
||||
t!("scan_qr")
|
||||
} else if self.account_content.list_content.is_some() {
|
||||
} else if self.account_content.show_list {
|
||||
t!("wallets.accounts")
|
||||
} else if self.transport_content.settings_content.is_some() {
|
||||
t!("wallets.transport")
|
||||
|
||||
@@ -40,13 +40,6 @@ impl WalletContentContainer for WalletTransportContent {
|
||||
|
||||
fn container_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
if let Some(content) = self.qr_address_content.as_mut() {
|
||||
// Close panel on wallet change.
|
||||
if let Some(address) = wallet.slatepack_address() {
|
||||
if address != content.text {
|
||||
self.qr_address_content = None;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Draw QR code content.
|
||||
ui.add_space(6.0);
|
||||
content.ui(ui, cb);
|
||||
|
||||
Reference in New Issue
Block a user