mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 23:36:00 -04:00
Use combo box for Make market price, update all prices on interval
This commit is contained in:
parent
0ebf3f6b36
commit
3f5e1296b1
@ -8,13 +8,10 @@ import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.pricefeed.providers.BitcoinAveragePriceProvider;
|
||||
import io.bitsquare.btc.pricefeed.providers.PoloniexPriceProvider;
|
||||
import io.bitsquare.btc.pricefeed.providers.PriceProvider;
|
||||
import io.bitsquare.common.Timer;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.FaultHandler;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import javafx.beans.property.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -43,8 +40,10 @@ public class PriceFeed {
|
||||
}
|
||||
}
|
||||
|
||||
private static final long PERIOD_FIAT_SEC = Timer.STRESS_TEST ? 30 : 60; // We load only the selected currency on interval. Only the first request we load all
|
||||
private static final long PERIOD_CRYPTO_SEC = Timer.STRESS_TEST ? 30 : 10 * 60; // We load the full list with 33kb so we don't want to load too often
|
||||
private static final long PERIOD_FIAT_SEC = 60;
|
||||
private static final long PERIOD_ALL_FIAT_SEC = 60 * 5;
|
||||
private static final long PERIOD_CRYPTO_SEC = 60;
|
||||
private static final long PERIOD_ALL_CRYPTO_SEC = 60 * 5;
|
||||
|
||||
private final Map<String, MarketPrice> cache = new HashMap<>();
|
||||
private final PriceProvider fiatPriceProvider = new BitcoinAveragePriceProvider();
|
||||
@ -53,8 +52,9 @@ public class PriceFeed {
|
||||
private FaultHandler faultHandler;
|
||||
private Type type;
|
||||
private String currencyCode;
|
||||
transient private final StringProperty currencyCodeProperty = new SimpleStringProperty();
|
||||
transient private final ObjectProperty<Type> typeProperty = new SimpleObjectProperty<>();
|
||||
private final StringProperty currencyCodeProperty = new SimpleStringProperty();
|
||||
private final ObjectProperty<Type> typeProperty = new SimpleObjectProperty<>();
|
||||
private final IntegerProperty currenciesUpdateFlag = new SimpleIntegerProperty(0);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -84,6 +84,10 @@ public class PriceFeed {
|
||||
UserThread.runPeriodically(() -> requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice),
|
||||
PERIOD_CRYPTO_SEC);
|
||||
});
|
||||
|
||||
UserThread.runPeriodically(() -> requestAllPrices(fiatPriceProvider, this::applyPrice), PERIOD_ALL_FIAT_SEC);
|
||||
UserThread.runPeriodically(() -> requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice), PERIOD_ALL_CRYPTO_SEC);
|
||||
|
||||
requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice);
|
||||
}
|
||||
|
||||
@ -109,6 +113,11 @@ public class PriceFeed {
|
||||
this.currencyCode = currencyCode;
|
||||
currencyCodeProperty.set(currencyCode);
|
||||
applyPrice();
|
||||
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
requestPrice(fiatPriceProvider);
|
||||
else
|
||||
requestPrice(cryptoCurrenciesPriceProvider);
|
||||
}
|
||||
|
||||
|
||||
@ -132,6 +141,10 @@ public class PriceFeed {
|
||||
return typeProperty;
|
||||
}
|
||||
|
||||
public IntegerProperty currenciesUpdateFlagProperty() {
|
||||
return currenciesUpdateFlag;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
@ -142,13 +155,15 @@ public class PriceFeed {
|
||||
if (cache.containsKey(currencyCode)) {
|
||||
MarketPrice marketPrice = cache.get(currencyCode);
|
||||
//log.debug("applyPrice type=" + type);
|
||||
priceConsumer.accept(marketPrice.getPrice(type));
|
||||
if (marketPrice != null)
|
||||
priceConsumer.accept(marketPrice.getPrice(type));
|
||||
} else {
|
||||
String errorMessage = "We don't have a price for currencyCode " + currencyCode;
|
||||
log.debug(errorMessage);
|
||||
faultHandler.handleFault(errorMessage, new PriceRequestException(errorMessage));
|
||||
}
|
||||
}
|
||||
currenciesUpdateFlag.setValue(currenciesUpdateFlag.get() + 1);
|
||||
}
|
||||
|
||||
private void requestPrice(PriceProvider provider) {
|
||||
|
@ -83,7 +83,7 @@ public final class Preferences implements Persistable {
|
||||
return defaultTradeCurrency;
|
||||
}
|
||||
|
||||
private static boolean _useAnimations = true;
|
||||
private static boolean staticUseAnimations = true;
|
||||
|
||||
transient private final Storage<Preferences> storage;
|
||||
transient private final BitsquareEnvironment bitsquareEnvironment;
|
||||
@ -107,10 +107,12 @@ public final class Preferences implements Persistable {
|
||||
private TradeCurrency preferredTradeCurrency;
|
||||
private long nonTradeTxFeePerKB = FeePolicy.getNonTradeFeePerKb().value;
|
||||
private double maxPriceDistanceInPercent;
|
||||
private boolean useInvertedMarketPrice;
|
||||
|
||||
// Observable wrappers
|
||||
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
||||
transient private final BooleanProperty useAnimationsProperty = new SimpleBooleanProperty(useAnimations);
|
||||
transient private final BooleanProperty useInvertedMarketPriceProperty = new SimpleBooleanProperty(useInvertedMarketPrice);
|
||||
transient private final ObservableList<FiatCurrency> fiatCurrenciesAsObservable = FXCollections.observableArrayList();
|
||||
transient private final ObservableList<CryptoCurrency> cryptoCurrenciesAsObservable = FXCollections.observableArrayList();
|
||||
transient private final ObservableList<TradeCurrency> tradeCurrenciesAsObservable = FXCollections.observableArrayList();
|
||||
@ -130,6 +132,7 @@ public final class Preferences implements Persistable {
|
||||
if (persisted != null) {
|
||||
setBtcDenomination(persisted.btcDenomination);
|
||||
setUseAnimations(persisted.useAnimations);
|
||||
setUseInvertedMarketPrice(persisted.useInvertedMarketPrice);
|
||||
|
||||
setFiatCurrencies(persisted.fiatCurrencies);
|
||||
fiatCurrencies = new ArrayList<>(fiatCurrenciesAsObservable);
|
||||
@ -194,7 +197,11 @@ public final class Preferences implements Persistable {
|
||||
});
|
||||
useAnimationsProperty.addListener((ov) -> {
|
||||
useAnimations = useAnimationsProperty.get();
|
||||
_useAnimations = useAnimations;
|
||||
staticUseAnimations = useAnimations;
|
||||
storage.queueUpForSave(2000);
|
||||
});
|
||||
useInvertedMarketPriceProperty.addListener((ov) -> {
|
||||
useInvertedMarketPrice = useInvertedMarketPriceProperty.get();
|
||||
storage.queueUpForSave(2000);
|
||||
});
|
||||
fiatCurrenciesAsObservable.addListener((Observable ov) -> {
|
||||
@ -229,12 +236,16 @@ public final class Preferences implements Persistable {
|
||||
// Setter
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setBtcDenomination(String btcDenominationProperty) {
|
||||
this.btcDenominationProperty.set(btcDenominationProperty);
|
||||
public void setBtcDenomination(String btcDenomination) {
|
||||
this.btcDenominationProperty.set(btcDenomination);
|
||||
}
|
||||
|
||||
public void setUseAnimations(boolean useAnimationsProperty) {
|
||||
this.useAnimationsProperty.set(useAnimationsProperty);
|
||||
public void setUseAnimations(boolean useAnimations) {
|
||||
this.useAnimationsProperty.set(useAnimations);
|
||||
}
|
||||
|
||||
public void setUseInvertedMarketPrice(boolean useInvertedMarketPrice) {
|
||||
this.useInvertedMarketPriceProperty.set(useInvertedMarketPrice);
|
||||
}
|
||||
|
||||
public void setBitcoinNetwork(BitcoinNetwork bitcoinNetwork) {
|
||||
@ -343,6 +354,11 @@ public final class Preferences implements Persistable {
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
|
||||
public boolean flipUseInvertedMarketPrice() {
|
||||
setUseInvertedMarketPrice(!getUseInvertedMarketPrice());
|
||||
return getUseInvertedMarketPrice();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getter
|
||||
@ -352,22 +368,31 @@ public final class Preferences implements Persistable {
|
||||
return btcDenominationProperty.get();
|
||||
}
|
||||
|
||||
public boolean getUseAnimations() {
|
||||
return useAnimationsProperty.get();
|
||||
}
|
||||
|
||||
public static boolean useAnimations() {
|
||||
return _useAnimations;
|
||||
}
|
||||
|
||||
public StringProperty btcDenominationProperty() {
|
||||
return btcDenominationProperty;
|
||||
}
|
||||
|
||||
public boolean getUseAnimations() {
|
||||
return useAnimationsProperty.get();
|
||||
}
|
||||
|
||||
public BooleanProperty useAnimationsProperty() {
|
||||
return useAnimationsProperty;
|
||||
}
|
||||
|
||||
|
||||
public static boolean useAnimations() {
|
||||
return staticUseAnimations;
|
||||
}
|
||||
|
||||
public boolean getUseInvertedMarketPrice() {
|
||||
return useInvertedMarketPriceProperty.get();
|
||||
}
|
||||
|
||||
public BooleanProperty useInvertedMarketPriceProperty() {
|
||||
return useInvertedMarketPriceProperty;
|
||||
}
|
||||
|
||||
public BitcoinNetwork getBitcoinNetwork() {
|
||||
return bitcoinNetwork;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY;
|
||||
public class BitsquareApp extends Application {
|
||||
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
||||
|
||||
public static final boolean DEV_MODE = false;
|
||||
public static final boolean DEV_MODE = true;
|
||||
public static final boolean IS_RELEASE_VERSION = !DEV_MODE && true;
|
||||
|
||||
private static Environment env;
|
||||
|
@ -1000,13 +1000,16 @@ textfield */
|
||||
-fx-text-fill: #dd6900;
|
||||
}
|
||||
|
||||
#price-feed-text-field {
|
||||
-fx-alignment: center;
|
||||
#price-feed-combo {
|
||||
-fx-background-color: #555;
|
||||
-fx-text-fill: white;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
#invert-market-price {
|
||||
-fx-text-fill: #111;
|
||||
}
|
||||
|
||||
#popup-qr-code-info {
|
||||
-fx-font-size: 11;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package io.bitsquare.gui.main;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.BitsquareException;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.pricefeed.PriceFeed;
|
||||
@ -36,8 +38,6 @@ import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
||||
import io.bitsquare.gui.main.settings.SettingsView;
|
||||
import io.bitsquare.gui.util.Transitions;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
@ -47,8 +47,6 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.monadic.MonadicBinding;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
@ -61,7 +59,6 @@ import static javafx.scene.layout.AnchorPane.*;
|
||||
public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
|
||||
public static final String TITLE_KEY = "view.title";
|
||||
private MonadicBinding<String> marketPriceBinding;
|
||||
|
||||
public static StackPane getRootContainer() {
|
||||
return MainView.rootContainer;
|
||||
@ -92,7 +89,6 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
private final ViewLoader viewLoader;
|
||||
private final Navigation navigation;
|
||||
private static Transitions transitions;
|
||||
private final String title;
|
||||
private ChangeListener<String> walletServiceErrorMsgListener;
|
||||
private ChangeListener<String> btcSyncIconIdListener;
|
||||
private ChangeListener<String> splashP2PNetworkErrorMsgListener;
|
||||
@ -106,6 +102,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
private BorderPane baseApplicationContainer;
|
||||
private Overlay<Popup> p2PNetworkWarnMsgPopup, btcNetworkWarnMsgPopup;
|
||||
private static StackPane rootContainer;
|
||||
private ChangeListener<PriceFeedComboBoxItem> selectedPriceFeedItemListender;
|
||||
|
||||
@Inject
|
||||
public MainView(MainViewModel model, CachingViewLoader viewLoader, Navigation navigation, Transitions transitions,
|
||||
@ -114,7 +111,6 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
this.viewLoader = viewLoader;
|
||||
this.navigation = navigation;
|
||||
MainView.transitions = transitions;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -138,22 +134,19 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
setTopAnchor(this, 0d);
|
||||
}};
|
||||
|
||||
Tuple3<TextField, Label, VBox> marketPriceBox = getMarketPriceBox("Market price");
|
||||
final BooleanProperty priceInverted = new SimpleBooleanProperty(false);
|
||||
marketPriceBox.first.setOnMouseClicked(e -> priceInverted.setValue(!priceInverted.get()));
|
||||
marketPriceBinding = EasyBind.combine(
|
||||
model.marketPriceCurrency, model.marketPrice, model.marketPriceInverted, priceInverted,
|
||||
(marketPriceCurrency, marketPrice, marketPriceInverted, inverted) ->
|
||||
(priceInverted.get() ?
|
||||
marketPriceInverted :
|
||||
marketPrice) +
|
||||
(priceInverted.get() ?
|
||||
" BTC/" + marketPriceCurrency :
|
||||
" " + marketPriceCurrency + "/BTC"));
|
||||
Tuple3<ComboBox<PriceFeedComboBoxItem>, Label, VBox> marketPriceBox = getMarketPriceBox("Market price");
|
||||
ComboBox<PriceFeedComboBoxItem> priceComboBox = marketPriceBox.first;
|
||||
|
||||
priceComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||
model.setPriceFeedComboBoxItem(newValue);
|
||||
|
||||
marketPriceBinding.subscribe((observable, oldValue, newValue) -> {
|
||||
marketPriceBox.first.setText(newValue);
|
||||
});
|
||||
selectedPriceFeedItemListender = (observable, oldValue, newValue) -> {
|
||||
priceComboBox.getSelectionModel().select(newValue);
|
||||
|
||||
};
|
||||
model.selectedPriceFeedComboBoxItemProperty.addListener(selectedPriceFeedItemListender);
|
||||
priceComboBox.setItems(model.priceFeedComboBoxItems);
|
||||
|
||||
marketPriceBox.second.textProperty().bind(createStringBinding(
|
||||
() -> {
|
||||
@ -268,22 +261,56 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
return new Tuple2(textField, vBox);
|
||||
}
|
||||
|
||||
private Tuple3<TextField, Label, VBox> getMarketPriceBox(String text) {
|
||||
TextField textField = new TextField();
|
||||
textField.setEditable(false);
|
||||
textField.setPrefWidth(180);
|
||||
textField.setFocusTraversable(false);
|
||||
textField.setId("price-feed-text-field");
|
||||
private ListCell<PriceFeedComboBoxItem> getPriceFeedComboBoxListCell() {
|
||||
return new ListCell<PriceFeedComboBoxItem>() {
|
||||
@Override
|
||||
protected void updateItem(PriceFeedComboBoxItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (!empty && item != null) {
|
||||
textProperty().bind(item.displayStringProperty);
|
||||
} else {
|
||||
textProperty().unbind();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Tuple3<ComboBox<PriceFeedComboBoxItem>, Label, VBox> getMarketPriceBox(String text) {
|
||||
ComboBox<PriceFeedComboBoxItem> priceComboBox = new ComboBox<>();
|
||||
priceComboBox.setVisibleRowCount(40);
|
||||
priceComboBox.setMaxWidth(210);
|
||||
priceComboBox.setMinWidth(210);
|
||||
priceComboBox.setFocusTraversable(false);
|
||||
priceComboBox.setId("price-feed-combo");
|
||||
priceComboBox.setCellFactory(p -> getPriceFeedComboBoxListCell());
|
||||
ListCell<PriceFeedComboBoxItem> buttonCell = getPriceFeedComboBoxListCell();
|
||||
buttonCell.setId("price-feed-combo");
|
||||
priceComboBox.setButtonCell(buttonCell);
|
||||
|
||||
Label invertIcon = new Label();
|
||||
HBox.setMargin(invertIcon, new Insets(3, 0, 0, 0));
|
||||
invertIcon.setId("invert-market-price");
|
||||
invertIcon.setOpacity(0.8);
|
||||
invertIcon.setOnMouseClicked(e -> {
|
||||
model.preferences.flipUseInvertedMarketPrice();
|
||||
});
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setSpacing(5);
|
||||
AwesomeDude.setIcon(invertIcon, AwesomeIcon.RETWEET, "14.0");
|
||||
hBox.getChildren().setAll(priceComboBox, invertIcon);
|
||||
|
||||
Label label = new Label(text);
|
||||
label.setId("nav-balance-label");
|
||||
label.setPadding(new Insets(0, 5, 0, 5));
|
||||
label.setPrefWidth(textField.getPrefWidth());
|
||||
label.setTextAlignment(TextAlignment.CENTER);
|
||||
label.setPadding(new Insets(0, 25, 0, 5));
|
||||
label.prefWidthProperty().bind(hBox.widthProperty());
|
||||
|
||||
VBox vBox = new VBox();
|
||||
vBox.setSpacing(3);
|
||||
vBox.setPadding(new Insets(11, 0, 0, 0));
|
||||
vBox.getChildren().addAll(textField, label);
|
||||
return new Tuple3(textField, label, vBox);
|
||||
vBox.getChildren().addAll(hBox, label);
|
||||
return new Tuple3(priceComboBox, label, vBox);
|
||||
}
|
||||
|
||||
public void setPersistedFilesCorrupted(List<String> persistedFilesCorrupted) {
|
||||
|
@ -30,6 +30,7 @@ import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.pricefeed.MarketPrice;
|
||||
import io.bitsquare.btc.pricefeed.PriceFeed;
|
||||
import io.bitsquare.common.Clock;
|
||||
import io.bitsquare.common.Timer;
|
||||
@ -48,6 +49,7 @@ import io.bitsquare.gui.main.overlays.windows.TacWindow;
|
||||
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.P2PServiceListener;
|
||||
import io.bitsquare.p2p.network.CloseConnectionReason;
|
||||
@ -57,14 +59,14 @@ import io.bitsquare.p2p.peers.keepalive.messages.Ping;
|
||||
import io.bitsquare.payment.OKPayAccount;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.closed.ClosedTradableManager;
|
||||
import io.bitsquare.trade.failed.FailedTradesManager;
|
||||
import io.bitsquare.trade.offer.OpenOffer;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
@ -76,10 +78,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
@ -94,7 +93,7 @@ public class MainViewModel implements ViewModel {
|
||||
private final TradeManager tradeManager;
|
||||
private final OpenOfferManager openOfferManager;
|
||||
private final DisputeManager disputeManager;
|
||||
private final Preferences preferences;
|
||||
final Preferences preferences;
|
||||
private final AlertManager alertManager;
|
||||
private final WalletPasswordWindow walletPasswordWindow;
|
||||
private final NotificationCenter notificationCenter;
|
||||
@ -113,6 +112,7 @@ public class MainViewModel implements ViewModel {
|
||||
final StringProperty marketPriceInverted = new SimpleStringProperty("N/A");
|
||||
final StringProperty marketPriceCurrency = new SimpleStringProperty("");
|
||||
final ObjectProperty<PriceFeed.Type> typeProperty = new SimpleObjectProperty<>(PriceFeed.Type.LAST);
|
||||
final ObjectProperty<PriceFeedComboBoxItem> selectedPriceFeedComboBoxItemProperty = new SimpleObjectProperty<>();
|
||||
final StringProperty availableBalance = new SimpleStringProperty();
|
||||
final StringProperty reservedBalance = new SimpleStringProperty();
|
||||
final StringProperty lockedBalance = new SimpleStringProperty();
|
||||
@ -139,15 +139,16 @@ public class MainViewModel implements ViewModel {
|
||||
final StringProperty p2pNetworkLabelId = new SimpleStringProperty("footer-pane");
|
||||
|
||||
private MonadicBinding<Boolean> allServicesDone, tradesAndUIReady;
|
||||
private final PriceFeed priceFeed;
|
||||
private final ClosedTradableManager closedTradableManager;
|
||||
private final FailedTradesManager failedTradesManager;
|
||||
final PriceFeed priceFeed;
|
||||
private final User user;
|
||||
private int numBtcPeers = 0;
|
||||
private Timer checkNumberOfBtcPeersTimer;
|
||||
private Timer checkNumberOfP2pNetworkPeersTimer;
|
||||
private Timer startupTimeout;
|
||||
private final Map<String, Subscription> disputeIsClosedSubscriptionsMap = new HashMap<>();
|
||||
final ObservableList<PriceFeedComboBoxItem> priceFeedComboBoxItems = FXCollections.observableArrayList();
|
||||
private MonadicBinding<String> marketPriceBinding;
|
||||
private Subscription priceFeedAllLoadedSubscription;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -158,14 +159,11 @@ public class MainViewModel implements ViewModel {
|
||||
public MainViewModel(WalletService walletService, TradeWalletService tradeWalletService,
|
||||
PriceFeed priceFeed,
|
||||
ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager,
|
||||
OpenOfferManager openOfferManager, ClosedTradableManager closedTradableManager,
|
||||
FailedTradesManager failedTradesManager, DisputeManager disputeManager, Preferences preferences,
|
||||
OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences,
|
||||
User user, AlertManager alertManager, WalletPasswordWindow walletPasswordWindow,
|
||||
NotificationCenter notificationCenter, TacWindow tacWindow, Clock clock,
|
||||
KeyRing keyRing, Navigation navigation, BSFormatter formatter) {
|
||||
this.priceFeed = priceFeed;
|
||||
this.closedTradableManager = closedTradableManager;
|
||||
this.failedTradesManager = failedTradesManager;
|
||||
this.user = user;
|
||||
this.walletService = walletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
@ -472,6 +470,7 @@ public class MainViewModel implements ViewModel {
|
||||
setupDevDummyPaymentAccount();
|
||||
setupMarketPriceFeed();
|
||||
swapPendingOfferFundingEntries();
|
||||
fillPriceFeedComboBoxItems();
|
||||
|
||||
showAppScreen.set(true);
|
||||
|
||||
@ -666,7 +665,7 @@ public class MainViewModel implements ViewModel {
|
||||
priceFeed.setType(PriceFeed.Type.LAST);
|
||||
priceFeed.init(price -> {
|
||||
marketPrice.set(formatter.formatMarketPrice(price));
|
||||
marketPriceInverted.set(formatter.formatMarketPrice(1 / price, 8));
|
||||
marketPriceInverted.set(price != 0 ? formatter.formatMarketPrice(1 / price, 8) : "");
|
||||
},
|
||||
(errorMessage, throwable) -> {
|
||||
marketPrice.set("N/A");
|
||||
@ -674,6 +673,74 @@ public class MainViewModel implements ViewModel {
|
||||
});
|
||||
marketPriceCurrency.bind(priceFeed.currencyCodeProperty());
|
||||
typeProperty.bind(priceFeed.typeProperty());
|
||||
|
||||
marketPriceBinding = EasyBind.combine(
|
||||
marketPriceCurrency, marketPrice, marketPriceInverted, preferences.useInvertedMarketPriceProperty(),
|
||||
(marketPriceCurrency, marketPrice, marketPriceInverted, useInvertedMarketPrice) ->
|
||||
(useInvertedMarketPrice ? marketPriceInverted : marketPrice) +
|
||||
(useInvertedMarketPrice ? " BTC/" + marketPriceCurrency : " " + marketPriceCurrency + "/BTC"));
|
||||
|
||||
marketPriceBinding.subscribe((observable, oldValue, newValue) -> {
|
||||
if (selectedPriceFeedComboBoxItemProperty.get() == null) {
|
||||
findPriceFeedComboBoxItem(preferences.getPreferredTradeCurrency().getCode())
|
||||
.ifPresent(item -> {
|
||||
item.setDisplayString(newValue);
|
||||
selectedPriceFeedComboBoxItemProperty.set(item);
|
||||
});
|
||||
}
|
||||
if (selectedPriceFeedComboBoxItemProperty.get() != null)
|
||||
selectedPriceFeedComboBoxItemProperty.get().setDisplayString(newValue);
|
||||
});
|
||||
|
||||
priceFeedAllLoadedSubscription = EasyBind.subscribe(priceFeed.currenciesUpdateFlagProperty(), newPriceUpdate -> {
|
||||
priceFeedComboBoxItems.stream().forEach(item -> {
|
||||
String currencyCode = item.currencyCode;
|
||||
MarketPrice marketPrice = priceFeed.getMarketPrice(currencyCode);
|
||||
boolean useInvertedMarketPrice = preferences.getUseInvertedMarketPrice();
|
||||
String priceString;
|
||||
String currencyPairString = useInvertedMarketPrice ? "BTC/" + currencyCode : currencyCode + "/BTC";
|
||||
if (marketPrice != null) {
|
||||
double price = marketPrice.getPrice(priceFeed.getType());
|
||||
if (price != 0) {
|
||||
double priceInverted = 1 / price;
|
||||
priceString = useInvertedMarketPrice ? formatter.formatMarketPrice(priceInverted, 8) : formatter.formatMarketPrice(price);
|
||||
} else {
|
||||
priceString = "N/A";
|
||||
}
|
||||
} else {
|
||||
priceString = "N/A";
|
||||
}
|
||||
item.setDisplayString(priceString + " " + currencyPairString);
|
||||
});
|
||||
});
|
||||
|
||||
preferences.getTradeCurrenciesAsObservable().addListener((ListChangeListener<TradeCurrency>) c -> {
|
||||
UserThread.runAfter(() -> fillPriceFeedComboBoxItems(), 100, TimeUnit.MILLISECONDS);
|
||||
});
|
||||
}
|
||||
|
||||
public void setPriceFeedComboBoxItem(PriceFeedComboBoxItem item) {
|
||||
if (item != null) {
|
||||
selectedPriceFeedComboBoxItemProperty.set(item);
|
||||
priceFeed.setCurrencyCode(item.currencyCode);
|
||||
} else {
|
||||
findPriceFeedComboBoxItem(preferences.getPreferredTradeCurrency().getCode())
|
||||
.ifPresent(item2 -> selectedPriceFeedComboBoxItemProperty.set(item2));
|
||||
}
|
||||
}
|
||||
|
||||
Optional<PriceFeedComboBoxItem> findPriceFeedComboBoxItem(String currencyCode) {
|
||||
return priceFeedComboBoxItems.stream()
|
||||
.filter(item -> item.currencyCode.equals(currencyCode))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
private void fillPriceFeedComboBoxItems() {
|
||||
List<PriceFeedComboBoxItem> currencyItems = preferences.getTradeCurrenciesAsObservable()
|
||||
.stream()
|
||||
.map(tradeCurrency -> new PriceFeedComboBoxItem(tradeCurrency.getCode()))
|
||||
.collect(Collectors.toList());
|
||||
priceFeedComboBoxItems.setAll(currencyItems);
|
||||
}
|
||||
|
||||
private void displayAlertIfPresent(Alert alert) {
|
||||
|
@ -0,0 +1,25 @@
|
||||
package io.bitsquare.gui.main;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PriceFeedComboBoxItem {
|
||||
private static final Logger log = LoggerFactory.getLogger(PriceFeedComboBoxItem.class);
|
||||
|
||||
public final String currencyCode;
|
||||
public final StringProperty displayStringProperty = new SimpleStringProperty();
|
||||
|
||||
public PriceFeedComboBoxItem(String currencyCode) {
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
public String getDisplayString() {
|
||||
return displayStringProperty.get();
|
||||
}
|
||||
|
||||
public void setDisplayString(String displayString) {
|
||||
this.displayStringProperty.set(displayString);
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||
offerBookListItems.addListener(listChangeListener);
|
||||
offerBook.fillOfferBookListItems();
|
||||
updateChartData(offerBookListItems);
|
||||
priceFeed.setCurrencyCode(tradeCurrency.get().getCode());
|
||||
//priceFeed.setCurrencyCode(tradeCurrency.get().getCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,7 +136,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
||||
this.tradeCurrency.set(tradeCurrency);
|
||||
updateChartData(offerBookListItems);
|
||||
priceFeed.setCurrencyCode(tradeCurrency.getCode());
|
||||
//priceFeed.setCurrencyCode(tradeCurrency.getCode());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -175,8 +175,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
|
||||
paymentAccounts.setAll(user.getPaymentAccounts());
|
||||
|
||||
if (isTabSelected)
|
||||
priceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
/*if (isTabSelected)
|
||||
priceFeed.setCurrencyCode(tradeCurrencyCode.get());*/
|
||||
|
||||
updateBalance();
|
||||
}
|
||||
@ -220,7 +220,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
if (account != null)
|
||||
paymentAccount = account;
|
||||
|
||||
priceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
//priceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
|
||||
calculateVolume();
|
||||
calculateTotalToPay();
|
||||
@ -228,8 +228,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
|
||||
void onTabSelected(boolean isSelected) {
|
||||
this.isTabSelected = isSelected;
|
||||
if (isTabSelected)
|
||||
priceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
/*if (isTabSelected)
|
||||
priceFeed.setCurrencyCode(tradeCurrencyCode.get());*/
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -299,7 +299,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
if (paymentAccount != null)
|
||||
paymentAccount.setSelectedTradeCurrency(tradeCurrency);
|
||||
|
||||
priceFeed.setCurrencyCode(code);
|
||||
//priceFeed.setCurrencyCode(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,12 +158,12 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
}
|
||||
|
||||
private void setMarketPriceFeedCurrency() {
|
||||
if (isTabSelected) {
|
||||
/*if (isTabSelected) {
|
||||
if (showAllTradeCurrenciesProperty.get())
|
||||
priceFeed.setCurrencyCode(CurrencyUtil.getDefaultTradeCurrency().getCode());
|
||||
else
|
||||
priceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -136,7 +136,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||
// if (isWalletFunded.get())
|
||||
// feeFromFundingTxProperty.set(FeePolicy.getMinRequiredFeeForFundingTx());
|
||||
|
||||
if (isTabSelected)
|
||||
/*if (isTabSelected)*/
|
||||
priceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||
|
||||
tradeManager.checkOfferAvailability(offer, () -> {
|
||||
@ -207,13 +207,13 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||
};
|
||||
|
||||
offer.resetState();
|
||||
priceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||
//priceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||
}
|
||||
|
||||
void onTabSelected(boolean isSelected) {
|
||||
this.isTabSelected = isSelected;
|
||||
if (isTabSelected)
|
||||
priceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||
/*if (isTabSelected)
|
||||
priceFeed.setCurrencyCode(offer.getCurrencyCode());*/
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user