mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Simplify the trade complete summary dialog
This commit is contained in:
parent
670c5418ee
commit
1162060e28
2 changed files with 28 additions and 190 deletions
|
@ -898,6 +898,8 @@ portfolio.pending.step3_seller.onPaymentReceived.signer=IMPORTANT: By confirming
|
|||
you should delay confirmation of the payment as long as possible to reduce the risk of a chargeback.
|
||||
|
||||
portfolio.pending.step5_buyer.groupTitle=Summary of completed trade
|
||||
portfolio.pending.step5_buyer.groupTitle.mediated=This trade was resolved by mediation
|
||||
portfolio.pending.step5_buyer.groupTitle.arbitrated=This trade was resolved by arbitration
|
||||
portfolio.pending.step5_buyer.tradeFee=Trade fee
|
||||
portfolio.pending.step5_buyer.makersMiningFee=Mining fee
|
||||
portfolio.pending.step5_buyer.takersMiningFee=Total mining fees
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
package bisq.desktop.main.portfolio.pendingtrades.steps.buyer;
|
||||
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.components.TitledGroupBg;
|
||||
import bisq.desktop.main.MainView;
|
||||
import bisq.desktop.main.overlays.notifications.Notification;
|
||||
|
@ -31,26 +29,13 @@ import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel;
|
|||
import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||
import bisq.desktop.util.Layout;
|
||||
|
||||
import bisq.core.btc.exceptions.AddressEntryException;
|
||||
import bisq.core.btc.exceptions.InsufficientFundsException;
|
||||
import bisq.core.btc.model.AddressEntry;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.btc.wallet.Restrictions;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.trade.txproof.AssetTxProofResult;
|
||||
import bisq.core.user.DontShowAgainLookup;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
import bisq.core.util.coin.CoinUtil;
|
||||
import bisq.core.util.validation.BtcAddressValidator;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.app.DevEnv;
|
||||
import bisq.common.handlers.FaultHandler;
|
||||
import bisq.common.handlers.ResultHandler;
|
||||
|
||||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import com.jfoenix.controls.JFXBadge;
|
||||
|
||||
|
@ -63,20 +48,13 @@ import javafx.scene.layout.Priority;
|
|||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
|
||||
import org.bouncycastle.crypto.params.KeyParameter;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addInputTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
|
||||
public class BuyerStep4View extends TradeStepView {
|
||||
// private final ChangeListener<Boolean> focusedPropertyListener;
|
||||
|
||||
private InputTextField withdrawAddressTextField, withdrawMemoTextField;
|
||||
private Button withdrawToExternalWalletButton, useSavingsWalletButton;
|
||||
private TitledGroupBg withdrawTitledGroupBg;
|
||||
private Button closeButton;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, Initialisation
|
||||
|
@ -108,8 +86,13 @@ public class BuyerStep4View extends TradeStepView {
|
|||
gridPane.getColumnConstraints().get(1).setHgrow(Priority.SOMETIMES);
|
||||
|
||||
TitledGroupBg completedTradeLabel = new TitledGroupBg();
|
||||
if (trade.getDisputeState().isMediated()) {
|
||||
completedTradeLabel.setText(Res.get("portfolio.pending.step5_buyer.groupTitle.mediated"));
|
||||
} else if (trade.getDisputeState().isArbitrated()) {
|
||||
completedTradeLabel.setText(Res.get("portfolio.pending.step5_buyer.groupTitle.arbitrated"));
|
||||
} else {
|
||||
completedTradeLabel.setText(Res.get("portfolio.pending.step5_buyer.groupTitle"));
|
||||
|
||||
}
|
||||
JFXBadge autoConfBadge = new JFXBadge(new Label(""), Pos.BASELINE_RIGHT);
|
||||
autoConfBadge.setText(Res.get("portfolio.pending.autoConf"));
|
||||
autoConfBadge.getStyleClass().add("auto-conf");
|
||||
|
@ -120,6 +103,7 @@ public class BuyerStep4View extends TradeStepView {
|
|||
GridPane.setRowSpan(hBox2, 5);
|
||||
autoConfBadge.setVisible(AssetTxProofResult.COMPLETED == trade.getAssetTxProofResult());
|
||||
|
||||
if (trade.getDisputeState().isNotDisputed()) {
|
||||
addCompactTopLabelTextField(gridPane, gridRow, getBtcTradeAmountLabel(), model.getTradeVolume(), Layout.TWICE_FIRST_ROW_DISTANCE);
|
||||
addCompactTopLabelTextField(gridPane, ++gridRow, getFiatTradeAmountLabel(), model.getFiatVolume());
|
||||
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.refunded"), model.getSecurityDeposit());
|
||||
|
@ -128,41 +112,19 @@ public class BuyerStep4View extends TradeStepView {
|
|||
Res.get("portfolio.pending.step5_buyer.makersMiningFee") :
|
||||
Res.get("portfolio.pending.step5_buyer.takersMiningFee");
|
||||
addCompactTopLabelTextField(gridPane, ++gridRow, miningFee, model.getTxFee());
|
||||
withdrawTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, Res.get("portfolio.pending.step5_buyer.withdrawBTC"), Layout.COMPACT_GROUP_DISTANCE);
|
||||
withdrawTitledGroupBg.getStyleClass().add("last");
|
||||
addCompactTopLabelTextField(gridPane, gridRow, Res.get("portfolio.pending.step5_buyer.amount"), model.getPayoutAmount(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
}
|
||||
|
||||
withdrawAddressTextField = addInputTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.withdrawToAddress"));
|
||||
withdrawAddressTextField.setManaged(false);
|
||||
withdrawAddressTextField.setVisible(false);
|
||||
closeButton = new AutoTooltipButton(Res.get("shared.close"));
|
||||
closeButton.setDefaultButton(true);
|
||||
closeButton.getStyleClass().add("action-button");
|
||||
GridPane.setRowIndex(closeButton, ++gridRow);
|
||||
GridPane.setMargin(closeButton, new Insets(Layout.GROUP_DISTANCE, 10, 0, 0));
|
||||
gridPane.getChildren().add(closeButton);
|
||||
|
||||
withdrawMemoTextField = addInputTextField(gridPane, ++gridRow,
|
||||
Res.get("funds.withdrawal.memoLabel", Res.getBaseCurrencyCode()));
|
||||
withdrawMemoTextField.setPromptText(Res.get("funds.withdrawal.memo"));
|
||||
withdrawMemoTextField.setManaged(false);
|
||||
withdrawMemoTextField.setVisible(false);
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setSpacing(10);
|
||||
useSavingsWalletButton = new AutoTooltipButton(Res.get("portfolio.pending.step5_buyer.moveToBisqWallet"));
|
||||
useSavingsWalletButton.setDefaultButton(true);
|
||||
useSavingsWalletButton.getStyleClass().add("action-button");
|
||||
Label label = new AutoTooltipLabel(Res.get("shared.OR"));
|
||||
label.setPadding(new Insets(5, 0, 0, 0));
|
||||
withdrawToExternalWalletButton = new AutoTooltipButton(Res.get("portfolio.pending.step5_buyer.withdrawExternal"));
|
||||
withdrawToExternalWalletButton.setDefaultButton(false);
|
||||
hBox.getChildren().addAll(useSavingsWalletButton, label, withdrawToExternalWalletButton);
|
||||
GridPane.setRowIndex(hBox, ++gridRow);
|
||||
GridPane.setMargin(hBox, new Insets(5, 10, 0, 0));
|
||||
gridPane.getChildren().add(hBox);
|
||||
|
||||
useSavingsWalletButton.setOnAction(e -> {
|
||||
closeButton.setOnAction(e -> {
|
||||
handleTradeCompleted();
|
||||
model.dataModel.tradeManager.onTradeCompleted(trade);
|
||||
});
|
||||
withdrawToExternalWalletButton.setOnAction(e -> {
|
||||
onWithdrawal();
|
||||
});
|
||||
|
||||
String key = "tradeCompleted" + trade.getId();
|
||||
if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) {
|
||||
|
@ -174,128 +136,8 @@ public class BuyerStep4View extends TradeStepView {
|
|||
}
|
||||
}
|
||||
|
||||
private void onWithdrawal() {
|
||||
withdrawAddressTextField.setManaged(true);
|
||||
withdrawAddressTextField.setVisible(true);
|
||||
withdrawMemoTextField.setManaged(true);
|
||||
withdrawMemoTextField.setVisible(true);
|
||||
GridPane.setRowSpan(withdrawTitledGroupBg, 3);
|
||||
withdrawToExternalWalletButton.setDefaultButton(true);
|
||||
useSavingsWalletButton.setDefaultButton(false);
|
||||
withdrawToExternalWalletButton.getStyleClass().add("action-button");
|
||||
useSavingsWalletButton.getStyleClass().remove("action-button");
|
||||
|
||||
withdrawToExternalWalletButton.setOnAction(e -> {
|
||||
if (model.dataModel.isReadyForTxBroadcast()) {
|
||||
reviewWithdrawal();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void reviewWithdrawal() {
|
||||
Coin amount = trade.getPayoutAmount();
|
||||
BtcWalletService walletService = model.dataModel.btcWalletService;
|
||||
|
||||
AddressEntry fromAddressesEntry = walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT);
|
||||
String fromAddresses = fromAddressesEntry.getAddressString();
|
||||
String toAddresses = withdrawAddressTextField.getText();
|
||||
if (new BtcAddressValidator().validate(toAddresses).isValid) {
|
||||
Coin balance = walletService.getBalanceForAddress(fromAddressesEntry.getAddress());
|
||||
try {
|
||||
Transaction feeEstimationTransaction = walletService.getFeeEstimationTransaction(fromAddresses, toAddresses, amount, AddressEntry.Context.TRADE_PAYOUT);
|
||||
Coin fee = feeEstimationTransaction.getFee();
|
||||
Coin receiverAmount = amount.subtract(fee);
|
||||
if (balance.isZero()) {
|
||||
new Popup().warning(Res.get("portfolio.pending.step5_buyer.alreadyWithdrawn")).show();
|
||||
model.dataModel.tradeManager.onTradeCompleted(trade);
|
||||
} else {
|
||||
if (toAddresses.isEmpty()) {
|
||||
validateWithdrawAddress();
|
||||
} else if (Restrictions.isAboveDust(receiverAmount)) {
|
||||
CoinFormatter formatter = model.btcFormatter;
|
||||
int txVsize = feeEstimationTransaction.getVsize();
|
||||
double feePerVbyte = CoinUtil.getFeePerVbyte(fee, txVsize);
|
||||
double vkb = txVsize / 1000d;
|
||||
String recAmount = formatter.formatCoinWithCode(receiverAmount);
|
||||
new Popup().headLine(Res.get("portfolio.pending.step5_buyer.confirmWithdrawal"))
|
||||
.confirmation(Res.get("shared.sendFundsDetailsWithFee",
|
||||
formatter.formatCoinWithCode(amount),
|
||||
fromAddresses,
|
||||
toAddresses,
|
||||
formatter.formatCoinWithCode(fee),
|
||||
feePerVbyte,
|
||||
vkb,
|
||||
recAmount))
|
||||
.actionButtonText(Res.get("shared.yes"))
|
||||
.onAction(() -> doWithdrawal(amount, fee))
|
||||
.closeButtonText(Res.get("shared.cancel"))
|
||||
.onClose(() -> {
|
||||
useSavingsWalletButton.setDisable(false);
|
||||
withdrawToExternalWalletButton.setDisable(false);
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
new Popup().warning(Res.get("portfolio.pending.step5_buyer.amountTooLow")).show();
|
||||
}
|
||||
}
|
||||
} catch (AddressFormatException e) {
|
||||
validateWithdrawAddress();
|
||||
} catch (AddressEntryException e) {
|
||||
log.error(e.getMessage());
|
||||
} catch (InsufficientFundsException e) {
|
||||
log.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
new Popup().warning(e.getMessage()).show();
|
||||
}
|
||||
} else {
|
||||
new Popup().warning(Res.get("validation.btc.invalidAddress")).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void doWithdrawal(Coin amount, Coin fee) {
|
||||
String toAddress = withdrawAddressTextField.getText();
|
||||
ResultHandler resultHandler = this::handleTradeCompleted;
|
||||
FaultHandler faultHandler = (errorMessage, throwable) -> {
|
||||
useSavingsWalletButton.setDisable(false);
|
||||
withdrawToExternalWalletButton.setDisable(false);
|
||||
if (throwable != null && throwable.getMessage() != null)
|
||||
new Popup().error(errorMessage + "\n\n" + throwable.getMessage()).show();
|
||||
else
|
||||
new Popup().error(errorMessage).show();
|
||||
};
|
||||
if (model.dataModel.btcWalletService.isEncrypted()) {
|
||||
UserThread.runAfter(() -> model.dataModel.walletPasswordWindow.onAesKey(aesKey ->
|
||||
doWithdrawRequest(toAddress, amount, fee, aesKey, resultHandler, faultHandler))
|
||||
.show(), 300, TimeUnit.MILLISECONDS);
|
||||
} else
|
||||
doWithdrawRequest(toAddress, amount, fee, null, resultHandler, faultHandler);
|
||||
}
|
||||
|
||||
private void doWithdrawRequest(String toAddress,
|
||||
Coin amount,
|
||||
Coin fee,
|
||||
KeyParameter aesKey,
|
||||
ResultHandler resultHandler,
|
||||
FaultHandler faultHandler) {
|
||||
useSavingsWalletButton.setDisable(true);
|
||||
withdrawToExternalWalletButton.setDisable(true);
|
||||
String memo = withdrawMemoTextField.getText();
|
||||
if (memo.isEmpty()) {
|
||||
memo = null;
|
||||
}
|
||||
model.dataModel.onWithdrawRequest(toAddress,
|
||||
amount,
|
||||
fee,
|
||||
aesKey,
|
||||
memo,
|
||||
resultHandler,
|
||||
faultHandler);
|
||||
}
|
||||
|
||||
private void handleTradeCompleted() {
|
||||
useSavingsWalletButton.setDisable(true);
|
||||
withdrawToExternalWalletButton.setDisable(true);
|
||||
closeButton.setDisable(true);
|
||||
model.dataModel.btcWalletService.swapTradeEntryToAvailableEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT);
|
||||
|
||||
openTradeFeedbackWindow();
|
||||
|
@ -328,12 +170,6 @@ public class BuyerStep4View extends TradeStepView {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateWithdrawAddress() {
|
||||
withdrawAddressTextField.setValidator(model.btcAddressValidator);
|
||||
withdrawAddressTextField.requestFocus();
|
||||
useSavingsWalletButton.requestFocus();
|
||||
}
|
||||
|
||||
protected String getBtcTradeAmountLabel() {
|
||||
return Res.get("portfolio.pending.step5_buyer.bought");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue