Add timeout handler to UI

This commit is contained in:
Manfred Karrer 2015-03-14 12:29:23 +01:00
parent f5a7391cb5
commit 0c0efd3fe0
8 changed files with 63 additions and 22 deletions

View file

@ -96,6 +96,7 @@ 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 ChangeListener<Offer.State> offerIsAvailableChangeListener;
private ChangeListener<String> errorMessageChangeListener;
private TradeView.CloseHandler closeHandler; private TradeView.CloseHandler closeHandler;
@Inject @Inject
@ -117,6 +118,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
protected void doDeactivate() { protected void doDeactivate() {
if (offerIsAvailableChangeListener != null) if (offerIsAvailableChangeListener != null)
model.offerIsAvailable.removeListener(offerIsAvailableChangeListener); model.offerIsAvailable.removeListener(offerIsAvailableChangeListener);
if (errorMessageChangeListener != null)
model.errorMessage.removeListener(errorMessageChangeListener);
} }
public void initWithData(Direction direction, Coin amount, Offer offer) { public void initWithData(Direction direction, Coin amount, Offer offer) {
@ -152,17 +156,22 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
model.offerIsAvailable.addListener(offerIsAvailableChangeListener); model.offerIsAvailable.addListener(offerIsAvailableChangeListener);
handleOfferIsAvailableState(model.offerIsAvailable.get()); 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 errorMessageChangeListener = (ov, oldValue, newValue) -> handleErrorMessage(newValue);
if (!model.isTakeOfferButtonDisabled.get()) { model.errorMessage.addListener(errorMessageChangeListener);
showPayFundsScreen();
showPaymentInfoScreenButton.setVisible(false);
}
} }
public void setCloseHandler(TradeView.CloseHandler closeHandler) { public void setCloseHandler(TradeView.CloseHandler closeHandler) {
this.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) { private void handleOfferIsAvailableState(Offer.State state) {
switch (state) { switch (state) {
case UNKNOWN: case UNKNOWN:
@ -173,8 +182,16 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
isOfferAvailableProgressIndicator.setProgress(0); isOfferAvailableProgressIndicator.setProgress(0);
isOfferAvailableProgressIndicator.setVisible(false); isOfferAvailableProgressIndicator.setVisible(false);
isOfferAvailableProgressIndicator.setManaged(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); showPaymentInfoScreenButton.setVisible(true);
}
break; break;
case OFFERER_OFFLINE: case OFFERER_OFFLINE:
Popups.openWarningPopup("You cannot take that offer", "The offerer is offline."); Popups.openWarningPopup("You cannot take that offer", "The offerer is offline.");

View file

@ -24,6 +24,7 @@ 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.util.Utilities;
import io.bitsquare.viewfx.model.ActivatableWithDataModel; import io.bitsquare.viewfx.model.ActivatableWithDataModel;
import io.bitsquare.viewfx.model.ViewModel; import io.bitsquare.viewfx.model.ViewModel;
@ -32,6 +33,7 @@ import org.bitcoinj.core.Coin;
import javax.inject.Inject; import javax.inject.Inject;
import javafx.animation.AnimationTimer;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -39,9 +41,13 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static javafx.beans.binding.Bindings.createStringBinding; 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 String fiatCode; private String fiatCode;
private String amountRange; private String amountRange;
@ -73,6 +79,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
final StringProperty transactionId = new SimpleStringProperty(); final StringProperty transactionId = new SimpleStringProperty();
final StringProperty requestTakeOfferErrorMessage = new SimpleStringProperty(); final StringProperty requestTakeOfferErrorMessage = new SimpleStringProperty();
final StringProperty btcCode = new SimpleStringProperty(); final StringProperty btcCode = new SimpleStringProperty();
final StringProperty errorMessage = new SimpleStringProperty();
final BooleanProperty isTakeOfferButtonVisible = new SimpleBooleanProperty(false); final BooleanProperty isTakeOfferButtonVisible = new SimpleBooleanProperty(false);
@ -86,6 +93,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
// Needed for the addressTextField // Needed for the addressTextField
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>(); final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
private AnimationTimer timeoutTimer;
@Inject @Inject
@ -144,6 +152,14 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
isTakeOfferButtonDisabled.set(true); isTakeOfferButtonDisabled.set(true);
isTakeOfferSpinnerVisible.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(); dataModel.takeOffer();
} }

View file

@ -301,6 +301,7 @@ public class TomP2PNode implements ClientNode {
else { else {
throw new RuntimeException("Received msg from myself. That must never happen."); throw new RuntimeException("Received msg from myself. That must never happen.");
} }
return true; return true;
}); });
} }

View file

@ -359,6 +359,9 @@ public class TradeManager {
signatureService, signatureService,
user); user);
if (pendingTrades.containsKey(openOffer.getId()))
model.setTrade(pendingTrades.get(openOffer.getId()));
openOffer.stateProperty().addListener((ov, oldValue, newValue) -> { openOffer.stateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("openOffer state = " + newValue); log.debug("openOffer state = " + newValue);
switch (newValue) { switch (newValue) {

View file

@ -41,9 +41,9 @@ public class RespondToTakeOfferRequest extends Task<BuyerAsOffererModel> {
offerIsAvailable = model.getOpenOffer().getState() == OpenOffer.State.OPEN; offerIsAvailable = model.getOpenOffer().getState() == OpenOffer.State.OPEN;
if (offerIsAvailable) { if (offerIsAvailable) {
model.getOpenOffer().setState(OpenOffer.State.OFFER_ACCEPTED);
Trade trade = new Trade(model.getOpenOffer().getOffer()); Trade trade = new Trade(model.getOpenOffer().getOffer());
model.setTrade(trade); model.setTrade(trade);
model.getOpenOffer().setState(OpenOffer.State.OFFER_ACCEPTED);
} }
else { else {
log.info("Received take offer request but the offer not marked as open anymore."); log.info("Received take offer request but the offer not marked as open anymore.");

View file

@ -36,6 +36,7 @@ import java.net.URI;
import java.util.function.Function; import java.util.function.Function;
import javafx.animation.AnimationTimer; import javafx.animation.AnimationTimer;
import javafx.application.Platform;
import javafx.scene.input.*; import javafx.scene.input.*;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -209,7 +210,7 @@ public class Utilities {
@Override @Override
public void handle(long arg0) { public void handle(long arg0) {
if (System.currentTimeMillis() > delay + lastTimeStamp) { if (System.currentTimeMillis() > delay + lastTimeStamp) {
callback.apply(this); Platform.runLater(() -> callback.apply(this));
this.stop(); this.stop();
} }
} }

View file

@ -111,7 +111,7 @@ takeOffer.fundsBox.total=Total:
takeOffer.fundsBox.showAdvanced=Show advanced settings takeOffer.fundsBox.showAdvanced=Show advanced settings
takeOffer.fundsBox.hideAdvanced=Hide advanced settings takeOffer.fundsBox.hideAdvanced=Hide advanced settings
takeOffer.fundsBox.takeOffer=Take offer 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.fundsBox.paymentLabel=Bitsquare trade ({0})
takeOffer.advancedBox.title=Advanced settings takeOffer.advancedBox.title=Advanced settings

View file

@ -23,35 +23,38 @@
</encoder> </encoder>
</appender> </appender>
<root level="INFO"> <root level="WARN">
<appender-ref ref="CONSOLE_APPENDER"/> <appender-ref ref="CONSOLE_APPENDER"/>
<appender-ref ref="FILE"/> <appender-ref ref="FILE"/>
</root> </root>
<logger name="io.bitsquare" level="TRACE"/> <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.message.Encoder" 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.Decoder" level="WARN"/> <logger name="net.tomp2p.message.Decoder" level="WARN"/>
<logger name="net.tomp2p.message.MessageHeaderCodec" level="WARN"/> <logger name="net.tomp2p.message.MessageHeaderCodec" level="WARN"/>
<logger name="io.netty.util" level="WARN"/> <logger name="io.netty.util" level="WARN"/>
<logger name="io.netty.channel" 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.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"/>--> <!-- <logger name="io.bitsquare.btc.WalletService" level="WARN"/>-->
<!-- <!--