diff --git a/src/action.rs b/src/action.rs index bed98a9..27fcd4d 100644 --- a/src/action.rs +++ b/src/action.rs @@ -32,7 +32,7 @@ pub enum Action { ClosePopup, BalanceRequest([u8; 32], bool), - BalanceResponse([u8; 32], SystemAccount), + BalanceResponse([u8; 32], Option), BalanceSetActive(Option), RenameAccount(String), @@ -118,5 +118,5 @@ pub enum Action { GetExistentialDeposit, SetExistentialDeposit(u128), - SetTotalIssuance(u128), + SetTotalIssuance(Option), } diff --git a/src/components/validator/stash_details.rs b/src/components/validator/stash_details.rs index 1814ed1..5031d57 100644 --- a/src/components/validator/stash_details.rs +++ b/src/components/validator/stash_details.rs @@ -8,6 +8,7 @@ use ratatui::{ }; use super::{PartialComponent, Component, CurrentTab}; +use crate::widgets::DotSpinner; use crate::{ action::Action, config::Config, @@ -17,9 +18,9 @@ use crate::{ pub struct StashDetails { palette: StylePalette, is_bonded: bool, - free_balance: u128, - staked_total: u128, - staked_active: u128, + free_balance: Option, + staked_total: Option, + staked_active: Option, stash_account_id: [u8; 32], } @@ -37,17 +38,22 @@ impl StashDetails { Self { palette: StylePalette::default(), is_bonded: false, - free_balance: 0, - staked_total: 0, - staked_active: 0, + free_balance: None, + staked_total: None, + staked_active: None, stash_account_id: [0u8; 32], } } - fn prepare_u128(&self, value: u128) -> String { - let value = value as f64 / 10f64.powi(18); - let after = Self::DECIMALS; - format!("{:.after$}{}", value, Self::TICKER) + fn prepare_u128(&self, maybe_value: Option) -> String { + match maybe_value { + Some(value) => { + let value = value as f64 / 10f64.powi(18); + let after = Self::DECIMALS; + format!("{:.after$}{}", value, Self::TICKER) + }, + None => format!("{}{}", DotSpinner::default().to_string(), Self::TICKER) + } } fn is_bonded_to_string(&self) -> String { @@ -83,13 +89,13 @@ impl Component for StashDetails { Action::SetStashAccount(account_id) => self.stash_account_id = account_id, Action::SetBondedAmount(is_bonded) => self.is_bonded = is_bonded, Action::SetStakedAmountRatio(total, active) => { - self.staked_total = total; - self.staked_active = active; + self.staked_total = Some(total); + self.staked_active = Some(active); }, - Action::BalanceResponse(account_id, balance) if account_id == self.stash_account_id => { - self.free_balance = balance.free + Action::BalanceResponse(account_id, maybe_balance) if account_id == self.stash_account_id => { + self.free_balance = maybe_balance.map(|balance| balance.free .saturating_sub(balance.frozen) - .saturating_sub(balance.reserved); + .saturating_sub(balance.reserved)); }, _ => {} }; diff --git a/src/components/wallet/accounts.rs b/src/components/wallet/accounts.rs index 14dcaa9..6c123b7 100644 --- a/src/components/wallet/accounts.rs +++ b/src/components/wallet/accounts.rs @@ -15,18 +15,17 @@ use ratatui::{ }, Frame }; -use subxt::{ - ext::sp_core::{ - Pair as PairT, - sr25519::Pair, - crypto::{Ss58Codec, Ss58AddressFormat, AccountId32}, - }, +use subxt::ext::sp_core::{ + Pair as PairT, + sr25519::Pair, + crypto::{Ss58Codec, Ss58AddressFormat, AccountId32}, }; use tokio::sync::mpsc::UnboundedSender; use std::sync::mpsc::Sender; use super::{PartialComponent, Component, CurrentTab}; use crate::types::{SystemAccount, ActionLevel}; +use crate::widgets::DotSpinner; use crate::{ action::Action, config::Config, @@ -59,6 +58,9 @@ impl Default for Accounts { } impl Accounts { + const TICKER: &str = " CSPR"; + const DECIMALS: usize = 3; + pub fn new() -> Self { Self { is_active: false, @@ -353,9 +355,15 @@ impl Accounts { self.set_used_account(i); } - fn prepare_u128(&self, value: u128, after: usize, ticker: Option<&str>) -> String { - let value = value as f64 / 10f64.powi(18); - format!("{:.after$}{}", value, ticker.unwrap_or_default()) + fn prepare_u128(&self, maybe_value: Option) -> String { + match maybe_value { + Some(value) => { + let value = value as f64 / 10f64.powi(18); + let after = Self::DECIMALS; + format!("{:.after$}{}", value, Self::TICKER) + } + None => format!("{}{}", DotSpinner::default().to_string(), Self::TICKER) + } } } @@ -402,9 +410,12 @@ impl Component for Accounts { match action { Action::NewAccount(name) => self.create_new_account(name), Action::UpdateAccountName(new_name) => self.rename_account(new_name), - Action::BalanceResponse(account_id, balance) => { + Action::BalanceResponse(account_id, maybe_balance) => { if self.wallet_keys.iter().any(|wallet| wallet.account_id == account_id) { - let _ = self.balances.insert(account_id, balance); + let _ = match maybe_balance { + Some(balance) => self.balances.insert(account_id, balance), + None => self.balances.remove(&account_id), + }; if let Some(index) = self.table_state.selected() { if self.wallet_keys[index].account_id == account_id { self.set_balance_active(index); @@ -445,12 +456,11 @@ impl Component for Accounts { .map(|info| { let balance = self.balances .get(&info.account_id) - .map(|b| b.free) - .unwrap_or_default(); + .map(|b| b.free); Row::new(vec![ Cell::from(Text::from(info.name.clone()).alignment(Alignment::Left)), Cell::from(Text::from(info.address.clone()).alignment(Alignment::Center)), - Cell::from(Text::from(self.prepare_u128(balance, 2, Some(" CSPR"))).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(balance)).alignment(Alignment::Right)), ]) }), [ diff --git a/src/components/wallet/address_book.rs b/src/components/wallet/address_book.rs index b69cfec..89c6084 100644 --- a/src/components/wallet/address_book.rs +++ b/src/components/wallet/address_book.rs @@ -53,6 +53,9 @@ impl Default for AddressBook { } impl AddressBook { + const TICKER: &str = " CSPR"; + const DECIMALS: usize = 3; + pub fn new() -> Self { Self { is_active: false, @@ -305,13 +308,14 @@ impl AddressBook { self.scroll_state = self.scroll_state.position(i); } - fn prepare_u128(&self, maybe_value: Option, ticker: Option<&str>, after: usize) -> String { + fn prepare_u128(&self, maybe_value: Option) -> String { match maybe_value { Some(value) => { let value = value as f64 / 10f64.powi(18); - format!("{:.after$}{}", value, ticker.unwrap_or_default()) + let after = Self::DECIMALS; + format!("{:.after$}{}", value, Self::TICKER) }, - None => DotSpinner::default().to_string(), + None => format!("{}{}", DotSpinner::default().to_string(), Self::TICKER) } } } @@ -360,9 +364,12 @@ impl Component for AddressBook { self.rename_record(new_name), Action::NewAddressBookRecord(name, address) => self.add_new_record(name, address), - Action::BalanceResponse(account_id, balance) => { + Action::BalanceResponse(account_id, maybe_balance) => { if self.address_book.iter().any(|record| record.account_id == account_id) { - let _ = self.balances.insert(account_id, balance); + let _ = match maybe_balance { + Some(balance) => self.balances.insert(account_id, balance), + None => self.balances.remove(&account_id), + }; } }, _ => {} @@ -407,7 +414,7 @@ impl Component for AddressBook { Row::new(vec![ Cell::from(Text::from(info.name.clone()).alignment(Alignment::Left)), Cell::from(Text::from(info.address.clone()).alignment(Alignment::Center)), - Cell::from(Text::from(self.prepare_u128(balance, Some(" CSPR"), 2)).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(balance)).alignment(Alignment::Right)), ]) }), [ diff --git a/src/components/wallet/balance.rs b/src/components/wallet/balance.rs index 529c74a..c8d3f51 100644 --- a/src/components/wallet/balance.rs +++ b/src/components/wallet/balance.rs @@ -32,7 +32,8 @@ impl Default for Balance { } impl Balance { - const DECIMALS_FOR_BALANCE: usize = 5; + const TICKER: &str = " CSPR"; + const DECIMALS: usize = 6; pub fn new() -> Self { Self { @@ -46,13 +47,14 @@ impl Balance { } } - fn prepare_u128(&self, maybe_value: Option, ticker: Option<&str>, after: usize) -> String { + fn prepare_u128(&self, maybe_value: Option) -> String { match maybe_value { Some(value) => { let value = value as f64 / 10f64.powi(18); - format!("{:.after$}{}", value, ticker.unwrap_or_default()) + let after = Self::DECIMALS; + format!("{:.after$}{}", value, Self::TICKER) }, - None => DotSpinner::default().to_string() + None => format!("{}{}", DotSpinner::default().to_string(), Self::TICKER) } } } @@ -84,15 +86,15 @@ impl Component for Balance { Action::BalanceSetActive(maybe_balance) => { match maybe_balance { Some(balance) => { - self.transferable_balance = Some(balance.free); + self.total_balance = Some(balance.free); self.locked_balance = Some(balance.reserved); self.bonded_balance = Some(balance.frozen); + self.nonce = Some(balance.nonce); - let total_balance = balance.free + let transferable = balance.free .saturating_add(balance.reserved) .saturating_add(balance.frozen); - self.total_balance = Some(total_balance); - self.nonce = Some(balance.nonce); + self.transferable_balance = Some(transferable); }, None => { self.transferable_balance = None; @@ -117,38 +119,26 @@ impl Component for Balance { [ Row::new(vec![ Cell::from(Text::from("nonce: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.nonce.map(|n| n as u128), - None, - 0)).alignment(Alignment::Right)), + Cell::from(Text::from(self.nonce + .map(|n| n.to_string()) + .unwrap_or(DotSpinner::default().to_string()) + ).alignment(Alignment::Right)), ]), Row::new(vec![ Cell::from(Text::from("account: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.total_balance, - Some(" CSPR"), - Self::DECIMALS_FOR_BALANCE)).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(self.total_balance)).alignment(Alignment::Right)), ]), Row::new(vec![ Cell::from(Text::from("free: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.transferable_balance, - Some(" CSPR"), - Self::DECIMALS_FOR_BALANCE)).alignment(Alignment::Right)) + Cell::from(Text::from(self.prepare_u128(self.transferable_balance)).alignment(Alignment::Right)) ]), Row::new(vec![ Cell::from(Text::from("locked: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.locked_balance, - Some(" CSPR"), - Self::DECIMALS_FOR_BALANCE)).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(self.locked_balance)).alignment(Alignment::Right)), ]), Row::new(vec![ Cell::from(Text::from("bonded: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.bonded_balance, - Some(" CSPR"), - Self::DECIMALS_FOR_BALANCE)).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(self.bonded_balance)).alignment(Alignment::Right)), ]), ], [ diff --git a/src/components/wallet/overview.rs b/src/components/wallet/overview.rs index e82ac49..59d7932 100644 --- a/src/components/wallet/overview.rs +++ b/src/components/wallet/overview.rs @@ -10,7 +10,7 @@ use super::{Component, PartialComponent, CurrentTab}; use crate::{ action::Action, config::Config, - palette::StylePalette, + palette::StylePalette, widgets::DotSpinner, }; #[derive(Debug)] @@ -28,7 +28,8 @@ impl Default for Overview { } impl Overview { - const DECIMALS_FOR_BALANCE: usize = 6; + const TICKER: &str = " CSPR"; + const DECIMALS: usize = 6; pub fn new() -> Self { Self { @@ -39,9 +40,15 @@ impl Overview { } } - fn prepare_u128(&self, value: u128, after: usize) -> String { - let value = value as f64 / 10f64.powi(18); - format!("{:.after$}", value) + fn prepare_u128(&self, maybe_value: Option) -> String { + match maybe_value { + Some(value) => { + let value = value as f64 / 10f64.powi(18); + let after = Self::DECIMALS; + format!("{:.after$}{}", value, Self::TICKER) + }, + None => format!("{}{}", DotSpinner::default().to_string(), Self::TICKER) + } } } @@ -70,7 +77,7 @@ impl Component for Overview { fn update(&mut self, action: Action) -> Result> { match action { Action::SetExistentialDeposit(ed) => self.existential_balance = Some(ed), - Action::SetTotalIssuance(issuance) => self.total_issuance = Some(issuance), + Action::SetTotalIssuance(maybe_issuance) => self.total_issuance = maybe_issuance, _ => {} }; Ok(None) @@ -85,25 +92,16 @@ impl Component for Overview { [ Row::new(vec![ Cell::from(Text::from("total supply: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.total_issuance.unwrap_or_default(), - Self::DECIMALS_FOR_BALANCE, - )).alignment(Alignment::Center)), - Cell::from(Text::from("CSPR".to_string()).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(self.total_issuance)).alignment(Alignment::Right)), ]), Row::new(vec![ Cell::from(Text::from("min deposit: ".to_string()).alignment(Alignment::Left)), - Cell::from(Text::from(self.prepare_u128( - self.existential_balance.unwrap_or_default(), - Self::DECIMALS_FOR_BALANCE, - )).alignment(Alignment::Center)), - Cell::from(Text::from("CSPR".to_string()).alignment(Alignment::Right)), + Cell::from(Text::from(self.prepare_u128(self.existential_balance)).alignment(Alignment::Right)), ]), ], [ Constraint::Max(15), Constraint::Min(0), - Constraint::Length(5), ] ) .block(Block::bordered() diff --git a/src/network/predefined_calls.rs b/src/network/predefined_calls.rs index b41523f..e90d1aa 100644 --- a/src/network/predefined_calls.rs +++ b/src/network/predefined_calls.rs @@ -111,10 +111,9 @@ pub async fn get_total_issuance( action_tx: &UnboundedSender, api: &OnlineClient, ) -> Result<()> { - let total_issuance = super::raw_calls::balances::total_issuance(api, None) - .await? - .unwrap_or_default(); - action_tx.send(Action::SetTotalIssuance(total_issuance))?; + let maybe_total_issuance = super::raw_calls::balances::total_issuance(api, None) + .await?; + action_tx.send(Action::SetTotalIssuance(maybe_total_issuance))?; Ok(()) } @@ -133,21 +132,15 @@ pub async fn get_balance( account_id: &[u8; 32], ) -> Result<()> { let maybe_balance = super::raw_calls::system::balance(api, None, account_id) - .await?; - - let balance = match maybe_balance { - Some(balance) => { - SystemAccount { + .await? + .map(|balance| SystemAccount { nonce: balance.nonce, free: balance.data.free, reserved: balance.data.reserved, frozen: balance.data.frozen, } - }, - None => SystemAccount::default(), - }; - - action_tx.send(Action::BalanceResponse(*account_id, balance))?; + ); + action_tx.send(Action::BalanceResponse(*account_id, maybe_balance))?; Ok(()) }