Fix missing spinner and incorrect error handling at take offer

This commit is contained in:
Manfred Karrer 2016-03-04 03:01:58 +01:00
parent 32066b15a7
commit 2b3387d385
10 changed files with 110 additions and 62 deletions

View File

@ -63,7 +63,7 @@ public class Log {
logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
//TODO for now use always trace
logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.INFO);
logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.TRACE);
// logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.DEBUG);
logbackLogger.addAppender(appender);
}

View File

@ -246,7 +246,6 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
}
private void onShowFundsScreen() {
model.onShowFundsScreen();
amountTextField.setMouseTransparent(true);
minAmountTextField.setMouseTransparent(true);
priceTextField.setMouseTransparent(true);
@ -729,8 +728,6 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
placeOfferButton.setPadding(new Insets(0, 20, 0, 20));
spinner = placeOfferTuple.second;
spinner.setProgress(0);
//spinner.setPrefSize(18, 18);
spinnerInfoLabel = placeOfferTuple.third;
cancelButton2 = addButton(gridPane, ++gridRow, BSResources.get("shared.cancel"));

View File

@ -65,7 +65,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
final StringProperty errorMessage = new SimpleStringProperty();
final StringProperty btcCode = new SimpleStringProperty();
final StringProperty tradeCurrencyCode = new SimpleStringProperty();
final StringProperty spinnerInfoText = new SimpleStringProperty("Waiting for funds...");
final StringProperty spinnerInfoText = new SimpleStringProperty("");
final BooleanProperty isPlaceOfferButtonDisabled = new SimpleBooleanProperty(true);
final BooleanProperty cancelButtonDisabled = new SimpleBooleanProperty();
@ -154,6 +154,14 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
directionLabel = BSResources.get("shared.sellBitcoin");
amountDescription = BSResources.get("createOffer.amountPriceBox.amountDescription", BSResources.get("shared.sell"));
}
if (dataModel.isWalletFunded.get()) {
isSpinnerVisible.set(false);
spinnerInfoText.set("");
} else {
spinnerInfoText.set("Waiting for funds...");
isSpinnerVisible.set(true);
}
}
@Override
@ -271,7 +279,6 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
dataModel.feeFromFundingTxProperty.addListener(feeFromFundingTxListener);
dataModel.isWalletFunded.addListener(isWalletFundedListener);
errorMessage.addListener(requestPlaceOfferErrorMessageListener);
}
private void removeListeners() {
@ -363,9 +370,6 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
dataModel.onCurrencySelected(tradeCurrency);
}
public void onShowFundsScreen() {
isSpinnerVisible.set(true);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Handle focus

View File

@ -79,14 +79,14 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private ImageView imageView;
private AddressTextField addressTextField;
private BalanceTextField balanceTextField;
private ProgressIndicator takeOfferSpinner, offerAvailabilitySpinner;
private ProgressIndicator spinner, offerAvailabilitySpinner;
private TitledGroupBg payFundsPane;
private Button nextButton, takeOfferButton, cancelButton1, cancelButton2;
private InputTextField amountTextField;
private TextField paymentMethodTextField, currencyTextField, priceTextField, volumeTextField, amountRangeTextField;
private Label directionLabel, amountDescriptionLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel,
amountBtcLabel, priceCurrencyLabel,
volumeCurrencyLabel, amountRangeBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, takeOfferSpinnerLabel, offerAvailabilitySpinnerLabel;
volumeCurrencyLabel, amountRangeBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, spinnerInfoLabel, offerAvailabilitySpinnerLabel;
private TextFieldWithCopyIcon totalToPayTextField;
private PopOver totalToPayInfoPopover;
private OfferView.CloseHandler closeHandler;
@ -97,11 +97,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private Label paymentMethodLabel;
private Subscription offerWarningSubscription;
private Subscription errorMessageSubscription, isOfferAvailableSubscription;
private Subscription isTakeOfferSpinnerVisibleSubscription;
private Subscription isSpinnerVisibleSubscription;
private Subscription showWarningInvalidBtcDecimalPlacesSubscription;
private Subscription showTransactionPublishedScreenSubscription;
private SimpleBooleanProperty errorPopupDisplayed;
private ChangeListener<Coin> feeFromFundingTxListener;
private boolean offerDetailsWindowDisplayed;
///////////////////////////////////////////////////////////////////////////////////////////
@ -146,7 +147,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addressTextField.amountAsCoinProperty().bind(model.totalToPayAsCoin);
amountTextField.validationResultProperty().bind(model.amountValidationResult);
takeOfferButton.disableProperty().bind(model.isTakeOfferButtonDisabled);
takeOfferSpinnerLabel.visibleProperty().bind(model.isTakeOfferSpinnerVisible);
spinner.visibleProperty().bind(model.isSpinnerVisible);
spinnerInfoLabel.visibleProperty().bind(model.isSpinnerVisible);
spinnerInfoLabel.textProperty().bind(model.spinnerInfoText);
priceCurrencyLabel.textProperty().bind(createStringBinding(() ->
model.dataModel.getCurrencyCode() + "/" + model.btcCode.get(), model.btcCode));
@ -160,11 +164,25 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
errorPopupDisplayed = new SimpleBooleanProperty();
offerWarningSubscription = EasyBind.subscribe(model.offerWarning, newValue -> {
if (newValue != null) {
new Popup().warning(newValue).onClose(() -> {
errorPopupDisplayed.set(true);
model.resetOfferWarning();
close();
}).show();
if (offerDetailsWindowDisplayed)
offerDetailsWindow.hide();
UserThread.runAfter(() -> new Popup().warning(newValue + "\n\n" +
"If you have already paid in funds you can withdraw it in the " +
"\"Funds/Available for withdrawal\" screen.")
.actionButtonText("Go to \"Available for withdrawal\"")
.onAction(() -> {
errorPopupDisplayed.set(true);
model.resetOfferWarning();
close();
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
})
.onClose(() -> {
errorPopupDisplayed.set(true);
model.resetOfferWarning();
close();
})
.show(), 100, TimeUnit.MILLISECONDS);
}
});
@ -188,10 +206,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
});
isTakeOfferSpinnerVisibleSubscription = EasyBind.subscribe(model.isTakeOfferSpinnerVisible, newValue -> {
takeOfferSpinner.setProgress(newValue ? -1 : 0);
takeOfferSpinner.setVisible(newValue);
});
isSpinnerVisibleSubscription = EasyBind.subscribe(model.isSpinnerVisible,
isSpinnerVisible -> spinner.setProgress(isSpinnerVisible ? -1 : 0));
showWarningInvalidBtcDecimalPlacesSubscription = EasyBind.subscribe(model.showWarningInvalidBtcDecimalPlaces, newValue -> {
if (newValue) {
@ -270,7 +286,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addressTextField.amountAsCoinProperty().unbind();
amountTextField.validationResultProperty().unbind();
takeOfferButton.disableProperty().unbind();
takeOfferSpinnerLabel.visibleProperty().unbind();
spinner.visibleProperty().unbind();
spinnerInfoLabel.visibleProperty().unbind();
spinnerInfoLabel.textProperty().unbind();
priceCurrencyLabel.textProperty().unbind();
volumeCurrencyLabel.textProperty().unbind();
amountRangeBtcLabel.textProperty().unbind();
@ -280,7 +298,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
offerWarningSubscription.unsubscribe();
errorMessageSubscription.unsubscribe();
isOfferAvailableSubscription.unsubscribe();
isTakeOfferSpinnerVisibleSubscription.unsubscribe();
isSpinnerVisibleSubscription.unsubscribe();
showWarningInvalidBtcDecimalPlacesSubscription.unsubscribe();
showTransactionPublishedScreenSubscription.unsubscribe();
@ -290,8 +308,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
if (offerAvailabilitySpinner != null)
offerAvailabilitySpinner.setProgress(0);
if (takeOfferSpinner != null)
takeOfferSpinner.setProgress(0);
if (spinner != null)
spinner.setProgress(0);
}
@ -364,9 +383,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private void onTakeOffer() {
if (model.hasAcceptedArbitrators()) {
offerDetailsWindow.onTakeOffer(() ->
model.onTakeOffer(() ->
offerDetailsWindow.hide()))
.show(model.getOffer(), model.dataModel.amountAsCoin.get());
model.onTakeOffer(() -> {
offerDetailsWindow.hide();
offerDetailsWindowDisplayed = false;
})
).show(model.getOffer(), model.dataModel.amountAsCoin.get());
offerDetailsWindowDisplayed = true;
} else {
new Popup().warning("You have no arbitrator selected.\n" +
"You need to select at least one arbitrator.")
@ -381,6 +403,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
private void onShowPayFundsScreen() {
model.onShowPayFundsScreen();
amountTextField.setMouseTransparent(true);
priceTextField.setMouseTransparent(true);
volumeTextField.setMouseTransparent(true);
@ -423,6 +447,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
takeOfferButton.setVisible(true);
cancelButton2.setVisible(true);
spinner.setProgress(-1);
payFundsPane.setVisible(true);
totalToPayLabel.setVisible(true);
totalToPayInfoIconLabel.setVisible(true);
@ -598,18 +624,15 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
Tuple3<Button, ProgressIndicator, Label> takeOfferTuple = addButtonWithStatusAfterGroup(gridPane, ++gridRow, "");
takeOfferButton = takeOfferTuple.first;
takeOfferButton.setVisible(false);
takeOfferButton.setMinHeight(40);
takeOfferButton.setPadding(new Insets(0, 20, 0, 20));
takeOfferButton.setOnAction(e -> {
onTakeOffer();
balanceTextField.cleanup();
});
takeOfferButton.setMinHeight(40);
takeOfferButton.setPadding(new Insets(0, 20, 0, 20));
takeOfferSpinner = takeOfferTuple.second;
takeOfferSpinner.setPrefSize(18, 18);
takeOfferSpinnerLabel = takeOfferTuple.third;
takeOfferSpinnerLabel.textProperty().bind(model.takeOfferSpinnerInfoText);
takeOfferSpinnerLabel.setVisible(false);
spinner = takeOfferTuple.second;
spinnerInfoLabel = takeOfferTuple.third;
cancelButton2 = addButton(gridPane, ++gridRow, BSResources.get("shared.cancel"));
cancelButton2.setOnAction(e -> close());

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.main.offer.takeoffer;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
@ -66,12 +67,12 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
final StringProperty errorMessage = new SimpleStringProperty();
final StringProperty offerWarning = new SimpleStringProperty();
final StringProperty btcCode = new SimpleStringProperty();
final StringProperty takeOfferSpinnerInfoText = new SimpleStringProperty();
final StringProperty spinnerInfoText = new SimpleStringProperty("");
final BooleanProperty isOfferAvailable = new SimpleBooleanProperty();
final BooleanProperty isTakeOfferButtonDisabled = new SimpleBooleanProperty(true);
final BooleanProperty isNextButtonDisabled = new SimpleBooleanProperty(true);
final BooleanProperty isTakeOfferSpinnerVisible = new SimpleBooleanProperty();
final BooleanProperty isSpinnerVisible = new SimpleBooleanProperty();
final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
@ -91,6 +92,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private ConnectionListener connectionListener;
private ChangeListener<Coin> feeFromFundingTxListener;
private Runnable takeOfferSucceededHandler;
private boolean showPayFundsScreenDisplayed;
///////////////////////////////////////////////////////////////////////////////////////////
@ -115,7 +117,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
addListeners();
amount.set(formatter.formatCoin(dataModel.amountAsCoin.get()));
isTakeOfferSpinnerVisible.set(false);
isSpinnerVisible.set(false);
showTransactionPublishedScreen.set(false);
// when getting back to an open screen we want to re-check again
@ -126,6 +128,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
applyOfferState(offer.stateProperty().get());
updateButtonDisableState();
updateSpinnerInfo();
}
@Override
@ -195,6 +199,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
}
public void onShowPayFundsScreen() {
showPayFundsScreenDisplayed = true;
updateSpinnerInfo();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Handle focus
///////////////////////////////////////////////////////////////////////////////////////////
@ -277,8 +286,10 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
break;
}
if (offerWarning != null)
isTakeOfferSpinnerVisible.set(false);
if (offerWarning.get() != null) {
isSpinnerVisible.set(false);
spinnerInfoText.set("");
}
updateButtonDisableState();
}
@ -317,6 +328,9 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
}
this.errorMessage.set(errorMessage + appendMsg);
isSpinnerVisible.set(false);
spinnerInfoText.set("");
if (takeOfferSucceededHandler != null)
takeOfferSucceededHandler.run();
} else {
@ -335,15 +349,13 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
if (takeOfferSucceededHandler != null)
takeOfferSucceededHandler.run();
isSpinnerVisible.set(false);
spinnerInfoText.set("");
showTransactionPublishedScreen.set(true);
} else {
log.error("trade.getDepositTx() == null. That must not happen");
}
}
takeOfferSpinnerInfoText.set("");
if (errorMessage.get() == null)
isTakeOfferSpinnerVisible.set(false);
}
private void updateButtonDisableState() {
@ -398,8 +410,15 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
amountAsCoinListener = (ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue));
isWalletFundedListener = (ov, oldValue, newValue) -> {
updateButtonDisableState();
isTakeOfferSpinnerVisible.set(true);
takeOfferSpinnerInfoText.set("Checking funding tx miner fee...");
isSpinnerVisible.set(true);
spinnerInfoText.set("Checking funding tx miner fee...");
};
feeFromFundingTxListener = (ov, oldValue, newValue) -> {
updateButtonDisableState();
if (newValue.compareTo(FeePolicy.getMinRequiredFeeForFundingTx()) >= 0) {
isSpinnerVisible.set(false);
spinnerInfoText.set("");
}
};
tradeStateListener = (ov, oldValue, newValue) -> applyTradeState(newValue);
tradeErrorListener = (ov, oldValue, newValue) -> applyTradeErrorMessage(newValue);
@ -408,11 +427,14 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
@Override
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
if (connection.getPeersNodeAddressOptional().isPresent() &&
connection.getPeersNodeAddressOptional().get().equals(offer.getOffererNodeAddress()))
connection.getPeersNodeAddressOptional().get().equals(offer.getOffererNodeAddress())) {
offerWarning.set("You lost connection to the offerer.\n" +
"He might have gone offline or has closed the connection to you because of too " +
"many open connections.\n\n" +
"If you can still see his offer in the offerbook you can try to take the offer again.");
isSpinnerVisible.set(false);
spinnerInfoText.set("");
}
}
@Override
@ -423,15 +445,19 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
public void onError(Throwable throwable) {
}
};
feeFromFundingTxListener = (ov, oldValue, newValue) -> {
updateButtonDisableState();
if (newValue.isPositive()) {
isTakeOfferSpinnerVisible.set(false);
takeOfferSpinnerInfoText.set("");
}
};
}
private void updateSpinnerInfo() {
if (dataModel.isWalletFunded.get() || !showPayFundsScreenDisplayed) {
isSpinnerVisible.set(false);
spinnerInfoText.set("");
} else if (showPayFundsScreenDisplayed) {
spinnerInfoText.set("Waiting for funds...");
isSpinnerVisible.set(true);
}
}
private void addListeners() {
// Bidirectional bindings are used for all input fields: amount, price, volume and minAmount
// We do volume/amount calculation during input, so user has immediate feedback

View File

@ -273,6 +273,7 @@ public abstract class Overlay<T extends Overlay> {
return (T) this;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -86,7 +86,6 @@ public abstract class TradeStepView extends AnchorPane {
public void activate() {
if (txIdTextField != null) {
txIdTextField.setup(model.dataModel.txId.get());
if (txIdSubscription != null)
txIdSubscription.unsubscribe();

View File

@ -67,7 +67,7 @@ public class BuyerStep2View extends TradeStepView {
tradeStatePropertySubscription = EasyBind.subscribe(trade.stateProperty(), state -> {
if (state == Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN) {
PaymentAccountContractData paymentAccountContractData = model.dataModel.getSellersPaymentAccountContractData();
String key = "StartPaymentPopup_" + trade.getId();
String key = "startPaymentPopup";
if (attentionRequiredPopup == null && !BitsquareApp.DEV_MODE) {
String message = "";
if (paymentAccountContractData instanceof BlockChainAccountContractData)

View File

@ -114,10 +114,7 @@ public class BuyerStep5View extends TradeStepView {
addLabelTextField(gridPane, gridRow, "Amount to withdraw:", model.getPayoutAmount(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
withdrawAddressTextField = addLabelInputTextField(gridPane, ++gridRow, "Withdraw to address:").second;
withdrawButton = addButtonAfterGroup(gridPane, ++gridRow, "Withdraw to external wallet");
withdrawButton.setOnAction(e -> {
withdrawButton.setDisable(true);
reviewWithdrawal();
});
withdrawButton.setOnAction(e -> reviewWithdrawal());
String key = "tradeCompleteInfo";
if (BitsquareApp.DEV_MODE)
@ -130,6 +127,7 @@ public class BuyerStep5View extends TradeStepView {
}
private void doWithdrawal() {
withdrawButton.setDisable(true);
model.dataModel.onWithdrawRequest(withdrawAddressTextField.getText(),
() -> {
String key = "tradeCompleteWithdrawCompletedInfo";

View File

@ -67,7 +67,7 @@ public class SellerStep3View extends TradeStepView {
tradeStatePropertySubscription = EasyBind.subscribe(trade.stateProperty(), state -> {
if (state == Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG) {
PaymentAccountContractData paymentAccountContractData = model.dataModel.getSellersPaymentAccountContractData();
String key = "ConfirmPaymentPopup_" + trade.getId();
String key = "confirmPaymentPopup";
if (attentionRequiredPopup == null && !BitsquareApp.DEV_MODE) {
String message;
String tradeAmountWithCode = model.formatter.formatFiatWithCode(trade.getTradeVolume());