improve amount error labels adding dust threshold label for too low amounts

This commit is contained in:
Craig Raw 2021-06-29 12:48:02 +02:00
parent badf8c8f2f
commit 8033e5fd88
3 changed files with 35 additions and 11 deletions

View file

@ -21,6 +21,8 @@ import com.sparrowwallet.sparrow.event.FiatCurrencySelectedEvent;
import com.sparrowwallet.sparrow.io.Config; import com.sparrowwallet.sparrow.io.Config;
import com.sparrowwallet.sparrow.net.ExchangeSource; import com.sparrowwallet.sparrow.net.ExchangeSource;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
@ -65,12 +67,19 @@ public class PaymentController extends WalletFormController implements Initializ
@FXML @FXML
private Label amountStatus; private Label amountStatus;
@FXML
private Label dustStatus;
@FXML @FXML
private ToggleButton maxButton; private ToggleButton maxButton;
@FXML @FXML
private Button addPaymentButton; private Button addPaymentButton;
private final BooleanProperty emptyAmountProperty = new SimpleBooleanProperty(true);
private final BooleanProperty dustAmountProperty = new SimpleBooleanProperty();
private final ChangeListener<String> amountListener = new ChangeListener<>() { private final ChangeListener<String> amountListener = new ChangeListener<>() {
@Override @Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
@ -86,8 +95,12 @@ public class PaymentController extends WalletFormController implements Initializ
Long recipientValueSats = getRecipientValueSats(); Long recipientValueSats = getRecipientValueSats();
if(recipientValueSats != null) { if(recipientValueSats != null) {
setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), recipientValueSats); setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), recipientValueSats);
dustAmountProperty.set(recipientValueSats <= getRecipientDustThreshold());
emptyAmountProperty.set(false);
} else { } else {
fiatAmount.setText(""); fiatAmount.setText("");
dustAmountProperty.set(false);
emptyAmountProperty.set(true);
} }
sendController.updateTransaction(); sendController.updateTransaction();
@ -115,7 +128,7 @@ public class PaymentController extends WalletFormController implements Initializ
//ignore, not a URI //ignore, not a URI
} }
revalidate(amount, amountListener); revalidateAmount();
maxButton.setDisable(!isValidAddressAndLabel()); maxButton.setDisable(!isValidAddressAndLabel());
sendController.updateTransaction(); sendController.updateTransaction();
@ -148,10 +161,9 @@ public class PaymentController extends WalletFormController implements Initializ
maxButton.setText("Max" + newValue); maxButton.setText("Max" + newValue);
}); });
amountStatus.managedProperty().bind(amountStatus.visibleProperty()); amountStatus.managedProperty().bind(amountStatus.visibleProperty());
amountStatus.setVisible(sendController.isInsufficientInputs()); amountStatus.visibleProperty().bind(sendController.insufficientInputsProperty().and(dustAmountProperty.not()).and(emptyAmountProperty.not()));
sendController.insufficientInputsProperty().addListener((observable, oldValue, newValue) -> { dustStatus.managedProperty().bind(dustStatus.visibleProperty());
amountStatus.setVisible(newValue); dustStatus.visibleProperty().bind(dustAmountProperty);
});
Optional<Tab> firstTab = sendController.getPaymentTabs().getTabs().stream().findFirst(); Optional<Tab> firstTab = sendController.getPaymentTabs().getTabs().stream().findFirst();
if(firstTab.isPresent()) { if(firstTab.isPresent()) {
@ -173,7 +185,7 @@ public class PaymentController extends WalletFormController implements Initializ
Validator.createEmptyValidator("Label is required") Validator.createEmptyValidator("Label is required")
)); ));
validationSupport.registerValidator(amount, Validator.combine( validationSupport.registerValidator(amount, Validator.combine(
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Inputs", sendController.isInsufficientInputs()), (Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Inputs", getRecipientValueSats() != null && sendController.isInsufficientInputs()),
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Value", getRecipientValueSats() != null && getRecipientValueSats() <= getRecipientDustThreshold()) (Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Value", getRecipientValueSats() != null && getRecipientValueSats() <= getRecipientDustThreshold())
)); ));
} }
@ -234,8 +246,11 @@ public class PaymentController extends WalletFormController implements Initializ
} }
} }
public void revalidate() { public void revalidateAmount() {
revalidate(amount, amountListener); revalidate(amount, amountListener);
Long recipientValueSats = getRecipientValueSats();
dustAmountProperty.set(recipientValueSats != null && recipientValueSats <= getRecipientDustThreshold());
emptyAmountProperty.set(recipientValueSats == null);
} }
private void revalidate(TextField field, ChangeListener<String> listener) { private void revalidate(TextField field, ChangeListener<String> listener) {
@ -302,7 +317,7 @@ public class PaymentController extends WalletFormController implements Initializ
fiatAmount.setText(""); fiatAmount.setText("");
setSendMax(false); setSendMax(false);
amountStatus.setVisible(false); dustAmountProperty.set(false);
} }
public void setMaxInput(ActionEvent event) { public void setMaxInput(ActionEvent event) {

View file

@ -170,7 +170,7 @@ public class SendController extends WalletFormController implements Initializabl
userFeeSet.set(false); userFeeSet.set(false);
for(Tab tab : paymentTabs.getTabs()) { for(Tab tab : paymentTabs.getTabs()) {
PaymentController controller = (PaymentController)tab.getUserData(); PaymentController controller = (PaymentController)tab.getUserData();
controller.revalidate(); controller.revalidateAmount();
} }
updateTransaction(); updateTransaction();
} }
@ -183,7 +183,7 @@ public class SendController extends WalletFormController implements Initializabl
userFeeSet.set(false); userFeeSet.set(false);
for(Tab tab : paymentTabs.getTabs()) { for(Tab tab : paymentTabs.getTabs()) {
PaymentController controller = (PaymentController)tab.getUserData(); PaymentController controller = (PaymentController)tab.getUserData();
controller.revalidate(); controller.revalidateAmount();
} }
updateTransaction(); updateTransaction();
} }
@ -228,7 +228,7 @@ public class SendController extends WalletFormController implements Initializabl
insufficientInputsProperty.addListener((observable, oldValue, newValue) -> { insufficientInputsProperty.addListener((observable, oldValue, newValue) -> {
for(Tab tab : paymentTabs.getTabs()) { for(Tab tab : paymentTabs.getTabs()) {
PaymentController controller = (PaymentController)tab.getUserData(); PaymentController controller = (PaymentController)tab.getUserData();
controller.revalidate(); controller.revalidateAmount();
} }
revalidate(fee, feeListener); revalidate(fee, feeListener);
}); });
@ -905,6 +905,7 @@ public class SendController extends WalletFormController implements Initializabl
excludedChangeNodes.clear(); excludedChangeNodes.clear();
walletTransactionProperty.setValue(null); walletTransactionProperty.setValue(null);
createdWalletTransactionProperty.set(null); createdWalletTransactionProperty.set(null);
insufficientInputsProperty.set(false);
validationSupport.setErrorDecorationEnabled(false); validationSupport.setErrorDecorationEnabled(false);
} }

View file

@ -65,6 +65,14 @@
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="EXCLAMATION_CIRCLE" styleClass="failure" /> <Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="EXCLAMATION_CIRCLE" styleClass="failure" />
</graphic> </graphic>
</Label> </Label>
<Label fx:id="dustStatus" text="Amount too low">
<tooltip>
<Tooltip text="Amount below the Bitcoin network dust threshold for this address type" />
</tooltip>
<graphic>
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="EXCLAMATION_CIRCLE" styleClass="failure" />
</graphic>
</Label>
</Group> </Group>
<Region style="-fx-pref-width: 5" /> <Region style="-fx-pref-width: 5" />
<ToggleButton fx:id="maxButton" text="Max" onAction="#setMaxInput" /> <ToggleButton fx:id="maxButton" text="Max" onAction="#setMaxInput" />