mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Handle errors at take offer screen
This commit is contained in:
parent
9a0e174099
commit
e6744fb727
@ -21,13 +21,13 @@ import io.bitsquare.btc.AddressEntry;
|
|||||||
import io.bitsquare.btc.FeePolicy;
|
import io.bitsquare.btc.FeePolicy;
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.offer.Offer;
|
|
||||||
import io.bitsquare.persistence.Persistence;
|
|
||||||
import io.bitsquare.user.Preferences;
|
|
||||||
import io.bitsquare.trade.Trade;
|
|
||||||
import io.bitsquare.trade.TradeManager;
|
|
||||||
import io.bitsquare.common.viewfx.model.Activatable;
|
import io.bitsquare.common.viewfx.model.Activatable;
|
||||||
import io.bitsquare.common.viewfx.model.DataModel;
|
import io.bitsquare.common.viewfx.model.DataModel;
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.persistence.Persistence;
|
||||||
|
import io.bitsquare.trade.Trade;
|
||||||
|
import io.bitsquare.trade.TradeManager;
|
||||||
|
import io.bitsquare.user.Preferences;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.utils.ExchangeRate;
|
import org.bitcoinj.utils.ExchangeRate;
|
||||||
@ -63,11 +63,8 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
|||||||
private Offer offer;
|
private Offer offer;
|
||||||
private AddressEntry addressEntry;
|
private AddressEntry addressEntry;
|
||||||
|
|
||||||
final StringProperty requestTakeOfferErrorMessage = new SimpleStringProperty();
|
|
||||||
final StringProperty transactionId = new SimpleStringProperty();
|
|
||||||
final StringProperty btcCode = new SimpleStringProperty();
|
final StringProperty btcCode = new SimpleStringProperty();
|
||||||
|
|
||||||
final BooleanProperty requestTakeOfferSuccess = new SimpleBooleanProperty();
|
|
||||||
final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
|
final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
|
||||||
final BooleanProperty useMBTC = new SimpleBooleanProperty();
|
final BooleanProperty useMBTC = new SimpleBooleanProperty();
|
||||||
|
|
||||||
@ -78,8 +75,6 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
|||||||
final ObjectProperty<Coin> offerFeeAsCoin = new SimpleObjectProperty<>();
|
final ObjectProperty<Coin> offerFeeAsCoin = new SimpleObjectProperty<>();
|
||||||
final ObjectProperty<Coin> networkFeeAsCoin = new SimpleObjectProperty<>();
|
final ObjectProperty<Coin> networkFeeAsCoin = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
final ObjectProperty<Offer.State> offerIsAvailable = new SimpleObjectProperty<>(Offer.State.UNKNOWN);
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TakeOfferDataModel(TradeManager tradeManager,
|
public TakeOfferDataModel(TradeManager tradeManager,
|
||||||
WalletService walletService,
|
WalletService walletService,
|
||||||
@ -130,64 +125,11 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
|||||||
});
|
});
|
||||||
updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress()));
|
updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress()));
|
||||||
|
|
||||||
offer.stateProperty().addListener((observable, oldValue, newValue) -> {
|
|
||||||
offerIsAvailable.set(newValue);
|
|
||||||
});
|
|
||||||
tradeManager.checkOfferAvailability(offer);
|
tradeManager.checkOfferAvailability(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void takeOffer() {
|
Trade takeOffer() {
|
||||||
final Trade trade = tradeManager.takeOffer(amountAsCoin.get(), offer);
|
return tradeManager.takeOffer(amountAsCoin.get(), offer);
|
||||||
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
|
||||||
log.debug("trade state = " + newValue);
|
|
||||||
String errorMessage = "";
|
|
||||||
if (newValue.getErrorMessage() != null)
|
|
||||||
errorMessage = "\nError message: " + newValue.getErrorMessage();
|
|
||||||
|
|
||||||
switch (newValue) {
|
|
||||||
case OPEN:
|
|
||||||
break;
|
|
||||||
case OFFERER_ACCEPTED:
|
|
||||||
break;
|
|
||||||
case OFFERER_REJECTED:
|
|
||||||
requestTakeOfferErrorMessage.set("Take offer request got rejected. Maybe another trader has taken the offer in the meantime.");
|
|
||||||
break;
|
|
||||||
case TAKE_OFFER_FEE_TX_CREATED:
|
|
||||||
break;
|
|
||||||
case DEPOSIT_PUBLISHED:
|
|
||||||
case DEPOSIT_CONFIRMED:
|
|
||||||
// TODO Check why DEPOSIT_CONFIRMED can happen, refactor state handling
|
|
||||||
// TODO null pointer happened here!
|
|
||||||
if (trade.getDepositTx() != null) {
|
|
||||||
transactionId.set(trade.getDepositTx().getHashAsString());
|
|
||||||
requestTakeOfferSuccess.set(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.warn("trade.getDepositTx() = null. at trade state " + newValue +
|
|
||||||
" That should not happen and needs more investigation why it can happen.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FIAT_PAYMENT_STARTED:
|
|
||||||
break;
|
|
||||||
case TAKE_OFFER_FEE_PUBLISH_FAILED:
|
|
||||||
requestTakeOfferErrorMessage.set("An error occurred when paying the trade fee." + errorMessage);
|
|
||||||
break;
|
|
||||||
case MESSAGE_SENDING_FAILED:
|
|
||||||
requestTakeOfferErrorMessage.set("An error occurred when sending a message to the offerer. Maybe there are connection problems. " +
|
|
||||||
"Please try later again." + errorMessage);
|
|
||||||
break;
|
|
||||||
case PAYOUT_PUBLISHED:
|
|
||||||
break;
|
|
||||||
case FAULT:
|
|
||||||
requestTakeOfferErrorMessage.set(errorMessage);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.error("Unhandled trade state: " + newValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateVolume() {
|
void calculateVolume() {
|
||||||
|
@ -136,7 +136,7 @@
|
|||||||
</ProgressIndicator>
|
</ProgressIndicator>
|
||||||
<Button fx:id="showPaymentInfoScreenButton" text="%takeOffer.amountPriceBox.next" id="show-details-button"
|
<Button fx:id="showPaymentInfoScreenButton" text="%takeOffer.amountPriceBox.next" id="show-details-button"
|
||||||
GridPane.columnIndex="1" GridPane.rowIndex="3" defaultButton="true" visible="false"
|
GridPane.columnIndex="1" GridPane.rowIndex="3" defaultButton="true" visible="false"
|
||||||
onAction="#onShowPayFundsScreen">
|
onAction="#onShowPaymentScreen">
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets top="15.0"/>
|
<Insets top="15.0"/>
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
package io.bitsquare.gui.main.trade.takeoffer;
|
package io.bitsquare.gui.main.trade.takeoffer;
|
||||||
|
|
||||||
|
|
||||||
|
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
||||||
|
import io.bitsquare.common.viewfx.view.FxmlView;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.OverlayManager;
|
import io.bitsquare.gui.OverlayManager;
|
||||||
import io.bitsquare.gui.components.AddressTextField;
|
import io.bitsquare.gui.components.AddressTextField;
|
||||||
@ -36,8 +38,6 @@ import io.bitsquare.gui.util.ImageUtil;
|
|||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.offer.Direction;
|
import io.bitsquare.offer.Direction;
|
||||||
import io.bitsquare.offer.Offer;
|
import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
|
||||||
import io.bitsquare.common.viewfx.view.FxmlView;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
@ -47,7 +47,6 @@ import java.util.List;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
@ -95,7 +94,6 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
|
|
||||||
private final Navigation navigation;
|
private final Navigation navigation;
|
||||||
private final OverlayManager overlayManager;
|
private final OverlayManager overlayManager;
|
||||||
private ChangeListener<Offer.State> offerIsAvailableChangeListener;
|
|
||||||
private TradeView.CloseHandler closeHandler;
|
private TradeView.CloseHandler closeHandler;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -115,8 +113,6 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doDeactivate() {
|
protected void doDeactivate() {
|
||||||
if (offerIsAvailableChangeListener != null)
|
|
||||||
model.offerIsAvailable.removeListener(offerIsAvailableChangeListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initWithData(Direction direction, Coin amount, Offer offer) {
|
public void initWithData(Direction direction, Coin amount, Offer offer) {
|
||||||
@ -127,13 +123,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
else
|
else
|
||||||
imageView.setId("image-sell-large");
|
imageView.setId("image-sell-large");
|
||||||
|
|
||||||
priceDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.priceDescription",
|
priceDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.priceDescription", model.getFiatCode()));
|
||||||
model.getFiatCode()));
|
volumeDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.volumeDescription", model.getFiatCode()));
|
||||||
volumeDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.volumeDescription",
|
|
||||||
model.getFiatCode()));
|
|
||||||
|
|
||||||
balanceTextField.setup(model.getWalletService(), model.address.get(),
|
balanceTextField.setup(model.getWalletService(), model.address.get(), model.getFormatter());
|
||||||
model.getFormatter());
|
|
||||||
|
|
||||||
buyLabel.setText(model.getDirectionLabel());
|
buyLabel.setText(model.getDirectionLabel());
|
||||||
amountRangeTextField.setText(model.getAmountRange());
|
amountRangeTextField.setText(model.getAmountRange());
|
||||||
@ -148,113 +141,23 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
acceptedLanguagesTextField.setText(model.getAcceptedLanguages());
|
acceptedLanguagesTextField.setText(model.getAcceptedLanguages());
|
||||||
acceptedArbitratorsTextField.setText(model.getAcceptedArbitrators());
|
acceptedArbitratorsTextField.setText(model.getAcceptedArbitrators());
|
||||||
|
|
||||||
offerIsAvailableChangeListener = (ov, oldValue, newValue) -> handleOfferIsAvailableState(newValue);
|
showCheckAvailabilityScreen();
|
||||||
model.offerIsAvailable.addListener(offerIsAvailableChangeListener);
|
|
||||||
handleOfferIsAvailableState(model.offerIsAvailable.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCloseHandler(TradeView.CloseHandler closeHandler) {
|
public void setCloseHandler(TradeView.CloseHandler closeHandler) {
|
||||||
this.closeHandler = closeHandler;
|
this.closeHandler = closeHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleOfferIsAvailableState(Offer.State state) {
|
|
||||||
switch (state) {
|
|
||||||
case UNKNOWN:
|
|
||||||
break;
|
|
||||||
case AVAILABLE:
|
|
||||||
isOfferAvailableLabel.setVisible(false);
|
|
||||||
isOfferAvailableLabel.setManaged(false);
|
|
||||||
isOfferAvailableProgressIndicator.setProgress(0);
|
|
||||||
isOfferAvailableProgressIndicator.setVisible(false);
|
|
||||||
isOfferAvailableProgressIndicator.setManaged(false);
|
|
||||||
|
|
||||||
// In case of returning to a canceled or failed take offer request and if trade wallet is sufficient funded we display directly the payment
|
|
||||||
// screen
|
|
||||||
if (!model.isTakeOfferButtonDisabled.get()) {
|
|
||||||
showPayFundsScreen();
|
|
||||||
showPaymentInfoScreenButton.setVisible(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
showPaymentInfoScreenButton.setVisible(true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OFFERER_OFFLINE:
|
|
||||||
Popups.openWarningPopup("You cannot take that offer", "The offerer is offline.");
|
|
||||||
Platform.runLater(this::close);
|
|
||||||
break;
|
|
||||||
case NOT_AVAILABLE:
|
|
||||||
Popups.openWarningPopup("You cannot take that offer", "The offer was already taken by another trader.");
|
|
||||||
Platform.runLater(this::close);
|
|
||||||
break;
|
|
||||||
case FAULT:
|
|
||||||
Popups.openWarningPopup("You cannot take that offer", "The check for the offer availability failed.");
|
|
||||||
Platform.runLater(this::close);
|
|
||||||
break;
|
|
||||||
case REMOVED:
|
|
||||||
Popups.openWarningPopup("You cannot take that offer", "The offerer has been removed in the meantime.");
|
|
||||||
Platform.runLater(this::close);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void onTakeOffer() {
|
void onTakeOffer() {
|
||||||
model.takeOffer();
|
model.takeOffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void onShowPayFundsScreen() {
|
void onShowPaymentScreen() {
|
||||||
showPayFundsScreen();
|
model.onShowPaymentScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPayFundsScreen() {
|
|
||||||
// TODO deactivate for testing the moment
|
|
||||||
/* if (model.displaySecurityDepositInfo()) {
|
|
||||||
overlayManager.blurContent();
|
|
||||||
List<Action> actions = new ArrayList<>();
|
|
||||||
actions.add(new AbstractAction(BSResources.get("shared.close")) {
|
|
||||||
@Override
|
|
||||||
public void handle(ActionEvent actionEvent) {
|
|
||||||
getProperties().put("type", "CLOSE");
|
|
||||||
Dialog.Actions.CLOSE.handle(actionEvent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Popups.openInfoPopup("To ensure that both traders behave fair they need to pay a security deposit.",
|
|
||||||
"The deposit will stay in your local trading wallet until the offer gets accepted by another trader. " +
|
|
||||||
"\nIt will be refunded to you after the trade has successfully completed.",
|
|
||||||
actions);
|
|
||||||
|
|
||||||
model.securityDepositInfoDisplayed();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
priceAmountPane.setInactive();
|
|
||||||
|
|
||||||
showPaymentInfoScreenButton.setVisible(false);
|
|
||||||
|
|
||||||
payFundsPane.setVisible(true);
|
|
||||||
totalToPayLabel.setVisible(true);
|
|
||||||
totalToPayInfoIconLabel.setVisible(true);
|
|
||||||
totalToPayTextField.setVisible(true);
|
|
||||||
addressLabel.setVisible(true);
|
|
||||||
addressTextField.setVisible(true);
|
|
||||||
balanceLabel.setVisible(true);
|
|
||||||
balanceTextField.setVisible(true);
|
|
||||||
fundsBoxInfoDisplay.setVisible(true);
|
|
||||||
|
|
||||||
// for irc demo
|
|
||||||
//showAdvancedSettingsButton.setVisible(true);
|
|
||||||
showAdvancedSettingsButton.setManaged(false);
|
|
||||||
|
|
||||||
if (expand == null) {
|
|
||||||
expand = ImageUtil.getImageViewById(ImageUtil.EXPAND);
|
|
||||||
collapse = ImageUtil.getImageViewById(ImageUtil.COLLAPSE);
|
|
||||||
}
|
|
||||||
showAdvancedSettingsButton.setGraphic(expand);
|
|
||||||
|
|
||||||
setupTotalToPayInfoIconLabel();
|
|
||||||
|
|
||||||
model.onShowPayFundsScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void onToggleShowAdvancedSettings() {
|
void onToggleShowAdvancedSettings() {
|
||||||
@ -300,6 +203,23 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
amountTextField.setText(model.amount.get());
|
amountTextField.setText(model.amount.get());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
model.state.addListener((ov, oldValue, newValue) -> {
|
||||||
|
switch (newValue) {
|
||||||
|
case CHECK_AVAILABILITY:
|
||||||
|
showCheckAvailabilityScreen();
|
||||||
|
break;
|
||||||
|
case AMOUNT_SCREEN:
|
||||||
|
showAmountScreen();
|
||||||
|
break;
|
||||||
|
case PAYMENT_SCREEN:
|
||||||
|
setupPaymentScreen();
|
||||||
|
break;
|
||||||
|
case DETAILS_SCREEN:
|
||||||
|
showDetailsScreen();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// warnings
|
// warnings
|
||||||
model.showWarningInvalidBtcDecimalPlaces.addListener((o, oldValue, newValue) -> {
|
model.showWarningInvalidBtcDecimalPlaces.addListener((o, oldValue, newValue) -> {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
@ -309,12 +229,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
model.requestTakeOfferErrorMessage.addListener((o, oldValue, newValue) -> {
|
|
||||||
|
model.errorMessage.addListener((o, oldValue, newValue) -> {
|
||||||
if (newValue != null) {
|
if (newValue != null) {
|
||||||
Popups.openErrorPopup(BSResources.get("shared.error"),
|
Popups.openErrorPopup(BSResources.get("shared.error"), BSResources.get("takeOffer.error.message", model.errorMessage.get()));
|
||||||
BSResources.get("takeOffer.amountPriceBox.error.message",
|
|
||||||
model.requestTakeOfferErrorMessage.get()));
|
|
||||||
Popups.removeBlurContent();
|
Popups.removeBlurContent();
|
||||||
|
Platform.runLater(this::close);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -364,8 +284,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
amountTextField.validationResultProperty().bind(model.amountValidationResult);
|
amountTextField.validationResultProperty().bind(model.amountValidationResult);
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
takeOfferButton.visibleProperty().bind(model.isTakeOfferButtonVisible);
|
takeOfferButton.disableProperty().bind(model.takeOfferButtonDisabled);
|
||||||
takeOfferButton.disableProperty().bind(model.isTakeOfferButtonDisabled);
|
|
||||||
|
|
||||||
takeOfferSpinnerInfoLabel.visibleProperty().bind(model.isTakeOfferSpinnerVisible);
|
takeOfferSpinnerInfoLabel.visibleProperty().bind(model.isTakeOfferSpinnerVisible);
|
||||||
|
|
||||||
@ -375,6 +294,68 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void showCheckAvailabilityScreen() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showAmountScreen() {
|
||||||
|
isOfferAvailableLabel.setVisible(false);
|
||||||
|
isOfferAvailableLabel.setManaged(false);
|
||||||
|
isOfferAvailableProgressIndicator.setProgress(0);
|
||||||
|
isOfferAvailableProgressIndicator.setVisible(false);
|
||||||
|
isOfferAvailableProgressIndicator.setManaged(false);
|
||||||
|
|
||||||
|
showPaymentInfoScreenButton.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupPaymentScreen() {
|
||||||
|
// TODO deactivate for testing the moment
|
||||||
|
/* if (model.displaySecurityDepositInfo()) {
|
||||||
|
overlayManager.blurContent();
|
||||||
|
List<Action> actions = new ArrayList<>();
|
||||||
|
actions.add(new AbstractAction(BSResources.get("shared.close")) {
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent actionEvent) {
|
||||||
|
getProperties().put("type", "CLOSE");
|
||||||
|
Dialog.Actions.CLOSE.handle(actionEvent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Popups.openInfoPopup("To ensure that both traders behave fair they need to pay a security deposit.",
|
||||||
|
"The deposit will stay in your local trading wallet until the offer gets accepted by another trader. " +
|
||||||
|
"\nIt will be refunded to you after the trade has successfully completed.",
|
||||||
|
actions);
|
||||||
|
|
||||||
|
model.securityDepositInfoDisplayed();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
priceAmountPane.setInactive();
|
||||||
|
takeOfferButton.setVisible(true);
|
||||||
|
showPaymentInfoScreenButton.setVisible(false);
|
||||||
|
|
||||||
|
payFundsPane.setVisible(true);
|
||||||
|
totalToPayLabel.setVisible(true);
|
||||||
|
totalToPayInfoIconLabel.setVisible(true);
|
||||||
|
totalToPayTextField.setVisible(true);
|
||||||
|
addressLabel.setVisible(true);
|
||||||
|
addressTextField.setVisible(true);
|
||||||
|
balanceLabel.setVisible(true);
|
||||||
|
balanceTextField.setVisible(true);
|
||||||
|
fundsBoxInfoDisplay.setVisible(true);
|
||||||
|
|
||||||
|
// for irc demo
|
||||||
|
//showAdvancedSettingsButton.setVisible(true);
|
||||||
|
showAdvancedSettingsButton.setManaged(false);
|
||||||
|
|
||||||
|
if (expand == null) {
|
||||||
|
expand = ImageUtil.getImageViewById(ImageUtil.EXPAND);
|
||||||
|
collapse = ImageUtil.getImageViewById(ImageUtil.COLLAPSE);
|
||||||
|
}
|
||||||
|
showAdvancedSettingsButton.setGraphic(expand);
|
||||||
|
|
||||||
|
setupTotalToPayInfoIconLabel();
|
||||||
|
}
|
||||||
|
|
||||||
private void showDetailsScreen() {
|
private void showDetailsScreen() {
|
||||||
payFundsPane.setInactive();
|
payFundsPane.setInactive();
|
||||||
|
|
||||||
@ -386,6 +367,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||||||
toggleDetailsScreen(true);
|
toggleDetailsScreen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void hideDetailsScreen() {
|
private void hideDetailsScreen() {
|
||||||
payFundsPane.setActive();
|
payFundsPane.setActive();
|
||||||
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
||||||
|
@ -18,14 +18,15 @@
|
|||||||
package io.bitsquare.gui.main.trade.takeoffer;
|
package io.bitsquare.gui.main.trade.takeoffer;
|
||||||
|
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
|
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
|
||||||
|
import io.bitsquare.common.viewfx.model.ViewModel;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.gui.util.validation.BtcValidator;
|
import io.bitsquare.gui.util.validation.BtcValidator;
|
||||||
import io.bitsquare.gui.util.validation.InputValidator;
|
import io.bitsquare.gui.util.validation.InputValidator;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.offer.Direction;
|
import io.bitsquare.offer.Direction;
|
||||||
import io.bitsquare.offer.Offer;
|
import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.common.viewfx.model.ViewModel;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Address;
|
import org.bitcoinj.core.Address;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
@ -47,6 +48,13 @@ import static javafx.beans.binding.Bindings.createStringBinding;
|
|||||||
class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> implements ViewModel {
|
class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> implements ViewModel {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TakeOfferViewModel.class);
|
private static final Logger log = LoggerFactory.getLogger(TakeOfferViewModel.class);
|
||||||
|
|
||||||
|
public static enum State {
|
||||||
|
CHECK_AVAILABILITY,
|
||||||
|
AMOUNT_SCREEN,
|
||||||
|
PAYMENT_SCREEN,
|
||||||
|
DETAILS_SCREEN
|
||||||
|
}
|
||||||
|
|
||||||
private String fiatCode;
|
private String fiatCode;
|
||||||
private String amountRange;
|
private String amountRange;
|
||||||
private String price;
|
private String price;
|
||||||
@ -62,6 +70,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
|
|
||||||
// Needed for the addressTextField
|
// Needed for the addressTextField
|
||||||
final ObjectProperty<Address> address = new SimpleObjectProperty<>();
|
final ObjectProperty<Address> address = new SimpleObjectProperty<>();
|
||||||
|
final ObjectProperty<State> state = new SimpleObjectProperty<>(State.CHECK_AVAILABILITY);
|
||||||
|
|
||||||
private final BtcValidator btcValidator;
|
private final BtcValidator btcValidator;
|
||||||
private final BSFormatter formatter;
|
private final BSFormatter formatter;
|
||||||
@ -75,22 +84,21 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
final StringProperty securityDeposit = new SimpleStringProperty();
|
final StringProperty securityDeposit = new SimpleStringProperty();
|
||||||
final StringProperty totalToPay = new SimpleStringProperty();
|
final StringProperty totalToPay = new SimpleStringProperty();
|
||||||
final StringProperty transactionId = new SimpleStringProperty();
|
final StringProperty transactionId = new SimpleStringProperty();
|
||||||
final StringProperty requestTakeOfferErrorMessage = new SimpleStringProperty();
|
final StringProperty errorMessage = new SimpleStringProperty();
|
||||||
final StringProperty btcCode = new SimpleStringProperty();
|
final StringProperty btcCode = new SimpleStringProperty();
|
||||||
|
|
||||||
|
|
||||||
final BooleanProperty isTakeOfferButtonVisible = new SimpleBooleanProperty(false);
|
final BooleanProperty takeOfferButtonDisabled = new SimpleBooleanProperty(false);
|
||||||
final BooleanProperty isTakeOfferButtonDisabled = new SimpleBooleanProperty(true);
|
|
||||||
final BooleanProperty isTakeOfferSpinnerVisible = new SimpleBooleanProperty(false);
|
final BooleanProperty isTakeOfferSpinnerVisible = new SimpleBooleanProperty(false);
|
||||||
final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
|
final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
|
||||||
final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
|
final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
|
||||||
final ObjectProperty<Offer.State> offerIsAvailable = new SimpleObjectProperty<>(Offer.State.UNKNOWN);
|
|
||||||
|
|
||||||
final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>();
|
final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
// Needed for the addressTextField
|
// Needed for the addressTextField
|
||||||
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
||||||
|
private boolean takeOfferRequested;
|
||||||
|
private boolean isAmountAndPriceValidAndWalletFunded;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TakeOfferViewModel(TakeOfferDataModel dataModel, BtcValidator btcValidator, BSFormatter formatter) {
|
public TakeOfferViewModel(TakeOfferDataModel dataModel, BtcValidator btcValidator, BSFormatter formatter) {
|
||||||
@ -104,6 +112,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
|
|
||||||
setupBindings();
|
setupBindings();
|
||||||
setupListeners();
|
setupListeners();
|
||||||
|
applyTakeOfferRequestResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setOfferBookFilter is a one time call
|
// setOfferBookFilter is a one time call
|
||||||
@ -119,8 +128,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
BSResources.get("takeOffer.validation.amountSmallerThanMinAmount")));
|
BSResources.get("takeOffer.validation.amountSmallerThanMinAmount")));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtonDisableState();
|
|
||||||
|
|
||||||
//model.volumeAsFiat.set(offer.getVolumeByAmount(model.amountAsCoin.get()));
|
//model.volumeAsFiat.set(offer.getVolumeByAmount(model.amountAsCoin.get()));
|
||||||
|
|
||||||
amountRange = formatter.formatCoinWithCode(offer.getMinAmount()) + " - " +
|
amountRange = formatter.formatCoinWithCode(offer.getMinAmount()) + " - " +
|
||||||
@ -139,16 +146,120 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
bankAccountType = BSResources.get(offer.getFiatAccountType().toString());
|
bankAccountType = BSResources.get(offer.getFiatAccountType().toString());
|
||||||
bankAccountCurrency = BSResources.get(offer.getCurrency().getDisplayName());
|
bankAccountCurrency = BSResources.get(offer.getCurrency().getDisplayName());
|
||||||
bankAccountCounty = BSResources.get(offer.getBankAccountCountry().getName());
|
bankAccountCounty = BSResources.get(offer.getBankAccountCountry().getName());
|
||||||
|
|
||||||
|
offer.stateProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
|
log.debug("offer state = " + newValue);
|
||||||
|
|
||||||
|
switch (newValue) {
|
||||||
|
case UNKNOWN:
|
||||||
|
break;
|
||||||
|
case AVAILABLE:
|
||||||
|
state.set(State.AMOUNT_SCREEN);
|
||||||
|
break;
|
||||||
|
case OFFERER_OFFLINE:
|
||||||
|
if (takeOfferRequested)
|
||||||
|
errorMessage.set("Take offer request failed because offerer is not online anymore.");
|
||||||
|
else
|
||||||
|
errorMessage.set("You cannot take that offer because the offerer is offline.");
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case NOT_AVAILABLE:
|
||||||
|
if (takeOfferRequested)
|
||||||
|
errorMessage.set("Take offer request failed because offer is not available anymore. " +
|
||||||
|
"Maybe another trader has taken the offer in the meantime.");
|
||||||
|
else
|
||||||
|
errorMessage.set("You cannot take that offer because the offer was already taken by another trader.");
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case FAULT:
|
||||||
|
if (takeOfferRequested)
|
||||||
|
errorMessage.set("Take offer request failed.");
|
||||||
|
else
|
||||||
|
errorMessage.set("The check for the offer availability failed.");
|
||||||
|
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case REMOVED:
|
||||||
|
if (!takeOfferRequested)
|
||||||
|
errorMessage.set("You cannot take that offer because the offer has been removed in the meantime.");
|
||||||
|
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.error("Unhandled offer state: " + newValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage.get() != null) {
|
||||||
|
isTakeOfferSpinnerVisible.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluateState();
|
||||||
|
});
|
||||||
|
|
||||||
|
evaluateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void takeOffer() {
|
void takeOffer() {
|
||||||
dataModel.requestTakeOfferErrorMessage.set(null);
|
errorMessage.set(null);
|
||||||
dataModel.requestTakeOfferSuccess.set(false);
|
takeOfferRequested = true;
|
||||||
|
applyTakeOfferRequestResult(false);
|
||||||
|
|
||||||
isTakeOfferButtonDisabled.set(true);
|
|
||||||
isTakeOfferSpinnerVisible.set(true);
|
isTakeOfferSpinnerVisible.set(true);
|
||||||
|
|
||||||
dataModel.takeOffer();
|
Trade trade = dataModel.takeOffer();
|
||||||
|
|
||||||
|
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
|
log.debug("trade state = " + newValue);
|
||||||
|
String msg = "";
|
||||||
|
if (newValue.getErrorMessage() != null)
|
||||||
|
msg = "\nError message: " + newValue.getErrorMessage();
|
||||||
|
|
||||||
|
switch (newValue) {
|
||||||
|
case OPEN:
|
||||||
|
break;
|
||||||
|
case OFFERER_ACCEPTED:
|
||||||
|
break;
|
||||||
|
case OFFERER_REJECTED:
|
||||||
|
errorMessage.set("Your take offer request got rejected. Maybe another trader has taken the offer in the meantime.");
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case TAKE_OFFER_FEE_TX_CREATED:
|
||||||
|
break;
|
||||||
|
case DEPOSIT_PUBLISHED:
|
||||||
|
case DEPOSIT_CONFIRMED:
|
||||||
|
transactionId.set(trade.getDepositTx().getHashAsString());
|
||||||
|
applyTakeOfferRequestResult(true);
|
||||||
|
break;
|
||||||
|
case FIAT_PAYMENT_STARTED:
|
||||||
|
break;
|
||||||
|
case TAKE_OFFER_FEE_PUBLISH_FAILED:
|
||||||
|
errorMessage.set("An error occurred when paying the trade fee." + msg);
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case MESSAGE_SENDING_FAILED:
|
||||||
|
errorMessage.set("An error occurred when sending a message to the offerer. Maybe there are connection problems. " +
|
||||||
|
"Please try later again." + msg);
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case PAYOUT_PUBLISHED:
|
||||||
|
break;
|
||||||
|
case FAULT:
|
||||||
|
errorMessage.set(msg);
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.error("Unhandled trade state: " + newValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage.get() != null) {
|
||||||
|
isAmountAndPriceValidAndWalletFunded = false;
|
||||||
|
isTakeOfferSpinnerVisible.set(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
evaluateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void securityDepositInfoDisplayed() {
|
void securityDepositInfoDisplayed() {
|
||||||
@ -156,8 +267,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void onShowPayFundsScreen() {
|
void onShowPaymentScreen() {
|
||||||
isTakeOfferButtonVisible.set(true);
|
state.set(State.PAYMENT_SCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On focus out we do validation and apply the data to the model
|
// On focus out we do validation and apply the data to the model
|
||||||
@ -268,26 +379,20 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
calculateVolume();
|
calculateVolume();
|
||||||
dataModel.calculateTotalToPay();
|
dataModel.calculateTotalToPay();
|
||||||
}
|
}
|
||||||
updateButtonDisableState();
|
evaluateState();
|
||||||
});
|
});
|
||||||
|
|
||||||
dataModel.isWalletFunded.addListener((ov, oldValue, newValue) -> {
|
dataModel.isWalletFunded.addListener((ov, oldValue, newValue) -> {
|
||||||
updateButtonDisableState();
|
evaluateState();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
|
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
|
||||||
dataModel.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue)));
|
dataModel.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue)));
|
||||||
|
|
||||||
dataModel.requestTakeOfferErrorMessage.addListener((ov, oldValue, newValue) -> {
|
|
||||||
if (newValue != null) {
|
|
||||||
isTakeOfferButtonDisabled.set(false);
|
|
||||||
isTakeOfferSpinnerVisible.set(false);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
dataModel.requestTakeOfferSuccess.addListener((ov, oldValue, newValue) -> {
|
private void applyTakeOfferRequestResult(boolean success) {
|
||||||
isTakeOfferButtonVisible.set(!newValue);
|
|
||||||
isTakeOfferSpinnerVisible.set(false);
|
isTakeOfferSpinnerVisible.set(false);
|
||||||
});
|
showTransactionPublishedScreen.set(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupBindings() {
|
private void setupBindings() {
|
||||||
@ -301,11 +406,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
|
|
||||||
totalToPayAsCoin.bind(dataModel.totalToPayAsCoin);
|
totalToPayAsCoin.bind(dataModel.totalToPayAsCoin);
|
||||||
|
|
||||||
requestTakeOfferErrorMessage.bind(dataModel.requestTakeOfferErrorMessage);
|
|
||||||
showTransactionPublishedScreen.bind(dataModel.requestTakeOfferSuccess);
|
|
||||||
transactionId.bind(dataModel.transactionId);
|
|
||||||
offerIsAvailable.bind(dataModel.offerIsAvailable);
|
|
||||||
|
|
||||||
btcCode.bind(dataModel.btcCode);
|
btcCode.bind(dataModel.btcCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,12 +418,16 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
dataModel.amountAsCoin.set(formatter.parseToCoinWith4Decimals(amount.get()));
|
dataModel.amountAsCoin.set(formatter.parseToCoinWith4Decimals(amount.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateButtonDisableState() {
|
private void evaluateState() {
|
||||||
isTakeOfferButtonDisabled.set(!(isBtcInputValid(amount.get()).isValid &&
|
isAmountAndPriceValidAndWalletFunded = isBtcInputValid(amount.get()).isValid &&
|
||||||
dataModel.isMinAmountLessOrEqualAmount() &&
|
dataModel.isMinAmountLessOrEqualAmount() &&
|
||||||
!dataModel.isAmountLargerThanOfferAmount() &&
|
!dataModel.isAmountLargerThanOfferAmount() &&
|
||||||
dataModel.isWalletFunded.get())
|
dataModel.isWalletFunded.get();
|
||||||
);
|
|
||||||
|
if (isAmountAndPriceValidAndWalletFunded && state.get() != State.CHECK_AVAILABILITY)
|
||||||
|
state.set(State.PAYMENT_SCREEN);
|
||||||
|
|
||||||
|
takeOfferButtonDisabled.set(!isAmountAndPriceValidAndWalletFunded || takeOfferRequested);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputValidator.ValidationResult isBtcInputValid(String input) {
|
private InputValidator.ValidationResult isBtcInputValid(String input) {
|
||||||
|
@ -103,6 +103,7 @@ public class Transitions {
|
|||||||
if (removeBlurTimeLine != null)
|
if (removeBlurTimeLine != null)
|
||||||
removeBlurTimeLine.stop();
|
removeBlurTimeLine.stop();
|
||||||
|
|
||||||
|
node.setMouseTransparent(true);
|
||||||
GaussianBlur blur = new GaussianBlur(0.0);
|
GaussianBlur blur = new GaussianBlur(0.0);
|
||||||
Timeline timeline = new Timeline();
|
Timeline timeline = new Timeline();
|
||||||
KeyValue kv1 = new KeyValue(blur.radiusProperty(), 15.0);
|
KeyValue kv1 = new KeyValue(blur.radiusProperty(), 15.0);
|
||||||
@ -134,6 +135,7 @@ public class Transitions {
|
|||||||
public void removeBlur(Node node, int duration, boolean useDarken) {
|
public void removeBlur(Node node, int duration, boolean useDarken) {
|
||||||
if (preferences.getUseEffects()) {
|
if (preferences.getUseEffects()) {
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
node.setMouseTransparent(false);
|
||||||
GaussianBlur blur = (GaussianBlur) node.getEffect();
|
GaussianBlur blur = (GaussianBlur) node.getEffect();
|
||||||
if (blur != null) {
|
if (blur != null) {
|
||||||
removeBlurTimeLine = new Timeline();
|
removeBlurTimeLine = new Timeline();
|
||||||
|
@ -55,7 +55,17 @@ public class Offer implements Serializable {
|
|||||||
AVAILABLE,
|
AVAILABLE,
|
||||||
NOT_AVAILABLE,
|
NOT_AVAILABLE,
|
||||||
FAULT,
|
FAULT,
|
||||||
REMOVED
|
REMOVED;
|
||||||
|
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
public void setErrorMessage(String errorMessage) {
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// key attributes for lookup
|
// key attributes for lookup
|
||||||
|
@ -17,15 +17,14 @@
|
|||||||
|
|
||||||
package io.bitsquare.trade.protocol.availability;
|
package io.bitsquare.trade.protocol.availability;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.network.Message;
|
import io.bitsquare.network.Message;
|
||||||
import io.bitsquare.network.Peer;
|
import io.bitsquare.network.Peer;
|
||||||
import io.bitsquare.offer.Offer;
|
|
||||||
import io.bitsquare.trade.handlers.MessageHandler;
|
import io.bitsquare.trade.handlers.MessageHandler;
|
||||||
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
|
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
|
||||||
import io.bitsquare.trade.protocol.availability.tasks.GetPeerAddress;
|
import io.bitsquare.trade.protocol.availability.tasks.GetPeerAddress;
|
||||||
import io.bitsquare.trade.protocol.availability.tasks.ProcessReportOfferAvailabilityMessage;
|
import io.bitsquare.trade.protocol.availability.tasks.ProcessReportOfferAvailabilityMessage;
|
||||||
import io.bitsquare.trade.protocol.availability.tasks.RequestIsOfferAvailable;
|
import io.bitsquare.trade.protocol.availability.tasks.RequestIsOfferAvailable;
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
|
||||||
@ -82,7 +81,6 @@ public class CheckOfferAvailabilityProtocol {
|
|||||||
public void cancel() {
|
public void cancel() {
|
||||||
isCanceled = true;
|
isCanceled = true;
|
||||||
taskRunner.cancel();
|
taskRunner.cancel();
|
||||||
model.getOffer().setState(Offer.State.UNKNOWN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker;
|
|||||||
|
|
||||||
import io.bitsquare.network.Message;
|
import io.bitsquare.network.Message;
|
||||||
import io.bitsquare.network.Peer;
|
import io.bitsquare.network.Peer;
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.handlers.MessageHandler;
|
import io.bitsquare.trade.handlers.MessageHandler;
|
||||||
import io.bitsquare.trade.protocol.trade.TradeMessage;
|
import io.bitsquare.trade.protocol.trade.TradeMessage;
|
||||||
@ -43,6 +44,11 @@ import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitDepositTx;
|
|||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignsDepositTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignsDepositTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
||||||
|
import io.bitsquare.util.Utilities;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import javafx.animation.AnimationTimer;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -51,9 +57,11 @@ import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
|||||||
|
|
||||||
public class SellerAsTakerProtocol {
|
public class SellerAsTakerProtocol {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerProtocol.class);
|
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerProtocol.class);
|
||||||
|
public static final int TIMEOUT_DELAY = 10000;
|
||||||
|
|
||||||
private final SellerAsTakerModel model;
|
private final SellerAsTakerModel model;
|
||||||
private final MessageHandler messageHandler;
|
private final MessageHandler messageHandler;
|
||||||
|
private AnimationTimer timeoutTimer;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -78,7 +86,15 @@ public class SellerAsTakerProtocol {
|
|||||||
|
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleRequestTakeOfferUIEvent completed");
|
log.debug("taskRunner at takeOffer completed");
|
||||||
|
|
||||||
|
startTimeout(animationTimer -> {
|
||||||
|
Offer.State offerState = Offer.State.FAULT;
|
||||||
|
offerState.setErrorMessage("We did not get any reply for the take offer request. " +
|
||||||
|
"Seems that there are connection problems to your peer.");
|
||||||
|
model.getOffer().setState(Offer.State.FAULT);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
(errorMessage) -> {
|
(errorMessage) -> {
|
||||||
log.error(errorMessage);
|
log.error(errorMessage);
|
||||||
@ -97,6 +113,8 @@ public class SellerAsTakerProtocol {
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void handleRespondToTakeOfferRequestMessage(RespondToTakeOfferRequestMessage tradeMessage) {
|
private void handleRespondToTakeOfferRequestMessage(RespondToTakeOfferRequestMessage tradeMessage) {
|
||||||
|
stopTimeout();
|
||||||
|
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
||||||
@ -223,4 +241,23 @@ public class SellerAsTakerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Timeout
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void startTimeout(Function<AnimationTimer, Void> callback) {
|
||||||
|
stopTimeout();
|
||||||
|
timeoutTimer = Utilities.setTimeout(TIMEOUT_DELAY, callback);
|
||||||
|
timeoutTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopTimeout() {
|
||||||
|
if (timeoutTimer != null) {
|
||||||
|
timeoutTimer.stop();
|
||||||
|
timeoutTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,6 @@ takeOffer.amountPriceBox.amountRangeDescription=Possible amount range
|
|||||||
takeOffer.amountPriceBox.info=Enter the amount of Bitcoin you want to sell. You can choose an amount between the minimum amount and the amount.
|
takeOffer.amountPriceBox.info=Enter the amount of Bitcoin you want to sell. You can choose an amount between the minimum amount and the amount.
|
||||||
takeOffer.amountPriceBox.next=Next step
|
takeOffer.amountPriceBox.next=Next step
|
||||||
takeOffer.amountPriceBox.warning.invalidBtcDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places.\nThe amount has been adjusted to 4 decimal places.
|
takeOffer.amountPriceBox.warning.invalidBtcDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places.\nThe amount has been adjusted to 4 decimal places.
|
||||||
takeOffer.amountPriceBox.error.message=An error occurred when taking the offer:\n\n {0}
|
|
||||||
takeOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount defined in the offer.
|
takeOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount defined in the offer.
|
||||||
takeOffer.validation.amountLargerThanOfferAmount=Input amount cannot be higher than the amount defined in the offer.
|
takeOffer.validation.amountLargerThanOfferAmount=Input amount cannot be higher than the amount defined in the offer.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user