From 0c0efd3fe0714868496f392ff7913bfa17494aa4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer <mk@nucleo.io> Date: Sat, 14 Mar 2015 12:29:23 +0100 Subject: [PATCH] Add timeout handler to UI --- .../main/trade/takeoffer/TakeOfferView.java | 29 +++++++++++++++---- .../trade/takeoffer/TakeOfferViewModel.java | 16 ++++++++++ .../bitsquare/network/tomp2p/TomP2PNode.java | 1 + .../java/io/bitsquare/trade/TradeManager.java | 3 ++ .../tasks/RespondToTakeOfferRequest.java | 2 +- .../java/io/bitsquare/util/Utilities.java | 3 +- .../resources/i18n/displayStrings.properties | 2 +- core/src/main/resources/logback.xml | 29 ++++++++++--------- 8 files changed, 63 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.java b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.java index 8109c923a4..de3055b4f2 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.java @@ -96,6 +96,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer private final Navigation navigation; private final OverlayManager overlayManager; private ChangeListener<Offer.State> offerIsAvailableChangeListener; + private ChangeListener<String> errorMessageChangeListener; private TradeView.CloseHandler closeHandler; @Inject @@ -117,6 +118,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer protected void doDeactivate() { if (offerIsAvailableChangeListener != null) model.offerIsAvailable.removeListener(offerIsAvailableChangeListener); + + if (errorMessageChangeListener != null) + model.errorMessage.removeListener(errorMessageChangeListener); } public void initWithData(Direction direction, Coin amount, Offer offer) { @@ -152,17 +156,22 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer model.offerIsAvailable.addListener(offerIsAvailableChangeListener); handleOfferIsAvailableState(model.offerIsAvailable.get()); - // 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); - } + errorMessageChangeListener = (ov, oldValue, newValue) -> handleErrorMessage(newValue); + model.errorMessage.addListener(errorMessageChangeListener); } public void setCloseHandler(TradeView.CloseHandler closeHandler) { this.closeHandler = closeHandler; } + + private void handleErrorMessage(String errorMessage) { + if (errorMessage != null) + Popups.openErrorPopup("An error occurred", errorMessage); + + model.errorMessage.set(null); + } + private void handleOfferIsAvailableState(Offer.State state) { switch (state) { case UNKNOWN: @@ -173,8 +182,16 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer isOfferAvailableProgressIndicator.setProgress(0); isOfferAvailableProgressIndicator.setVisible(false); isOfferAvailableProgressIndicator.setManaged(false); - if (model.isTakeOfferButtonDisabled.get()) + + // 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."); diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java index 661f8d0d31..8d2609e69c 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java @@ -24,6 +24,7 @@ import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.locale.BSResources; import io.bitsquare.offer.Direction; import io.bitsquare.offer.Offer; +import io.bitsquare.util.Utilities; import io.bitsquare.viewfx.model.ActivatableWithDataModel; import io.bitsquare.viewfx.model.ViewModel; @@ -32,6 +33,7 @@ import org.bitcoinj.core.Coin; import javax.inject.Inject; +import javafx.animation.AnimationTimer; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -39,9 +41,13 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import static javafx.beans.binding.Bindings.createStringBinding; class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> implements ViewModel { + private static final Logger log = LoggerFactory.getLogger(TakeOfferViewModel.class); private String fiatCode; private String amountRange; @@ -73,6 +79,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im final StringProperty transactionId = new SimpleStringProperty(); final StringProperty requestTakeOfferErrorMessage = new SimpleStringProperty(); final StringProperty btcCode = new SimpleStringProperty(); + final StringProperty errorMessage = new SimpleStringProperty(); final BooleanProperty isTakeOfferButtonVisible = new SimpleBooleanProperty(false); @@ -86,6 +93,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im // Needed for the addressTextField final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>(); + private AnimationTimer timeoutTimer; @Inject @@ -144,6 +152,14 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im isTakeOfferButtonDisabled.set(true); isTakeOfferSpinnerVisible.set(true); + timeoutTimer = Utilities.setTimeout(20000, animationTimer -> { + errorMessage.set("Timeout reached. Maybe there are connection problems. Please try again later."); + updateButtonDisableState(); + isTakeOfferSpinnerVisible.set(false); + return null; + }); + timeoutTimer.start(); + dataModel.takeOffer(); } diff --git a/core/src/main/java/io/bitsquare/network/tomp2p/TomP2PNode.java b/core/src/main/java/io/bitsquare/network/tomp2p/TomP2PNode.java index e625fed1e3..283663b93b 100644 --- a/core/src/main/java/io/bitsquare/network/tomp2p/TomP2PNode.java +++ b/core/src/main/java/io/bitsquare/network/tomp2p/TomP2PNode.java @@ -301,6 +301,7 @@ public class TomP2PNode implements ClientNode { else { throw new RuntimeException("Received msg from myself. That must never happen."); } + return true; }); } diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index 9eed40c5e9..2c0025dc8c 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -359,6 +359,9 @@ public class TradeManager { signatureService, user); + if (pendingTrades.containsKey(openOffer.getId())) + model.setTrade(pendingTrades.get(openOffer.getId())); + openOffer.stateProperty().addListener((ov, oldValue, newValue) -> { log.debug("openOffer state = " + newValue); switch (newValue) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RespondToTakeOfferRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RespondToTakeOfferRequest.java index c28c84887c..3a80bcb9bb 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RespondToTakeOfferRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RespondToTakeOfferRequest.java @@ -41,9 +41,9 @@ public class RespondToTakeOfferRequest extends Task<BuyerAsOffererModel> { offerIsAvailable = model.getOpenOffer().getState() == OpenOffer.State.OPEN; if (offerIsAvailable) { - model.getOpenOffer().setState(OpenOffer.State.OFFER_ACCEPTED); Trade trade = new Trade(model.getOpenOffer().getOffer()); model.setTrade(trade); + model.getOpenOffer().setState(OpenOffer.State.OFFER_ACCEPTED); } else { log.info("Received take offer request but the offer not marked as open anymore."); diff --git a/core/src/main/java/io/bitsquare/util/Utilities.java b/core/src/main/java/io/bitsquare/util/Utilities.java index 2ab98d42d2..e55c2fdd52 100644 --- a/core/src/main/java/io/bitsquare/util/Utilities.java +++ b/core/src/main/java/io/bitsquare/util/Utilities.java @@ -36,6 +36,7 @@ import java.net.URI; import java.util.function.Function; import javafx.animation.AnimationTimer; +import javafx.application.Platform; import javafx.scene.input.*; import org.slf4j.Logger; @@ -209,7 +210,7 @@ public class Utilities { @Override public void handle(long arg0) { if (System.currentTimeMillis() > delay + lastTimeStamp) { - callback.apply(this); + Platform.runLater(() -> callback.apply(this)); this.stop(); } } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index c6513ee603..f25ed85961 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -111,7 +111,7 @@ takeOffer.fundsBox.total=Total: takeOffer.fundsBox.showAdvanced=Show advanced settings takeOffer.fundsBox.hideAdvanced=Hide advanced settings takeOffer.fundsBox.takeOffer=Take offer -takeOffer.fundsBox.takeOfferSpinnerInfo=Deposit payment is in progress... +takeOffer.fundsBox.takeOfferSpinnerInfo=Take offer in progress... takeOffer.fundsBox.paymentLabel=Bitsquare trade ({0}) takeOffer.advancedBox.title=Advanced settings diff --git a/core/src/main/resources/logback.xml b/core/src/main/resources/logback.xml index 0c123b9d56..08baf8845a 100644 --- a/core/src/main/resources/logback.xml +++ b/core/src/main/resources/logback.xml @@ -23,35 +23,38 @@ </encoder> </appender> - <root level="INFO"> + <root level="WARN"> <appender-ref ref="CONSOLE_APPENDER"/> <appender-ref ref="FILE"/> </root> <logger name="io.bitsquare" level="TRACE"/> + <logger name="io.bitsquare.network.tomp2p.BootstrappedPeerBuilder" level="ERROR"/> + <logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/> + <logger name="io.bitsquare.persistence.Persistence" level="ERROR"/> + <logger name="io.bitsquare.locale.BSResources" level="ERROR"/> + + <logger name="org.bitcoinj" level="ERROR"/> + <logger name="net.tomp2p" level="ERROR"/> + <logger name="com.vinumeris.updatefx" level="OFF"/> + <logger name="io.netty" level="OFF"/> + - <logger name="org.bitcoinj" level="WARN"/> - <logger name="net.tomp2p" level="WARN"/> - <logger name="com.vinumeris.updatefx" level="INFO"/> - - - <logger name="net.tomp2p.message.Encoder" level="WARN"/> + <!-- <logger name="net.tomp2p.message.Encoder" level="WARN"/> <logger name="net.tomp2p.message.Decoder" level="WARN"/> <logger name="net.tomp2p.message.MessageHeaderCodec" level="WARN"/> <logger name="io.netty.util" level="WARN"/> <logger name="io.netty.channel" level="WARN"/> - <logger name="io.netty.buffer" level="WARN"/> + <logger name="io.netty.buffer" level="WARN"/>--> - <logger name="io.bitsquare.gui.util.Profiler" level="WARN"/> - <logger name="io.bitsquare.persistence.Persistence" level="WARN"/> - <logger name="io.bitsquare.locale.BSResources" level="OFF"/> + - <logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/> + <!-- <logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/> <logger name="org.bitcoinj.core.AbstractBlockChain" level="WARN"/> - <logger name="org.bitcoinj.wallet.DeterministicKeyChain" level="WARN"/> + <logger name="org.bitcoinj.wallet.DeterministicKeyChain" level="WARN"/>--> <!-- <logger name="io.bitsquare.btc.WalletService" level="WARN"/>--> <!--