mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-05 05:46:44 +00:00
create wallet transaction in background thread to keep ui responsive, and indicate if long running
This commit is contained in:
parent
40faaec31e
commit
11189bc605
3 changed files with 103 additions and 14 deletions
|
@ -49,6 +49,30 @@ public class TransactionDiagram extends GridPane {
|
|||
}
|
||||
}
|
||||
|
||||
public void update(String message) {
|
||||
setMinHeight(getDiagramHeight());
|
||||
setMaxHeight(getDiagramHeight());
|
||||
|
||||
getChildren().clear();
|
||||
|
||||
VBox messagePane = new VBox();
|
||||
messagePane.setPrefHeight(getDiagramHeight());
|
||||
messagePane.setPadding(new Insets(0, 10, 0, 280));
|
||||
messagePane.setAlignment(Pos.CENTER);
|
||||
messagePane.getChildren().add(createSpacer());
|
||||
|
||||
Label messageLabel = new Label(message);
|
||||
messagePane.getChildren().add(messageLabel);
|
||||
messagePane.getChildren().add(createSpacer());
|
||||
|
||||
GridPane.setConstraints(messagePane, 3, 0);
|
||||
getChildren().add(messagePane);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
getChildren().clear();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
Map<BlockTransactionHashIndex, WalletNode> displayedUtxos = getDisplayedUtxos();
|
||||
|
||||
|
|
|
@ -235,8 +235,10 @@ public class PaymentController extends WalletFormController implements Initializ
|
|||
private void revalidate(TextField field, ChangeListener<String> listener) {
|
||||
field.textProperty().removeListener(listener);
|
||||
String amt = field.getText();
|
||||
int caret = field.getCaretPosition();
|
||||
field.setText(amt + "0");
|
||||
field.setText(amt);
|
||||
field.positionCaret(caret);
|
||||
field.textProperty().addListener(listener);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,15 +13,16 @@ import com.sparrowwallet.sparrow.control.*;
|
|||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
||||
import com.sparrowwallet.sparrow.net.ElectrumServer;
|
||||
import com.sparrowwallet.sparrow.net.FeeRatesSource;
|
||||
import com.sparrowwallet.sparrow.net.MempoolRateSize;
|
||||
import com.sparrowwallet.sparrow.net.*;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -29,6 +30,7 @@ import javafx.fxml.Initializable;
|
|||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.controlsfx.validation.ValidationResult;
|
||||
|
@ -187,6 +189,8 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
|
||||
private ValidationSupport validationSupport;
|
||||
|
||||
private WalletTransactionService walletTransactionService;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
EventManager.get().register(this);
|
||||
|
@ -484,20 +488,40 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
boolean groupByAddress = Config.get().isGroupByAddress();
|
||||
boolean includeMempoolOutputs = Config.get().isIncludeMempoolOutputs();
|
||||
boolean includeSpentMempoolOutputs = includeSpentMempoolOutputsProperty.get();
|
||||
WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), payments, feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
walletTransactionProperty.setValue(walletTransaction);
|
||||
insufficientInputsProperty.set(false);
|
||||
|
||||
return;
|
||||
if(walletTransactionService != null && walletTransactionService.isRunning()) {
|
||||
walletTransactionService.cancel();
|
||||
}
|
||||
} catch(InvalidAddressException | IllegalStateException | IllegalArgumentException e) {
|
||||
//ignore
|
||||
} catch(InsufficientFundsException e) {
|
||||
|
||||
walletTransactionService = new WalletTransactionService(wallet, getUtxoSelectors(), getUtxoFilters(), payments, feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
walletTransactionService.setOnSucceeded(event -> {
|
||||
walletTransactionProperty.setValue(walletTransactionService.getValue());
|
||||
insufficientInputsProperty.set(false);
|
||||
});
|
||||
walletTransactionService.setOnFailed(event -> {
|
||||
transactionDiagram.clear();
|
||||
walletTransactionProperty.setValue(null);
|
||||
if(event.getSource().getException() instanceof InsufficientFundsException) {
|
||||
insufficientInputsProperty.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
final WalletTransactionService currentWalletTransactionService = walletTransactionService;
|
||||
final KeyFrame delay = new KeyFrame(Duration.millis(200), e -> {
|
||||
if(currentWalletTransactionService.isRunning()) {
|
||||
transactionDiagram.update("Selecting UTXOs...");
|
||||
createButton.setDisable(true);
|
||||
}
|
||||
});
|
||||
final Timeline timeline = new Timeline(delay);
|
||||
timeline.play();
|
||||
|
||||
walletTransactionService.start();
|
||||
}
|
||||
} catch(InvalidAddressException | IllegalStateException e) {
|
||||
walletTransactionProperty.setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
private List<UtxoSelector> getUtxoSelectors() throws InvalidAddressException {
|
||||
if(utxoSelectorProperty.get() != null) {
|
||||
|
@ -511,6 +535,43 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
return List.of(new BnBUtxoSelector(noInputsFee, costOfChange), new KnapsackUtxoSelector(noInputsFee));
|
||||
}
|
||||
|
||||
private static class WalletTransactionService extends Service<WalletTransaction> {
|
||||
private final Wallet wallet;
|
||||
private final List<UtxoSelector> utxoSelectors;
|
||||
private final List<UtxoFilter> utxoFilters;
|
||||
private final List<Payment> payments;
|
||||
private final double feeRate;
|
||||
private final double longTermFeeRate;
|
||||
private final Long fee;
|
||||
private final Integer currentBlockHeight;
|
||||
private final boolean groupByAddress;
|
||||
private final boolean includeMempoolOutputs;
|
||||
private final boolean includeSpentMempoolOutputs;
|
||||
|
||||
public WalletTransactionService(Wallet wallet, List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, List<Payment> payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) {
|
||||
this.wallet = wallet;
|
||||
this.utxoSelectors = utxoSelectors;
|
||||
this.utxoFilters = utxoFilters;
|
||||
this.payments = payments;
|
||||
this.feeRate = feeRate;
|
||||
this.longTermFeeRate = longTermFeeRate;
|
||||
this.fee = fee;
|
||||
this.currentBlockHeight = currentBlockHeight;
|
||||
this.groupByAddress = groupByAddress;
|
||||
this.includeMempoolOutputs = includeMempoolOutputs;
|
||||
this.includeSpentMempoolOutputs = includeSpentMempoolOutputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<WalletTransaction> createTask() {
|
||||
return new Task<>() {
|
||||
protected WalletTransaction call() throws InsufficientFundsException {
|
||||
return wallet.createWalletTransaction(utxoSelectors, utxoFilters, payments, feeRate, longTermFeeRate, fee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private List<UtxoFilter> getUtxoFilters() {
|
||||
UtxoFilter utxoFilter = utxoFilterProperty.get();
|
||||
if(utxoFilter != null) {
|
||||
|
@ -872,8 +933,10 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
private void revalidate(TextField field, ChangeListener<String> listener) {
|
||||
field.textProperty().removeListener(listener);
|
||||
String amt = field.getText();
|
||||
int caret = field.getCaretPosition();
|
||||
field.setText(amt + "0");
|
||||
field.setText(amt);
|
||||
field.positionCaret(caret);
|
||||
field.textProperty().addListener(listener);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue