diff --git a/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java b/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java index eef5e1cfe9..6e07b6bd6c 100644 --- a/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java @@ -195,16 +195,16 @@ class MainViewModel implements ViewModel { log.trace("updateProcess completed"); }); - Observable allTasks = Observable.merge(messageObservable, walletServiceObservable, updateProcessObservable); - allTasks.subscribe( + Observable allServices = Observable.merge(messageObservable, walletServiceObservable, updateProcessObservable); + allServices.subscribe( next -> { }, error -> log.error(error.toString()), - () -> Platform.runLater(() -> allTasksCompleted()) + () -> Platform.runLater(() -> onAllServicesInitialized()) ); } - private void allTasksCompleted() { + private void onAllServicesInitialized() { log.trace("backend completed"); tradeManager.getPendingTrades().addListener( @@ -232,6 +232,8 @@ class MainViewModel implements ViewModel { user.setAccountID(walletService.getRegistrationAddressEntry().toString()); persistence.write(user.getClass().getName(), user); } + + tradeManager.onAllServicesInitialized(); } private void applyUpdateState(UpdateProcess.State state) { diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java index 08418e892d..d19c9c32bb 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java @@ -70,12 +70,10 @@ class PendingTradesDataModel implements Activatable, DataModel { private TxConfidenceListener txConfidenceListener; private final ChangeListener stateChangeListener; - private final ChangeListener faultChangeListener; private final MapChangeListener mapChangeListener; final StringProperty txId = new SimpleStringProperty(); final ObjectProperty tradeState = new SimpleObjectProperty<>(); - final ObjectProperty fault = new SimpleObjectProperty<>(); @Inject @@ -85,7 +83,6 @@ class PendingTradesDataModel implements Activatable, DataModel { this.user = user; this.stateChangeListener = (ov, oldValue, newValue) -> tradeState.set(newValue); - this.faultChangeListener = (ov, oldValue, newValue) -> fault.set(newValue); this.mapChangeListener = change -> { if (change.wasAdded()) @@ -151,9 +148,6 @@ class PendingTradesDataModel implements Activatable, DataModel { }; walletService.addTxConfidenceListener(txConfidenceListener); updateConfidence(walletService.getConfidenceForTxId(txId.get())); - - trade.faultProperty().addListener(faultChangeListener); - fault.set(trade.faultProperty().get()); } else { txId.set(null); @@ -296,7 +290,6 @@ class PendingTradesDataModel implements Activatable, DataModel { if (selectedItem != null) { Trade trade = getTrade(); trade.stateProperty().removeListener(stateChangeListener); - trade.faultProperty().removeListener(faultChangeListener); } if (txConfidenceListener != null) diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java index a099a58b58..5759c0ca38 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java @@ -87,7 +87,6 @@ public class PendingTradesView extends ActivatableViewAndModel txIdChangeListener; private ChangeListener offererStateChangeListener; private ChangeListener takerStateChangeListener; - private ChangeListener faultChangeListener; private final Navigation navigation; @@ -129,7 +128,6 @@ public class PendingTradesView extends ActivatableViewAndModel applyOffererState(newValue); takerStateChangeListener = (ov, oldValue, newValue) -> applyTakerState(newValue); - faultChangeListener = (ov, oldValue, newValue) -> onFault(newValue); withdrawAddressTextField.setValidator(model.getBtcAddressValidator()); withdrawButton.disableProperty().bind(model.withdrawalButtonDisable); @@ -141,7 +139,6 @@ public class PendingTradesView extends ActivatableViewAndModel state = new SimpleObjectProperty<>(); - final ObjectProperty fault = new SimpleObjectProperty<>(); final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true); @@ -82,7 +81,6 @@ class PendingTradesViewModel extends ActivatableWithDataModel handleOfferIsAvailableState(newValue); 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); + } } public void setCloseHandler(TradeView.CloseHandler closeHandler) { @@ -167,7 +173,8 @@ public class TakeOfferView extends ActivatableViewAndModel _tradeAmount; transient private ObjectProperty _tradeVolume; transient private ObjectProperty _state; - transient private ObjectProperty _fault; - + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -131,11 +129,6 @@ public class Trade implements Serializable { stateProperty().set(state); } - public void setFault(Throwable fault) { - this.fault = fault; - faultProperty().set(fault); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Getters @@ -161,10 +154,6 @@ public class Trade implements Serializable { return state; } - public Throwable getFault() { - return fault; - } - public Coin getSecurityDeposit() { return offer.getSecurityDeposit(); } @@ -210,10 +199,4 @@ public class Trade implements Serializable { return _state; } - - public ObjectProperty faultProperty() { - if (_fault == null) - _fault = new SimpleObjectProperty<>(fault); - return _fault; - } } diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index cc334c5ddf..9eed40c5e9 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -74,8 +74,8 @@ public class TradeManager { private final SignatureService signatureService; private final OfferBookService offerBookService; - private final Map takerAsSellerProtocolMap = new HashMap<>(); - private final Map offererAsBuyerProtocolMap = new HashMap<>(); + private final Map sellerAsTakerProtocolMap = new HashMap<>(); + private final Map buyerAcceptsOfferProtocolMap = new HashMap<>(); private final Map checkOfferAvailabilityProtocolMap = new HashMap<>(); private final ObservableMap openOffers = FXCollections.observableHashMap(); @@ -123,6 +123,13 @@ public class TradeManager { tradeMessageService.addMessageHandler(messageHandler); } + // When all services are initialized we create the protocols for our open offers (which will listen for take offer requests) + public void onAllServicesInitialized() { + for (Map.Entry entry : openOffers.entrySet()) { + createBuyerAcceptsOfferProtocol(entry.getValue()); + } + } + /////////////////////////////////////////////////////////////////////////////////////////// // Called from UI @@ -180,7 +187,7 @@ public class TradeManager { model, (transaction) -> { OpenOffer openOffer = createOpenOffer(offer); - createOffererAsBuyerProtocol(openOffer); + createBuyerAcceptsOfferProtocol(openOffer); resultHandler.handleResult(transaction); }, (message) -> { @@ -214,7 +221,7 @@ public class TradeManager { persistPendingTrades(); break; case OFFERER_REJECTED: - case FAILED: + case MESSAGE_SENDING_FAILED: removeFailedTrade(trade); break; default: @@ -232,7 +239,7 @@ public class TradeManager { user); SellerAsTakerProtocol sellerTakesOfferProtocol = new SellerAsTakerProtocol(model); - takerAsSellerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol); + sellerAsTakerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol); sellerTakesOfferProtocol.takeOffer(); @@ -241,14 +248,14 @@ public class TradeManager { public void onFiatPaymentStarted(String tradeId) { // TODO remove if check when peristence is impl. - if (offererAsBuyerProtocolMap.containsKey(tradeId)) { - offererAsBuyerProtocolMap.get(tradeId).onFiatPaymentStarted(); + if (buyerAcceptsOfferProtocolMap.containsKey(tradeId)) { + buyerAcceptsOfferProtocolMap.get(tradeId).onFiatPaymentStarted(); persistPendingTrades(); } } public void onFiatPaymentReceived(String tradeId) { - takerAsSellerProtocolMap.get(tradeId).onFiatPaymentReceived(); + sellerAsTakerProtocolMap.get(tradeId).onFiatPaymentReceived(); } @@ -315,9 +322,9 @@ public class TradeManager { OpenOffer openOffer = openOffers.remove(offerId); disposeCheckOfferAvailabilityRequest(openOffer.getOffer()); persistOpenOffers(); - if (removeFromOffererAsBuyerProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) { - offererAsBuyerProtocolMap.get(offerId).cleanup(); - offererAsBuyerProtocolMap.remove(offerId); + if (removeFromOffererAsBuyerProtocolMap && buyerAcceptsOfferProtocolMap.containsKey(offerId)) { + buyerAcceptsOfferProtocolMap.get(offerId).cleanup(); + buyerAcceptsOfferProtocolMap.remove(offerId); } resultHandler.handleResult(); @@ -343,7 +350,7 @@ public class TradeManager { return trade; } - private void createOffererAsBuyerProtocol(OpenOffer openOffer) { + private void createBuyerAcceptsOfferProtocol(OpenOffer openOffer) { BuyerAsOffererModel model = new BuyerAsOffererModel( openOffer, tradeMessageService, @@ -383,9 +390,9 @@ public class TradeManager { persistPendingTrades(); break; case OFFERER_REJECTED: - case FAILED: + case MESSAGE_SENDING_FAILED: removeFailedTrade(trade); - offererAsBuyerProtocolMap.get(trade.getId()).cleanup(); + buyerAcceptsOfferProtocolMap.get(trade.getId()).cleanup(); break; default: log.error("Unhandled trade state: " + newValue); @@ -400,7 +407,7 @@ public class TradeManager { }); BuyerAsOffererProtocol buyerAcceptsOfferProtocol = new BuyerAsOffererProtocol(model); - offererAsBuyerProtocolMap.put(openOffer.getId(), buyerAcceptsOfferProtocol); + buyerAcceptsOfferProtocolMap.put(openOffer.getId(), buyerAcceptsOfferProtocol); } private void removeFailedTrade(Trade trade) { @@ -414,13 +421,13 @@ public class TradeManager { pendingTrades.remove(trade.getId()); persistPendingTrades(); - if (takerAsSellerProtocolMap.containsKey(trade.getId())) { - takerAsSellerProtocolMap.get(trade.getId()).cleanup(); - takerAsSellerProtocolMap.remove(trade.getId()); + if (sellerAsTakerProtocolMap.containsKey(trade.getId())) { + sellerAsTakerProtocolMap.get(trade.getId()).cleanup(); + sellerAsTakerProtocolMap.remove(trade.getId()); } - else if (offererAsBuyerProtocolMap.containsKey(trade.getId())) { - offererAsBuyerProtocolMap.get(trade.getId()).cleanup(); - offererAsBuyerProtocolMap.remove(trade.getId()); + else if (buyerAcceptsOfferProtocolMap.containsKey(trade.getId())) { + buyerAcceptsOfferProtocolMap.get(trade.getId()).cleanup(); + buyerAcceptsOfferProtocolMap.remove(trade.getId()); } if (!failed) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessRespondToTakeOfferRequestMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessRespondToTakeOfferRequestMessage.java index 2cff739838..8334262082 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessRespondToTakeOfferRequestMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessRespondToTakeOfferRequestMessage.java @@ -55,6 +55,6 @@ public class ProcessRespondToTakeOfferRequestMessage extends Task { private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class); + private AnimationTimer timeoutTimer; public RequestTakeOffer(TaskRunner taskHandler, SellerAsTakerModel model) { super(taskHandler, model); @@ -36,10 +40,18 @@ public class RequestTakeOffer extends Task { @Override protected void doRun() { + timeoutTimer = Utilities.setTimeout(10000, animationTimer -> { + failed("Timeout reached. We did not get any response form the offerer."); + model.getOffer().setState(Offer.State.OFFERER_OFFLINE); + return null; + }); + timeoutTimer.start(); + model.getTradeMessageService().sendMessage(model.getPeer(), new RequestTakeOfferMessage(model.getTrade().getId()), new SendMessageListener() { @Override public void handleResult() { + timeoutTimer.stop(); complete(); } @@ -53,6 +65,7 @@ public class RequestTakeOffer extends Task { @Override protected void applyStateOnFault() { + timeoutTimer.stop(); if (model.getOffer().getState() != Offer.State.OFFERER_OFFLINE) model.getOffer().setState(Offer.State.AVAILABILITY_CHECK_FAILED); }