revault-gui
revault-gui copied to clipboard
UI: Do not display zero value when state is not fully loaded
- [x] deposit.rs
- [x] emergency.rs
- [x] manager.rs
- [ ] settings.rs
- [ ] sign.rs
- [ ] spend_transaction.rs
- [x] stakeholder.rs
- [ ] vault.rs
- [x] vaults.rs
- [x] history.rs
What was the context for this? I don't remember.
The GUI is a little slow without the --release flag, then when changing state, the view display default values like 0 balance while waiting the response of revaultd. We should display nothing until, all revaultd responses are returned
My idea was to have an object like:
pub enum Loadable<T> {
Loading,
Loaded(T)
}
and then passing to the view method a Loadable object, so for example:
pub fn view<'a>(
&'a mut self,
ctx: &Context,
spend_txs: Vec<Element<'a, Message>>,
would become
pub fn view<'a>(
&'a mut self,
ctx: &Context,
spend_txs: Loadable<Vec<Element<'a, Message>>>,
then matching on the Loadable, and if it's in a Loading state you don't show certain parts of the UI
Can you provide an example how it is store in the State owning the view ?
Ok, it's way worse than what I expected:
(disclaimer, this doesn't compile yet as there are some iter_mut and iter around that need to be transformed in if let)
diff --git a/src/ui/mod.rs b/src/ui/mod.rs
index 36f2081..10b710e 100644
--- a/src/ui/mod.rs
+++ b/src/ui/mod.rs
@@ -5,3 +5,9 @@ mod menu;
mod message;
mod state;
mod view;
+
+#[derive(Debug)]
+pub enum Loadable<T> {
+ Loading,
+ Ready(T),
+}
diff --git a/src/ui/state/stakeholder.rs b/src/ui/state/stakeholder.rs
index 0f53800..14c0548 100644
--- a/src/ui/state/stakeholder.rs
+++ b/src/ui/state/stakeholder.rs
@@ -21,6 +21,7 @@ use crate::ui::{
Context, StakeholderACKFundsView, StakeholderDelegateFundsView, StakeholderHomeView,
StakeholderNetworkView,
},
+ Loadable,
};
#[derive(Debug)]
@@ -228,7 +229,7 @@ pub struct StakeholderACKFundsState {
warning: Option<Error>,
balance: u64,
- deposits: Vec<VaultListItem<AcknowledgeVaultListItemView>>,
+ deposits: Loadable<Vec<VaultListItem<AcknowledgeVaultListItemView>>>,
selected_vault: Option<Vault>,
view: StakeholderACKFundsView,
@@ -239,7 +240,7 @@ impl StakeholderACKFundsState {
StakeholderACKFundsState {
revaultd,
warning: None,
- deposits: Vec::new(),
+ deposits: Loadable::Loading,
view: StakeholderACKFundsView::new(),
balance: 0,
selected_vault: None,
@@ -254,25 +255,27 @@ impl StakeholderACKFundsState {
}
}
- if let Some(selected) = self
- .deposits
- .iter()
- .find(|vlt| vlt.vault.outpoint() == outpoint)
- {
- self.selected_vault = Some(Vault::new(selected.vault.clone()));
- return Command::perform(
- get_revocation_txs(self.revaultd.clone(), selected.vault.outpoint()),
- move |res| {
- Message::Vault(outpoint.clone(), VaultMessage::RevocationTransactions(res))
- },
- );
- };
+ if let Loadable::Ready(deposits) = self.deposits {
+ if let Some(selected) =
+ deposits
+ .iter()
+ .find(|vlt| vlt.vault.outpoint() == outpoint)
+ {
+ self.selected_vault = Some(Vault::new(selected.vault.clone()));
+ return Command::perform(
+ get_revocation_txs(self.revaultd.clone(), selected.vault.outpoint()),
+ move |res| {
+ Message::Vault(outpoint.clone(), VaultMessage::RevocationTransactions(res))
+ },
+ );
+ };
+ }
Command::none()
}
fn update_deposits(&mut self, vaults: Vec<model::Vault>) {
self.calculate_balance(&vaults);
- self.deposits = vaults.into_iter().map(VaultListItem::new).collect();
+ self.deposits = Loadable::Ready(vaults.into_iter().map(VaultListItem::new).collect());
}
fn calculate_balance(&mut self, vaults: &[model::Vault]) {
diff --git a/src/ui/view/stakeholder.rs b/src/ui/view/stakeholder.rs
index b189ebe..e238e62 100644
--- a/src/ui/view/stakeholder.rs
+++ b/src/ui/view/stakeholder.rs
@@ -10,6 +10,7 @@ use crate::ui::{
menu::Menu,
message::Message,
view::Context,
+ Loadable,
};
#[derive(Debug)]
@@ -29,7 +30,7 @@ impl StakeholderACKFundsView {
pub fn view<'a>(
&'a mut self,
_ctx: &Context,
- deposits: Vec<Element<'a, Message>>,
+ deposits: Loadable<Vec<Element<'a, Message>>>,
) -> Element<'a, Message> {
let mut col_deposits = Column::new();
for element in deposits.into_iter() {
My point was to use Loadable as if it was an Option. The problem is that you don't have some utilities like map() and you have to continuosly map or if let...
A second way could be to create an enum from the State and collecting every loading models in one message. Ex:
#[derive(Debug)]
pub enum VaultsState {
Loading,
Loaded {
revaultd: Arc<RevaultD>,
view: VaultsView,
blockheight: u64,
vault_status_filter: &'static [VaultStatus],
vaults: Vec<VaultListItem<VaultListItemView>>,
selected_vault: Option<Vault>,
warning: Option<Error>,
},
}
whith load like:
fn load(&self, revaultd: Arc<RevaultD>) -> Command<Message> {
Command::batch(vec![Command::perform(
load_vaults_state(revaultd.clone()),
Message::LoadVaultState,
)])
}
with view like:
fn view(&mut self, ctx: &Context) -> Element<Message> {
match self {
Self::Loading => view::dashboard_loading(ctx);
Self::Loaded{view, ..} => view.view(ctx,...)
}
I think we use revaultd only for update and load, we can stop allocate it each time we change state and just pass it as arg
fn update(&mut self, revaultd: Arc<RevaultD>, message: Message) -> Command<Message>
Was this addressed?
Nope, we still have 0 in some screens
I think it's important to fix this, at least in the home