From b97506cf5185c92389757d9c2171f9a8c233833c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 16 Apr 2016 15:46:45 +0200 Subject: [PATCH] Add listeners if pricefeed is not available --- .../io/bitsquare/btc/pricefeed/PriceFeed.java | 1 + .../java/io/bitsquare/trade/offer/Offer.java | 7 ++- .../markets/charts/MarketsChartsView.java | 59 +++++++++++++++---- .../charts/MarketsChartsViewModel.java | 24 +++++++- .../createoffer/CreateOfferViewModel.java | 4 +- .../main/offer/offerbook/OfferBookView.java | 57 ++++++++++++++++-- .../offer/offerbook/OfferBookViewModel.java | 18 +++--- .../offer/takeoffer/TakeOfferDataModel.java | 7 +-- .../main/offer/takeoffer/TakeOfferView.java | 9 +-- .../pendingtrades/PendingTradesView.fxml | 2 +- .../p2p/network/LocalhostNetworkNode.java | 4 +- 11 files changed, 150 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java b/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java index a029fa0be0..9f4304059c 100644 --- a/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java +++ b/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java @@ -107,6 +107,7 @@ public class PriceFeed { return null; } + /////////////////////////////////////////////////////////////////////////////////////////// // Setter /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/core/src/main/java/io/bitsquare/trade/offer/Offer.java b/core/src/main/java/io/bitsquare/trade/offer/Offer.java index f5b74a9b16..39e862d40c 100644 --- a/core/src/main/java/io/bitsquare/trade/offer/Offer.java +++ b/core/src/main/java/io/bitsquare/trade/offer/Offer.java @@ -277,7 +277,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload resultHandler.handleResult(); }, (errorMessage) -> { - availabilityProtocol.cancel(); + if (availabilityProtocol != null) + availabilityProtocol.cancel(); log.error(errorMessage); }); availabilityProtocol.sendOfferAvailabilityRequest(); @@ -370,8 +371,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload return null; } } else { - log.warn("We don't have a market price./n" + - "That case could only happen if you don't get a price feed."); + log.warn("We don't have a market price.\n" + + "That case could only happen if you don't have a price feed."); return null; } } else { diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java index 4eb8d7e4fc..915ddaa897 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java @@ -35,6 +35,8 @@ import io.bitsquare.trade.offer.Offer; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -47,7 +49,6 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.util.Callback; import javafx.util.StringConverter; -import org.bitcoinj.utils.Fiat; import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.Subscription; @@ -182,17 +183,34 @@ public class MarketsChartsView extends ActivatableViewAndModel call(TableColumn column) { return new TableCell() { + private Offer offer; + ChangeListener listener = new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + if (offer != null && offer.getPrice() != null) { + setText(formatter.formatFiat(offer.getPrice())); + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + } + } + }; + @Override public void updateItem(final Offer offer, boolean empty) { super.updateItem(offer, empty); if (offer != null && !empty) { - Fiat offerPrice = offer.getPrice(); - if (offerPrice != null) - setText(formatter.formatFiat(offerPrice)); - else - setText(""); - } else + if (offer.getPrice() == null) { + this.offer = offer; + model.priceFeed.currenciesUpdateFlagProperty().addListener(listener); + setText("N/A"); + } else { + setText(formatter.formatFiat(offer.getPrice())); + } + } else { + if (listener != null) + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + this.offer = null; setText(""); + } } }; } @@ -236,13 +254,34 @@ public class MarketsChartsView extends ActivatableViewAndModel call(TableColumn column) { return new TableCell() { + private Offer offer; + ChangeListener listener = new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + if (offer != null && offer.getPrice() != null) { + setText(formatter.formatFiat(offer.getOfferVolume())); + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + } + } + }; + @Override public void updateItem(final Offer offer, boolean empty) { super.updateItem(offer, empty); - if (offer != null && !empty) - setText(formatter.formatFiat(offer.getOfferVolume())); - else + if (offer != null && !empty) { + if (offer.getPrice() == null) { + this.offer = offer; + model.priceFeed.currenciesUpdateFlagProperty().addListener(listener); + setText("N/A"); + } else { + setText(formatter.formatFiat(offer.getOfferVolume())); + } + } else { + if (listener != null) + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + this.offer = null; setText(""); + } } }; } diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java index 0cab818119..ddb8b39384 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java @@ -29,6 +29,8 @@ import io.bitsquare.trade.offer.Offer; import io.bitsquare.user.Preferences; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; @@ -44,15 +46,16 @@ class MarketsChartsViewModel extends ActivatableViewModel { private final OfferBook offerBook; private final Preferences preferences; - private final PriceFeed priceFeed; + final PriceFeed priceFeed; final ObjectProperty tradeCurrency = new SimpleObjectProperty<>(CurrencyUtil.getDefaultTradeCurrency()); - private final List buyData = new ArrayList(); - private final List sellData = new ArrayList(); + private final List buyData = new ArrayList<>(); + private final List sellData = new ArrayList<>(); private final ObservableList offerBookListItems; private final ListChangeListener listChangeListener; private final ObservableList top3BuyOfferList = FXCollections.observableArrayList(); private final ObservableList top3SellOfferList = FXCollections.observableArrayList(); + private final ChangeListener cacheFilledListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -67,15 +70,30 @@ class MarketsChartsViewModel extends ActivatableViewModel { offerBookListItems = offerBook.getOfferBookListItems(); listChangeListener = c -> updateChartData(offerBookListItems); + + cacheFilledListener = new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + if (!offerBookListItems.stream().filter(item -> item.getOffer().getPrice() == null).findAny().isPresent()) { + offerBook.fillOfferBookListItems(); + updateChartData(offerBookListItems); + priceFeed.currenciesUpdateFlagProperty().removeListener(cacheFilledListener); + } + } + }; } @Override protected void activate() { priceFeed.setType(PriceFeed.Type.LAST); offerBookListItems.addListener(listChangeListener); + offerBook.fillOfferBookListItems(); updateChartData(offerBookListItems); + if (offerBookListItems.stream().filter(item -> item.getOffer().getPrice() == null).findAny().isPresent()) + priceFeed.currenciesUpdateFlagProperty().addListener(cacheFilledListener); + if (!preferences.getUseStickyMarketPrice()) priceFeed.setCurrencyCode(tradeCurrency.get().getCode()); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java index 85a2f13e21..84867e7e23 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java @@ -751,7 +751,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel call( TableColumn column) { return new TableCell() { + private OfferBookListItem offerBookListItem; + ChangeListener listener = new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + if (offerBookListItem != null && offerBookListItem.getOffer().getPrice() != null) { + setText(model.getPrice(offerBookListItem)); + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + } + } + }; + @Override public void updateItem(final OfferBookListItem item, boolean empty) { super.updateItem(item, empty); - if (item != null && !empty) - setText(model.getPrice(item)); - else + + if (item != null && !empty) { + if (item.getOffer().getPrice() == null) { + this.offerBookListItem = item; + model.priceFeed.currenciesUpdateFlagProperty().addListener(listener); + setText("N/A"); + } else { + setText(model.getPrice(item)); + } + } else { + if (listener != null) + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + this.offerBookListItem = null; setText(""); + } } }; } @@ -448,13 +472,34 @@ public class OfferBookView extends ActivatableViewAndModel call( TableColumn column) { return new TableCell() { + private OfferBookListItem offerBookListItem; + ChangeListener listener = new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + if (offerBookListItem != null && offerBookListItem.getOffer().getOfferVolume() != null) { + setText(model.getVolume(offerBookListItem)); + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + } + } + }; + @Override public void updateItem(final OfferBookListItem item, boolean empty) { super.updateItem(item, empty); - if (item != null && !empty) - setText(model.getVolume(item)); - else + if (item != null && !empty) { + if (item.getOffer().getPrice() == null) { + this.offerBookListItem = item; + model.priceFeed.currenciesUpdateFlagProperty().addListener(listener); + setText("N/A"); + } else { + setText(model.getVolume(item)); + } + } else { + if (listener != null) + model.priceFeed.currenciesUpdateFlagProperty().removeListener(listener); + this.offerBookListItem = null; setText(""); + } } }; } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModel.java index 1660c54ba5..9bbf8294a2 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModel.java @@ -70,7 +70,7 @@ class OfferBookViewModel extends ActivatableViewModel { private final OfferBook offerBook; private final Preferences preferences; private final P2PService p2PService; - private final PriceFeed priceFeed; + final PriceFeed priceFeed; private ClosedTradableManager closedTradableManager; private Navigation navigation; final BSFormatter formatter; @@ -272,19 +272,21 @@ class OfferBookViewModel extends ActivatableViewModel { else return formatter.formatFiat(price) + postFix; } else { - return ""; + return "N/A"; } } String getVolume(OfferBookListItem item) { Fiat offerVolume = item.getOffer().getOfferVolume(); Fiat minOfferVolume = item.getOffer().getMinOfferVolume(); - if (showAllTradeCurrenciesProperty.get()) - return (item != null) ? formatter.formatFiatWithCode(offerVolume) + - " (" + formatter.formatFiatWithCode(minOfferVolume) + ")" : ""; - else - return (item != null) ? formatter.formatFiat(offerVolume) + - " (" + formatter.formatFiat(minOfferVolume) + ")" : ""; + if (offerVolume != null && minOfferVolume != null) { + if (showAllTradeCurrenciesProperty.get()) + return formatter.formatFiatWithCode(offerVolume) + " (" + formatter.formatFiatWithCode(minOfferVolume) + ")"; + else + return formatter.formatFiat(offerVolume) + " (" + formatter.formatFiat(minOfferVolume) + ")"; + } else { + return "N/A"; + } } String getPaymentMethod(OfferBookListItem item) { diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java index bae28afe95..7ab1ed27ac 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java @@ -148,7 +148,8 @@ class TakeOfferDataModel extends ActivatableDataModel { protected void deactivate() { removeBindings(); removeListeners(); - tradeManager.onCancelAvailabilityRequest(offer); + if (offer != null) + tradeManager.onCancelAvailabilityRequest(offer); } @@ -160,8 +161,6 @@ class TakeOfferDataModel extends ActivatableDataModel { void initWithData(Offer offer) { this.offer = offer; tradePrice = offer.getPrice(); - // we check at the view class and close in case we dont get a price - checkNotNull(tradePrice, "tradePrice must not be null"); addressEntry = walletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.OFFER_FUNDING); checkNotNull(addressEntry, "addressEntry must not be null"); @@ -309,7 +308,7 @@ class TakeOfferDataModel extends ActivatableDataModel { /////////////////////////////////////////////////////////////////////////////////////////// void calculateVolume() { - if (offer != null && + if (tradePrice != null && offer != null && amountAsCoin.get() != null && !amountAsCoin.get().isZero()) { volumeAsFiat.set(new ExchangeRate(tradePrice).coinToFiat(amountAsCoin.get())); diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java index b49fc226ad..76c3fc24d0 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java @@ -59,6 +59,7 @@ import javafx.stage.Window; import javafx.util.StringConverter; import net.glxn.qrgen.QRCode; import net.glxn.qrgen.image.ImageType; +import org.bitcoinj.core.Coin; import org.bitcoinj.uri.BitcoinURI; import org.controlsfx.control.PopOver; import org.fxmisc.easybind.EasyBind; @@ -194,7 +195,6 @@ public class TakeOfferView extends ActivatableViewAndModel - + diff --git a/network/src/main/java/io/bitsquare/p2p/network/LocalhostNetworkNode.java b/network/src/main/java/io/bitsquare/p2p/network/LocalhostNetworkNode.java index aea6d728ba..356d83a189 100644 --- a/network/src/main/java/io/bitsquare/p2p/network/LocalhostNetworkNode.java +++ b/network/src/main/java/io/bitsquare/p2p/network/LocalhostNetworkNode.java @@ -27,8 +27,8 @@ import java.util.function.Consumer; public class LocalhostNetworkNode extends NetworkNode { private static final Logger log = LoggerFactory.getLogger(LocalhostNetworkNode.class); - private static volatile int simulateTorDelayTorNode = 200; - private static volatile int simulateTorDelayHiddenService = 300; + private static volatile int simulateTorDelayTorNode = 500; + private static volatile int simulateTorDelayHiddenService = 500; public static void setSimulateTorDelayTorNode(int simulateTorDelayTorNode) { LocalhostNetworkNode.simulateTorDelayTorNode = simulateTorDelayTorNode;