mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-17 10:50:55 -04:00
Add market price feed
This commit is contained in:
parent
30f7ca69f8
commit
d2e8c6afd7
37 changed files with 676 additions and 102 deletions
|
@ -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;
|
||||
|
@ -153,7 +153,7 @@ public class BitsquareApp extends Application {
|
|||
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
|
||||
});*/
|
||||
|
||||
scene = new Scene(mainView.getRoot(), 1000, 740);
|
||||
scene = new Scene(mainView.getRoot(), 1100, 740);
|
||||
scene.getStylesheets().setAll(
|
||||
"/io/bitsquare/gui/bitsquare.css",
|
||||
"/io/bitsquare/gui/images.css");
|
||||
|
|
|
@ -19,8 +19,10 @@ package io.bitsquare.gui.main;
|
|||
|
||||
import io.bitsquare.BitsquareException;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Tuple3;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.view.*;
|
||||
import io.bitsquare.gui.main.account.AccountView;
|
||||
|
@ -47,6 +49,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import java.util.List;
|
||||
|
||||
import static javafx.beans.binding.Bindings.createStringBinding;
|
||||
import static javafx.scene.layout.AnchorPane.*;
|
||||
|
||||
@FxmlView
|
||||
|
@ -121,6 +124,22 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
setTopAnchor(this, 0d);
|
||||
}};
|
||||
|
||||
Tuple3<TextField, Label, VBox> marketPriceBox = getMarketPriceBox("Market price");
|
||||
marketPriceBox.first.textProperty().bind(createStringBinding(
|
||||
() -> {
|
||||
return model.marketPrice.get() + " " +
|
||||
model.marketPriceCurrency.get() + "/BTC";
|
||||
},
|
||||
model.marketPriceCurrency, model.marketPrice));
|
||||
marketPriceBox.second.textProperty().bind(createStringBinding(
|
||||
() -> {
|
||||
MarketPriceFeed.Type type = model.typeProperty.get();
|
||||
return type != null ? "Market price (" + type.name + ")" : "";
|
||||
},
|
||||
model.marketPriceCurrency, model.typeProperty));
|
||||
HBox.setMargin(marketPriceBox.third, new Insets(0, 20, 0, 0));
|
||||
|
||||
|
||||
Tuple2<TextField, VBox> availableBalanceBox = getBalanceBox("Available balance");
|
||||
availableBalanceBox.first.textProperty().bind(model.availableBalance);
|
||||
|
||||
|
@ -130,7 +149,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
Tuple2<TextField, VBox> lockedBalanceBox = getBalanceBox("Locked balance");
|
||||
lockedBalanceBox.first.textProperty().bind(model.lockedBalance);
|
||||
|
||||
HBox rightNavPane = new HBox(availableBalanceBox.second, reservedBalanceBox.second, lockedBalanceBox.second,
|
||||
HBox rightNavPane = new HBox(marketPriceBox.third, availableBalanceBox.second, reservedBalanceBox.second, lockedBalanceBox.second,
|
||||
settingsButton, accountButton) {{
|
||||
setSpacing(10);
|
||||
setRightAnchor(this, 10d);
|
||||
|
@ -225,6 +244,25 @@ 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(140);
|
||||
textField.setMouseTransparent(true);
|
||||
textField.setFocusTraversable(false);
|
||||
textField.setStyle("-fx-alignment: center; -fx-background-color: -bs-bg-grey;");
|
||||
|
||||
Label label = new Label(text);
|
||||
label.setId("nav-balance-label");
|
||||
label.setPadding(new Insets(0, 5, 0, 5));
|
||||
label.setPrefWidth(textField.getPrefWidth());
|
||||
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);
|
||||
}
|
||||
|
||||
public void setPersistedFilesCorrupted(List<String> persistedFilesCorrupted) {
|
||||
this.persistedFilesCorrupted = persistedFilesCorrupted;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import io.bitsquare.arbitration.Dispute;
|
|||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.model.ViewModel;
|
||||
|
@ -99,6 +100,9 @@ public class MainViewModel implements ViewModel {
|
|||
final DoubleProperty btcSyncProgress = new SimpleDoubleProperty(-1);
|
||||
final StringProperty walletServiceErrorMsg = new SimpleStringProperty();
|
||||
final StringProperty btcSplashSyncIconId = new SimpleStringProperty();
|
||||
final StringProperty marketPrice = new SimpleStringProperty("N/A");
|
||||
final StringProperty marketPriceCurrency = new SimpleStringProperty("");
|
||||
final ObjectProperty<MarketPriceFeed.Type> typeProperty = new SimpleObjectProperty<>(MarketPriceFeed.Type.LAST);
|
||||
final StringProperty availableBalance = new SimpleStringProperty();
|
||||
final StringProperty reservedBalance = new SimpleStringProperty();
|
||||
final StringProperty lockedBalance = new SimpleStringProperty();
|
||||
|
@ -123,6 +127,7 @@ public class MainViewModel implements ViewModel {
|
|||
final StringProperty p2PNetworkLabelId = new SimpleStringProperty("footer-pane");
|
||||
|
||||
private MonadicBinding<Boolean> allServicesDone, tradesAndUIReady;
|
||||
private MarketPriceFeed marketPriceFeed;
|
||||
private final User user;
|
||||
private int numBTCPeers = 0;
|
||||
private Timer checkForBtcSyncStateTimer;
|
||||
|
@ -138,10 +143,12 @@ public class MainViewModel implements ViewModel {
|
|||
|
||||
@Inject
|
||||
public MainViewModel(WalletService walletService, TradeWalletService tradeWalletService,
|
||||
MarketPriceFeed marketPriceFeed,
|
||||
ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager,
|
||||
OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences,
|
||||
User user, AlertManager alertManager, WalletPasswordPopup walletPasswordPopup,
|
||||
Navigation navigation, BSFormatter formatter) {
|
||||
this.marketPriceFeed = marketPriceFeed;
|
||||
this.user = user;
|
||||
this.walletService = walletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
|
@ -497,6 +504,19 @@ public class MainViewModel implements ViewModel {
|
|||
okPayAccount.setCountry(CountryUtil.getDefaultCountry());
|
||||
user.addPaymentAccount(okPayAccount);
|
||||
}
|
||||
|
||||
if (marketPriceFeed.getCurrencyCode() == null)
|
||||
marketPriceFeed.setCurrencyCode(preferences.getPreferredTradeCurrency().getCode());
|
||||
if (marketPriceFeed.getType() == null)
|
||||
marketPriceFeed.setType(MarketPriceFeed.Type.LAST);
|
||||
marketPriceFeed.init(price -> {
|
||||
marketPrice.set(formatter.formatMarketPrice(price));
|
||||
},
|
||||
(errorMessage, throwable) -> {
|
||||
marketPrice.set("N/A");
|
||||
});
|
||||
marketPriceCurrency.bind(marketPriceFeed.currencyCodeProperty());
|
||||
typeProperty.bind(marketPriceFeed.typeProperty());
|
||||
}
|
||||
|
||||
private void checkPeriodicallyForBtcSyncState() {
|
||||
|
|
|
@ -19,6 +19,7 @@ package io.bitsquare.gui.main.markets.charts;
|
|||
|
||||
import com.google.common.math.LongMath;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||
import io.bitsquare.gui.main.offer.offerbook.OfferBook;
|
||||
import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem;
|
||||
|
@ -41,6 +42,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
|||
|
||||
private final OfferBook offerBook;
|
||||
private final Preferences preferences;
|
||||
private MarketPriceFeed marketPriceFeed;
|
||||
|
||||
final ObjectProperty<TradeCurrency> tradeCurrency = new SimpleObjectProperty<>(CurrencyUtil.getDefaultTradeCurrency());
|
||||
private final List<XYChart.Data> buyData = new ArrayList();
|
||||
|
@ -56,9 +58,10 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public MarketsChartsViewModel(OfferBook offerBook, Preferences preferences) {
|
||||
public MarketsChartsViewModel(OfferBook offerBook, Preferences preferences, MarketPriceFeed marketPriceFeed) {
|
||||
this.offerBook = offerBook;
|
||||
this.preferences = preferences;
|
||||
this.marketPriceFeed = marketPriceFeed;
|
||||
|
||||
offerBookListItems = offerBook.getOfferBookListItems();
|
||||
listChangeListener = c -> updateChartData(offerBookListItems);
|
||||
|
@ -66,9 +69,11 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
|||
|
||||
@Override
|
||||
protected void activate() {
|
||||
marketPriceFeed.setType(MarketPriceFeed.Type.LAST);
|
||||
offerBookListItems.addListener(listChangeListener);
|
||||
offerBook.fillOfferBookListItems();
|
||||
updateChartData(offerBookListItems);
|
||||
marketPriceFeed.setCurrencyCode(tradeCurrency.get().getCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,6 +139,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
|||
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
||||
this.tradeCurrency.set(tradeCurrency);
|
||||
updateChartData(offerBookListItems);
|
||||
marketPriceFeed.setCurrencyCode(tradeCurrency.getCode());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.main.offer;
|
||||
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.common.view.ViewLoader;
|
||||
|
@ -27,8 +28,8 @@ import javax.inject.Inject;
|
|||
public class BuyOfferView extends OfferView {
|
||||
|
||||
@Inject
|
||||
public BuyOfferView(ViewLoader viewLoader, Navigation navigation) {
|
||||
super(viewLoader, navigation);
|
||||
public BuyOfferView(ViewLoader viewLoader, Navigation navigation, MarketPriceFeed marketPriceFeed) {
|
||||
super(viewLoader, navigation, marketPriceFeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.main.offer;
|
||||
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
|
@ -50,15 +51,16 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
private final ViewLoader viewLoader;
|
||||
private final Navigation navigation;
|
||||
private MarketPriceFeed marketPriceFeed;
|
||||
private final Offer.Direction direction;
|
||||
private Tab createOfferTab;
|
||||
private Tab takeOfferTab;
|
||||
private Tab takeOfferTab, createOfferTab, offerBookTab;
|
||||
private TradeCurrency tradeCurrency;
|
||||
private boolean createOfferViewOpen, takeOfferViewOpen;
|
||||
|
||||
protected OfferView(ViewLoader viewLoader, Navigation navigation) {
|
||||
protected OfferView(ViewLoader viewLoader, Navigation navigation, MarketPriceFeed marketPriceFeed) {
|
||||
this.viewLoader = viewLoader;
|
||||
this.navigation = navigation;
|
||||
this.marketPriceFeed = marketPriceFeed;
|
||||
this.direction = (this instanceof BuyOfferView) ? Offer.Direction.BUY : Offer.Direction.SELL;
|
||||
}
|
||||
|
||||
|
@ -76,8 +78,19 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
|||
// UserThread.execute needed as focus-out event is called after selectedIndexProperty changed
|
||||
// TODO Find a way to do that in the InputTextField directly, but a tab change does not trigger any event...
|
||||
TabPane tabPane = root;
|
||||
tabPane.getSelectionModel().selectedIndexProperty()
|
||||
.addListener((observableValue, oldValue, newValue) -> UserThread.execute(InputTextField::hideErrorMessageDisplay));
|
||||
tabPane.getSelectionModel().selectedItemProperty()
|
||||
.addListener((observableValue, oldValue, newValue) -> {
|
||||
UserThread.execute(InputTextField::hideErrorMessageDisplay);
|
||||
if (newValue != null) {
|
||||
if (newValue.equals(createOfferTab) && createOfferView != null) {
|
||||
createOfferView.onTabSelected();
|
||||
} else if (newValue.equals(takeOfferTab) && takeOfferView != null) {
|
||||
takeOfferView.onTabSelected();
|
||||
} else if (newValue.equals(offerBookTab) && offerBookView != null) {
|
||||
offerBookView.onTabSelected();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// We want to get informed when a tab get closed
|
||||
tabPane.getTabs().addListener((ListChangeListener<Tab>) change -> {
|
||||
|
@ -105,14 +118,17 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
|||
private void loadView(Class<? extends View> viewClass) {
|
||||
TabPane tabPane = root;
|
||||
View view;
|
||||
boolean isBuy = direction == Offer.Direction.BUY;
|
||||
|
||||
marketPriceFeed.setType(isBuy ? MarketPriceFeed.Type.ASK : MarketPriceFeed.Type.BID);
|
||||
|
||||
if (viewClass == OfferBookView.class && offerBookView == null) {
|
||||
view = viewLoader.load(viewClass);
|
||||
// Offerbook must not be cached by ViewLoader as we use 2 instances for sell and buy screens.
|
||||
final Tab tab = new Tab(direction == Offer.Direction.BUY ? "Buy bitcoin" : "Sell bitcoin");
|
||||
tab.setClosable(false);
|
||||
tab.setContent(view.getRoot());
|
||||
tabPane.getTabs().add(tab);
|
||||
offerBookTab = new Tab(isBuy ? "Buy bitcoin" : "Sell bitcoin");
|
||||
offerBookTab.setClosable(false);
|
||||
offerBookTab.setContent(view.getRoot());
|
||||
tabPane.getTabs().add(offerBookTab);
|
||||
offerBookView = (OfferBookView) view;
|
||||
|
||||
OfferActionHandler offerActionHandler = new OfferActionHandler() {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.main.offer;
|
||||
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.common.view.ViewLoader;
|
||||
|
@ -27,8 +28,8 @@ import javax.inject.Inject;
|
|||
public class SellOfferView extends OfferView {
|
||||
|
||||
@Inject
|
||||
public SellOfferView(ViewLoader viewLoader, Navigation navigation) {
|
||||
super(viewLoader, navigation);
|
||||
public SellOfferView(ViewLoader viewLoader, Navigation navigation, MarketPriceFeed marketPriceFeed) {
|
||||
super(viewLoader, navigation, marketPriceFeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,12 +22,10 @@ import com.google.common.util.concurrent.Futures;
|
|||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.blockchain.BlockchainService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
|
@ -72,6 +70,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
private final User user;
|
||||
private final KeyRing keyRing;
|
||||
private final P2PService p2PService;
|
||||
private MarketPriceFeed marketPriceFeed;
|
||||
private final WalletPasswordPopup walletPasswordPopup;
|
||||
private BlockchainService blockchainService;
|
||||
private final BSFormatter formatter;
|
||||
|
@ -112,7 +111,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
|
||||
@Inject
|
||||
CreateOfferDataModel(OpenOfferManager openOfferManager, WalletService walletService, TradeWalletService tradeWalletService,
|
||||
Preferences preferences, User user, KeyRing keyRing, P2PService p2PService,
|
||||
Preferences preferences, User user, KeyRing keyRing, P2PService p2PService, MarketPriceFeed marketPriceFeed,
|
||||
WalletPasswordPopup walletPasswordPopup, BlockchainService blockchainService, BSFormatter formatter) {
|
||||
this.openOfferManager = openOfferManager;
|
||||
this.walletService = walletService;
|
||||
|
@ -121,6 +120,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
this.user = user;
|
||||
this.keyRing = keyRing;
|
||||
this.p2PService = p2PService;
|
||||
this.marketPriceFeed = marketPriceFeed;
|
||||
this.walletPasswordPopup = walletPasswordPopup;
|
||||
this.blockchainService = blockchainService;
|
||||
this.formatter = formatter;
|
||||
|
@ -223,8 +223,13 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
PaymentAccount account = user.findFirstPaymentAccountWithCurrency(tradeCurrency);
|
||||
if (account != null)
|
||||
paymentAccount = account;
|
||||
|
||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
}
|
||||
|
||||
void onTabSelected() {
|
||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
|
@ -283,9 +288,12 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
public void onCurrencySelected(TradeCurrency tradeCurrency) {
|
||||
if (tradeCurrency != null) {
|
||||
this.tradeCurrency = tradeCurrency;
|
||||
tradeCurrencyCode.set(tradeCurrency.getCode());
|
||||
String code = tradeCurrency.getCode();
|
||||
tradeCurrencyCode.set(code);
|
||||
|
||||
paymentAccount.setSelectedTradeCurrency(tradeCurrency);
|
||||
|
||||
marketPriceFeed.setCurrencyCode(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,24 +338,28 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
return feeFromFundingTxProperty.get().compareTo(FeePolicy.getMinRequiredFeeForFundingTx()) >= 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Utils
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void requestFeeFromBlockchain(String transactionId) {
|
||||
SettableFuture<Coin> future = blockchainService.requestFeeFromBlockchain(transactionId);
|
||||
Futures.addCallback(future, new FutureCallback<Coin>() {
|
||||
public void onSuccess(Coin fee) {
|
||||
UserThread.execute(() -> feeFromFundingTxProperty.set(fee));
|
||||
}
|
||||
if (preferences.getBitcoinNetwork() == BitcoinNetwork.MAINNET) {
|
||||
SettableFuture<Coin> future = blockchainService.requestFee(transactionId);
|
||||
Futures.addCallback(future, new FutureCallback<Coin>() {
|
||||
public void onSuccess(Coin fee) {
|
||||
UserThread.execute(() -> feeFromFundingTxProperty.set(fee));
|
||||
}
|
||||
|
||||
public void onFailure(@NotNull Throwable throwable) {
|
||||
UserThread.execute(() -> new Popup()
|
||||
.warning("We did not get a response for the request of the mining fee used in the funding transaction.")
|
||||
.show());
|
||||
}
|
||||
});
|
||||
public void onFailure(@NotNull Throwable throwable) {
|
||||
UserThread.execute(() -> new Popup()
|
||||
.warning("We did not get a response for the request of the mining fee used in the funding transaction.")
|
||||
.show());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
feeFromFundingTxProperty.set(FeePolicy.getMinRequiredFeeForFundingTx());
|
||||
}
|
||||
}
|
||||
|
||||
void calculateVolume() {
|
||||
|
|
|
@ -201,6 +201,9 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
|||
this.closeHandler = closeHandler;
|
||||
}
|
||||
|
||||
public void onTabSelected() {
|
||||
model.dataModel.onTabSelected();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
|
|
|
@ -105,7 +105,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
|||
|
||||
@Inject
|
||||
public CreateOfferViewModel(CreateOfferDataModel dataModel, FiatValidator fiatValidator, BtcValidator btcValidator,
|
||||
P2PService p2PService,
|
||||
P2PService p2PService,
|
||||
BSFormatter formatter) {
|
||||
super(dataModel);
|
||||
|
||||
|
|
|
@ -197,6 +197,10 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
this.offerActionHandler = offerActionHandler;
|
||||
}
|
||||
|
||||
public void onTabSelected() {
|
||||
model.onTabSelected();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
|
|
|
@ -19,6 +19,7 @@ package io.bitsquare.gui.main.offer.offerbook;
|
|||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||
|
@ -52,6 +53,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
private final OfferBook offerBook;
|
||||
private final Preferences preferences;
|
||||
private final P2PService p2PService;
|
||||
private MarketPriceFeed marketPriceFeed;
|
||||
final BSFormatter formatter;
|
||||
|
||||
private final FilteredList<OfferBookListItem> filteredItems;
|
||||
|
@ -72,7 +74,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
|
||||
@Inject
|
||||
public OfferBookViewModel(User user, OpenOfferManager openOfferManager, OfferBook offerBook,
|
||||
Preferences preferences, P2PService p2PService,
|
||||
Preferences preferences, P2PService p2PService, MarketPriceFeed marketPriceFeed,
|
||||
BSFormatter formatter) {
|
||||
super();
|
||||
|
||||
|
@ -81,6 +83,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
this.offerBook = offerBook;
|
||||
this.preferences = preferences;
|
||||
this.p2PService = p2PService;
|
||||
this.marketPriceFeed = marketPriceFeed;
|
||||
this.formatter = formatter;
|
||||
|
||||
offerBookListItems = offerBook.getOfferBookListItems();
|
||||
|
@ -91,6 +94,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
|
||||
tradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
|
||||
tradeCurrencyCode.set(tradeCurrency.getCode());
|
||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,6 +119,10 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
this.direction = direction;
|
||||
}
|
||||
|
||||
void onTabSelected() {
|
||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
|
@ -122,7 +130,9 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
|
||||
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
||||
this.tradeCurrency = tradeCurrency;
|
||||
tradeCurrencyCode.set(tradeCurrency.getCode());
|
||||
String code = tradeCurrency.getCode();
|
||||
tradeCurrencyCode.set(code);
|
||||
marketPriceFeed.setCurrencyCode(code);
|
||||
filterList();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import io.bitsquare.btc.FeePolicy;
|
|||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
import io.bitsquare.gui.popups.WalletPasswordPopup;
|
||||
|
@ -63,6 +64,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
private final User user;
|
||||
private final WalletPasswordPopup walletPasswordPopup;
|
||||
private final Preferences preferences;
|
||||
private MarketPriceFeed marketPriceFeed;
|
||||
|
||||
private final Coin offerFeeAsCoin;
|
||||
private final Coin networkFeeAsCoin;
|
||||
|
@ -90,13 +92,14 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
@Inject
|
||||
TakeOfferDataModel(TradeManager tradeManager, TradeWalletService tradeWalletService,
|
||||
WalletService walletService, User user, WalletPasswordPopup walletPasswordPopup,
|
||||
Preferences preferences) {
|
||||
Preferences preferences, MarketPriceFeed marketPriceFeed) {
|
||||
this.tradeManager = tradeManager;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.walletService = walletService;
|
||||
this.user = user;
|
||||
this.walletPasswordPopup = walletPasswordPopup;
|
||||
this.preferences = preferences;
|
||||
this.marketPriceFeed = marketPriceFeed;
|
||||
|
||||
offerFeeAsCoin = FeePolicy.getCreateOfferFee();
|
||||
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
|
||||
|
@ -152,12 +155,16 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
};
|
||||
|
||||
offer.resetState();
|
||||
marketPriceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||
}
|
||||
|
||||
void checkOfferAvailability(ResultHandler resultHandler) {
|
||||
tradeManager.checkOfferAvailability(offer, resultHandler);
|
||||
}
|
||||
|
||||
void onTabSelected() {
|
||||
marketPriceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
|
|
|
@ -310,6 +310,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
new Popup().warning("You have already funds paid in.\nIn the <Funds/Open for withdrawal> section you can withdraw those funds.").show();*/
|
||||
}
|
||||
|
||||
public void onTabSelected() {
|
||||
model.dataModel.onTabSelected();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -55,24 +55,24 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
addTitledGroupBg(root, gridRow, 3, "Preferences");
|
||||
addTitledGroupBg(root, gridRow, 4, "Preferences");
|
||||
tradeCurrencyComboBox = addLabelComboBox(root, gridRow, "Preferred currency:", Layout.FIRST_ROW_DISTANCE).second;
|
||||
languageComboBox = addLabelComboBox(root, ++gridRow, "Language:").second;
|
||||
// btcDenominationComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin denomination:").second;
|
||||
blockExplorerComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin block explorer:").second;
|
||||
|
||||
autoSelectArbitratorsCheckBox = addLabelCheckBox(root, ++gridRow, "Auto select arbitrators by language:", "").second;
|
||||
|
||||
// TODO need a bit extra work to separate trade and non trade tx fees before it can be used
|
||||
/*transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second;
|
||||
transactionFeeFocusedListener = (o, oldValue, newValue) -> {
|
||||
model.onFocusOutTransactionFeeTextField(oldValue, newValue);
|
||||
};*/
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 5, "Display options", Layout.GROUP_DISTANCE);
|
||||
addTitledGroupBg(root, ++gridRow, 4, "Display options", Layout.GROUP_DISTANCE);
|
||||
useAnimationsCheckBox = addLabelCheckBox(root, gridRow, "Use animations:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
useEffectsCheckBox = addLabelCheckBox(root, ++gridRow, "Use effects:", "").second;
|
||||
showPlaceOfferConfirmationCheckBox = addLabelCheckBox(root, ++gridRow, "Show confirmation at place offer:", "").second;
|
||||
showTakeOfferConfirmationCheckBox = addLabelCheckBox(root, ++gridRow, "Show confirmation at take offer:", "").second;
|
||||
autoSelectArbitratorsCheckBox = addLabelCheckBox(root, ++gridRow, "Auto select arbitrators by language:", "").second;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -261,6 +261,22 @@ public class BSFormatter {
|
|||
return parseToFiat(input, currencyCode).equals(parseToFiatWith2Decimals(input, currencyCode));
|
||||
}
|
||||
|
||||
public String formatMarketPrice(double price) {
|
||||
if (price > 0) {
|
||||
String str = String.valueOf(price);
|
||||
int decPoint = str.indexOf(".");
|
||||
if (decPoint > 0) {
|
||||
while (str.length() < decPoint + 3) {
|
||||
str += "0";
|
||||
}
|
||||
return str.substring(0, decPoint + 3);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
} else {
|
||||
return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Other
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
|
||||
|
||||
<!-- <logger name="io.bitsquare.p2p.peers.PeerGroup" level="TRACE"/>
|
||||
|
||||
|
@ -30,7 +31,6 @@
|
|||
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||
|
||||
<logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/>
|
||||
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
|
||||
<logger name="io.bitsquare.temp.storage.RemoteStorage" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue