mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Add market price feed for altcoins
This commit is contained in:
parent
d2e8c6afd7
commit
eefafab977
14 changed files with 177 additions and 63 deletions
|
@ -13,12 +13,23 @@ public class MarketPrice {
|
||||||
private final double last;
|
private final double last;
|
||||||
|
|
||||||
public MarketPrice(String currencyCode, String ask, String bid, String last) {
|
public MarketPrice(String currencyCode, String ask, String bid, String last) {
|
||||||
|
this(currencyCode, ask, bid, last, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarketPrice(String currencyCode, String ask, String bid, String last, boolean invert) {
|
||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
|
if (invert) {
|
||||||
|
this.ask = 1d / parseDouble(ask);
|
||||||
|
this.bid = 1d / parseDouble(bid);
|
||||||
|
this.last = 1d / parseDouble(last);
|
||||||
|
} else {
|
||||||
this.ask = parseDouble(ask);
|
this.ask = parseDouble(ask);
|
||||||
this.bid = parseDouble(bid);
|
this.bid = parseDouble(bid);
|
||||||
this.last = parseDouble(last);
|
this.last = parseDouble(last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public double getPrice(MarketPriceFeed.Type type) {
|
public double getPrice(MarketPriceFeed.Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ASK:
|
case ASK:
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.google.common.util.concurrent.SettableFuture;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bitsquare.app.Log;
|
import io.bitsquare.app.Log;
|
||||||
import io.bitsquare.btc.pricefeed.providers.BitcoinAveragePriceProvider;
|
import io.bitsquare.btc.pricefeed.providers.BitcoinAveragePriceProvider;
|
||||||
|
import io.bitsquare.btc.pricefeed.providers.PoloniexPriceProvider;
|
||||||
import io.bitsquare.btc.pricefeed.providers.PriceProvider;
|
import io.bitsquare.btc.pricefeed.providers.PriceProvider;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.handlers.FaultHandler;
|
import io.bitsquare.common.handlers.FaultHandler;
|
||||||
|
@ -18,6 +19,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
@ -43,15 +45,15 @@ public class MarketPriceFeed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
private static long PERIOD_FIAT = 1; // We load only the selected currency on interval. Only the first request we load all
|
||||||
// https://poloniex.com/public?command=returnTicker 33 kb
|
private static long PERIOD_CRYPTO = 10; // We load the full list with 33kb so we don't want to load too often
|
||||||
private static long PERIOD = 30;
|
|
||||||
|
|
||||||
private final ScheduledThreadPoolExecutor executorService = Utilities.getScheduledThreadPoolExecutor("MarketPriceFeed", 5, 10, 120L);
|
private final ScheduledThreadPoolExecutor executorService = Utilities.getScheduledThreadPoolExecutor("MarketPriceFeed", 5, 10, 700L);
|
||||||
private final Map<String, MarketPrice> cache = new HashMap<>();
|
private final Map<String, MarketPrice> cache = new HashMap<>();
|
||||||
|
private final PriceProvider fiatPriceProvider = new BitcoinAveragePriceProvider();
|
||||||
|
private final PriceProvider cryptoCurrenciesPriceProvider = new PoloniexPriceProvider();
|
||||||
private Consumer<Double> priceConsumer;
|
private Consumer<Double> priceConsumer;
|
||||||
private FaultHandler faultHandler;
|
private FaultHandler faultHandler;
|
||||||
private PriceProvider fiatPriceProvider = new BitcoinAveragePriceProvider();
|
|
||||||
private Type type;
|
private Type type;
|
||||||
private String currencyCode;
|
private String currencyCode;
|
||||||
transient private final StringProperty currencyCodeProperty = new SimpleStringProperty();
|
transient private final StringProperty currencyCodeProperty = new SimpleStringProperty();
|
||||||
|
@ -66,6 +68,7 @@ public class MarketPriceFeed {
|
||||||
public MarketPriceFeed() {
|
public MarketPriceFeed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// API
|
// API
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -76,8 +79,18 @@ public class MarketPriceFeed {
|
||||||
|
|
||||||
requestAllPrices(fiatPriceProvider, () -> {
|
requestAllPrices(fiatPriceProvider, () -> {
|
||||||
applyPrice();
|
applyPrice();
|
||||||
executorService.scheduleAtFixedRate(() -> requestPrice(fiatPriceProvider), PERIOD, PERIOD, TimeUnit.SECONDS);
|
executorService.scheduleAtFixedRate(
|
||||||
|
() -> requestPrice(fiatPriceProvider),
|
||||||
|
PERIOD_FIAT, PERIOD_FIAT, TimeUnit.MINUTES);
|
||||||
});
|
});
|
||||||
|
requestAllPrices(cryptoCurrenciesPriceProvider, () -> {
|
||||||
|
applyPrice();
|
||||||
|
executorService.scheduleAtFixedRate(
|
||||||
|
() -> requestAllPrices(cryptoCurrenciesPriceProvider,
|
||||||
|
this::applyPrice),
|
||||||
|
PERIOD_CRYPTO, PERIOD_CRYPTO, TimeUnit.MINUTES);
|
||||||
|
});
|
||||||
|
requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,7 +169,7 @@ public class MarketPriceFeed {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestAllPrices(PriceProvider provider, Runnable resultHandler) {
|
private void requestAllPrices(PriceProvider provider, @Nullable Runnable resultHandler) {
|
||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
GetPriceRequest getPriceRequest = new GetPriceRequest();
|
GetPriceRequest getPriceRequest = new GetPriceRequest();
|
||||||
SettableFuture<Map<String, MarketPrice>> future = getPriceRequest.requestAllPrices(provider);
|
SettableFuture<Map<String, MarketPrice>> future = getPriceRequest.requestAllPrices(provider);
|
||||||
|
@ -164,6 +177,7 @@ public class MarketPriceFeed {
|
||||||
public void onSuccess(Map<String, MarketPrice> marketPriceMap) {
|
public void onSuccess(Map<String, MarketPrice> marketPriceMap) {
|
||||||
UserThread.execute(() -> {
|
UserThread.execute(() -> {
|
||||||
cache.putAll(marketPriceMap);
|
cache.putAll(marketPriceMap);
|
||||||
|
if (resultHandler != null)
|
||||||
resultHandler.run();
|
resultHandler.run();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
package io.bitsquare.btc.pricefeed.providers;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.internal.LinkedTreeMap;
|
||||||
|
import io.bitsquare.app.Log;
|
||||||
|
import io.bitsquare.btc.pricefeed.MarketPrice;
|
||||||
|
import io.bitsquare.http.HttpClient;
|
||||||
|
import io.bitsquare.http.HttpException;
|
||||||
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PoloniexPriceProvider implements PriceProvider {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(PoloniexPriceProvider.class);
|
||||||
|
|
||||||
|
//https://poloniex.com/public?command=returnTicker
|
||||||
|
private final HttpClient httpClient = new HttpClient("https://poloniex.com/public");
|
||||||
|
|
||||||
|
public PoloniexPriceProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, MarketPrice> getAllPrices() throws IOException, HttpException {
|
||||||
|
Map<String, MarketPrice> marketPriceMap = new HashMap<>();
|
||||||
|
String response = httpClient.requestWithGET("?command=returnTicker");
|
||||||
|
LinkedTreeMap<String, Object> treeMap = new Gson().fromJson(response, LinkedTreeMap.class);
|
||||||
|
Map<String, String> temp = new HashMap<>();
|
||||||
|
Set<String> supported = CurrencyUtil.getSortedCryptoCurrencies().stream()
|
||||||
|
.map(TradeCurrency::getCode)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
treeMap.entrySet().stream().forEach(e -> {
|
||||||
|
Object value = e.getValue();
|
||||||
|
String currencyPair = e.getKey();
|
||||||
|
String otherCurrency = null;
|
||||||
|
if (currencyPair.startsWith("BTC")) {
|
||||||
|
String[] tokens = currencyPair.split("_");
|
||||||
|
if (tokens.length > 1) {
|
||||||
|
otherCurrency = tokens[1];
|
||||||
|
if (supported.contains(otherCurrency)) {
|
||||||
|
if (value instanceof LinkedTreeMap) {
|
||||||
|
LinkedTreeMap<String, Object> treeMap2 = (LinkedTreeMap) value;
|
||||||
|
temp.clear();
|
||||||
|
treeMap2.entrySet().stream().forEach(e2 -> temp.put(e2.getKey(), e2.getValue().toString()));
|
||||||
|
marketPriceMap.put(otherCurrency,
|
||||||
|
new MarketPrice(otherCurrency, temp.get("lowestAsk"), temp.get("highestBid"), temp.get("last"), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return marketPriceMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MarketPrice getPrice(String currencyCode) throws IOException, HttpException {
|
||||||
|
Log.traceCall("currencyCode=" + currencyCode);
|
||||||
|
JsonObject jsonObject = new JsonParser()
|
||||||
|
.parse(httpClient.requestWithGET(currencyCode))
|
||||||
|
.getAsJsonObject();
|
||||||
|
return new MarketPrice(currencyCode,
|
||||||
|
jsonObject.get("ask").getAsString(),
|
||||||
|
jsonObject.get("bid").getAsString(),
|
||||||
|
jsonObject.get("last").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "BitcoinAveragePriceProvider{" +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -178,20 +178,20 @@ public class CurrencyUtil {
|
||||||
// result.add(new CryptoCurrency("XMR", "Monero"));
|
// result.add(new CryptoCurrency("XMR", "Monero"));
|
||||||
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
|
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
|
||||||
result.add(new CryptoCurrency("DASH", "Dash"));
|
result.add(new CryptoCurrency("DASH", "Dash"));
|
||||||
result.add(new CryptoCurrency("ANC", "Anoncoin"));
|
|
||||||
result.add(new CryptoCurrency("NBT", "NuBits"));
|
result.add(new CryptoCurrency("NBT", "NuBits"));
|
||||||
result.add(new CryptoCurrency("NSR", "NuShares"));
|
result.add(new CryptoCurrency("NSR", "NuShares"));
|
||||||
result.add(new CryptoCurrency("FAIR", "FairCoin"));
|
|
||||||
result.add(new CryptoCurrency("PPC", "Peercoin"));
|
result.add(new CryptoCurrency("PPC", "Peercoin"));
|
||||||
result.add(new CryptoCurrency("XPM", "Primecoin"));
|
result.add(new CryptoCurrency("XPM", "Primecoin"));
|
||||||
|
result.add(new CryptoCurrency("SC", "Siacoin"));
|
||||||
|
result.add(new CryptoCurrency("SJCX", "StorjcoinX"));
|
||||||
|
result.add(new CryptoCurrency("GEMZ", "Gemz"));
|
||||||
result.add(new CryptoCurrency("DOGE", "Dogecoin"));
|
result.add(new CryptoCurrency("DOGE", "Dogecoin"));
|
||||||
|
result.add(new CryptoCurrency("BLK", "Blackcoin"));
|
||||||
|
result.add(new CryptoCurrency("FCT", "Factom"));
|
||||||
result.add(new CryptoCurrency("NXT", "Nxt"));
|
result.add(new CryptoCurrency("NXT", "Nxt"));
|
||||||
result.add(new CryptoCurrency("BTS", "BitShares"));
|
result.add(new CryptoCurrency("BTS", "BitShares"));
|
||||||
result.add(new CryptoCurrency("XCP", "Counterparty"));
|
result.add(new CryptoCurrency("XCP", "Counterparty"));
|
||||||
result.add(new CryptoCurrency("XRP", "Ripple"));
|
result.add(new CryptoCurrency("XRP", "Ripple"));
|
||||||
// Stellar (XLM Lumen) uses an additional memo field. We dont support that for now
|
|
||||||
//result.add(new CryptoCurrency("STR", "Stellar"));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
private Tuple3<TextField, Label, VBox> getMarketPriceBox(String text) {
|
private Tuple3<TextField, Label, VBox> getMarketPriceBox(String text) {
|
||||||
TextField textField = new TextField();
|
TextField textField = new TextField();
|
||||||
textField.setEditable(false);
|
textField.setEditable(false);
|
||||||
textField.setPrefWidth(140);
|
textField.setPrefWidth(150);
|
||||||
textField.setMouseTransparent(true);
|
textField.setMouseTransparent(true);
|
||||||
textField.setFocusTraversable(false);
|
textField.setFocusTraversable(false);
|
||||||
textField.setStyle("-fx-alignment: center; -fx-background-color: -bs-bg-grey;");
|
textField.setStyle("-fx-alignment: center; -fx-background-color: -bs-bg-grey;");
|
||||||
|
|
|
@ -83,11 +83,20 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
||||||
UserThread.execute(InputTextField::hideErrorMessageDisplay);
|
UserThread.execute(InputTextField::hideErrorMessageDisplay);
|
||||||
if (newValue != null) {
|
if (newValue != null) {
|
||||||
if (newValue.equals(createOfferTab) && createOfferView != null) {
|
if (newValue.equals(createOfferTab) && createOfferView != null) {
|
||||||
createOfferView.onTabSelected();
|
createOfferView.onTabSelected(true);
|
||||||
} else if (newValue.equals(takeOfferTab) && takeOfferView != null) {
|
} else if (newValue.equals(takeOfferTab) && takeOfferView != null) {
|
||||||
takeOfferView.onTabSelected();
|
takeOfferView.onTabSelected(true);
|
||||||
} else if (newValue.equals(offerBookTab) && offerBookView != null) {
|
} else if (newValue.equals(offerBookTab) && offerBookView != null) {
|
||||||
offerBookView.onTabSelected();
|
offerBookView.onTabSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oldValue != null) {
|
||||||
|
if (oldValue.equals(createOfferTab) && createOfferView != null) {
|
||||||
|
createOfferView.onTabSelected(false);
|
||||||
|
} else if (oldValue.equals(takeOfferTab) && takeOfferView != null) {
|
||||||
|
takeOfferView.onTabSelected(false);
|
||||||
|
} else if (oldValue.equals(offerBookTab) && offerBookView != null) {
|
||||||
|
offerBookView.onTabSelected(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -130,6 +139,7 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
||||||
offerBookTab.setContent(view.getRoot());
|
offerBookTab.setContent(view.getRoot());
|
||||||
tabPane.getTabs().add(offerBookTab);
|
tabPane.getTabs().add(offerBookTab);
|
||||||
offerBookView = (OfferBookView) view;
|
offerBookView = (OfferBookView) view;
|
||||||
|
offerBookView.onTabSelected(true);
|
||||||
|
|
||||||
OfferActionHandler offerActionHandler = new OfferActionHandler() {
|
OfferActionHandler offerActionHandler = new OfferActionHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -103,6 +103,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||||
|
|
||||||
private PaymentAccount paymentAccount;
|
private PaymentAccount paymentAccount;
|
||||||
private WalletEventListener walletEventListener;
|
private WalletEventListener walletEventListener;
|
||||||
|
private boolean isTabSelected;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -181,6 +182,9 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||||
|
|
||||||
if (direction == Offer.Direction.BUY)
|
if (direction == Offer.Direction.BUY)
|
||||||
calculateTotalToPay();
|
calculateTotalToPay();
|
||||||
|
|
||||||
|
if (isTabSelected)
|
||||||
|
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -227,7 +231,9 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTabSelected() {
|
void onTabSelected(boolean isSelected) {
|
||||||
|
this.isTabSelected = isSelected;
|
||||||
|
if (isTabSelected)
|
||||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,8 +201,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
this.closeHandler = closeHandler;
|
this.closeHandler = closeHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTabSelected() {
|
public void onTabSelected(boolean isSelected) {
|
||||||
model.dataModel.onTabSelected();
|
model.dataModel.onTabSelected(isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -197,8 +197,8 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||||
this.offerActionHandler = offerActionHandler;
|
this.offerActionHandler = offerActionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTabSelected() {
|
public void onTabSelected(boolean isSelected) {
|
||||||
model.onTabSelected();
|
model.onTabSelected(isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
private PaymentMethod paymentMethod = new AllPaymentMethodsEntry();
|
private PaymentMethod paymentMethod = new AllPaymentMethodsEntry();
|
||||||
private final ObservableList<OfferBookListItem> offerBookListItems;
|
private final ObservableList<OfferBookListItem> offerBookListItems;
|
||||||
private final ListChangeListener<OfferBookListItem> listChangeListener;
|
private final ListChangeListener<OfferBookListItem> listChangeListener;
|
||||||
|
private boolean isTabSelected;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, lifecycle
|
// Constructor, lifecycle
|
||||||
|
@ -94,7 +95,6 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
|
|
||||||
tradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
|
tradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
|
||||||
tradeCurrencyCode.set(tradeCurrency.getCode());
|
tradeCurrencyCode.set(tradeCurrency.getCode());
|
||||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,6 +103,8 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
offerBookListItems.addListener(listChangeListener);
|
offerBookListItems.addListener(listChangeListener);
|
||||||
offerBook.fillOfferBookListItems();
|
offerBook.fillOfferBookListItems();
|
||||||
filterList();
|
filterList();
|
||||||
|
if (isTabSelected)
|
||||||
|
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,7 +121,9 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTabSelected() {
|
void onTabSelected(boolean isSelected) {
|
||||||
|
this.isTabSelected = isSelected;
|
||||||
|
if (isTabSelected)
|
||||||
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
marketPriceFeed.setCurrencyCode(tradeCurrencyCode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||||
|
|
||||||
private BalanceListener balanceListener;
|
private BalanceListener balanceListener;
|
||||||
private PaymentAccount paymentAccount;
|
private PaymentAccount paymentAccount;
|
||||||
|
private boolean isTabSelected;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -114,6 +115,9 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||||
addBindings();
|
addBindings();
|
||||||
addListeners();
|
addListeners();
|
||||||
updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress()));
|
updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress()));
|
||||||
|
|
||||||
|
if (isTabSelected)
|
||||||
|
marketPriceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -162,7 +166,9 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||||
tradeManager.checkOfferAvailability(offer, resultHandler);
|
tradeManager.checkOfferAvailability(offer, resultHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTabSelected() {
|
void onTabSelected(boolean isSelected) {
|
||||||
|
this.isTabSelected = isSelected;
|
||||||
|
if (isTabSelected)
|
||||||
marketPriceFeed.setCurrencyCode(offer.getCurrencyCode());
|
marketPriceFeed.setCurrencyCode(offer.getCurrencyCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,8 +310,8 @@ 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();*/
|
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() {
|
public void onTabSelected(boolean isSelected) {
|
||||||
model.dataModel.onTabSelected();
|
model.dataModel.onTabSelected(isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||||
import io.bitsquare.gui.popups.OpenEmergencyTicketPopup;
|
import io.bitsquare.gui.popups.OpenEmergencyTicketPopup;
|
||||||
import io.bitsquare.gui.popups.TradeDetailsPopup;
|
import io.bitsquare.gui.popups.TradeDetailsPopup;
|
||||||
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||||
|
@ -50,6 +51,7 @@ import javax.inject.Inject;
|
||||||
public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTradesViewModel> {
|
public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTradesViewModel> {
|
||||||
|
|
||||||
private final TradeDetailsPopup tradeDetailsPopup;
|
private final TradeDetailsPopup tradeDetailsPopup;
|
||||||
|
private BSFormatter formatter;
|
||||||
@FXML
|
@FXML
|
||||||
TableView<PendingTradesListItem> table;
|
TableView<PendingTradesListItem> table;
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -74,9 +76,10 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PendingTradesView(PendingTradesViewModel model, TradeDetailsPopup tradeDetailsPopup) {
|
public PendingTradesView(PendingTradesViewModel model, TradeDetailsPopup tradeDetailsPopup, BSFormatter formatter) {
|
||||||
super(model);
|
super(model);
|
||||||
this.tradeDetailsPopup = tradeDetailsPopup;
|
this.tradeDetailsPopup = tradeDetailsPopup;
|
||||||
|
this.formatter = formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -232,7 +235,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
|
|
||||||
if (item != null && !empty) {
|
if (item != null && !empty) {
|
||||||
field = new HyperlinkWithIcon(model.formatTradeId(item.getId()), true);
|
field = new HyperlinkWithIcon(item.getId(), true);
|
||||||
field.setOnAction(event -> tradeDetailsPopup.show(item.getTrade()));
|
field.setOnAction(event -> tradeDetailsPopup.show(item.getTrade()));
|
||||||
field.setTooltip(new Tooltip("Open popup for details"));
|
field.setTooltip(new Tooltip("Open popup for details"));
|
||||||
setGraphic(field);
|
setGraphic(field);
|
||||||
|
@ -267,7 +270,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
} else {
|
} else {
|
||||||
setId("-fx-text-fill: black");
|
setId("-fx-text-fill: black");
|
||||||
}
|
}
|
||||||
setText(model.getDate(item));
|
setText(formatter.formatDateTime(item.getTrade().getDate()));
|
||||||
} else {
|
} else {
|
||||||
setText(null);
|
setText(null);
|
||||||
}
|
}
|
||||||
|
@ -282,7 +285,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
new StringConverter<Coin>() {
|
new StringConverter<Coin>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Coin value) {
|
public String toString(Coin value) {
|
||||||
return model.formatTradeAmount(value);
|
return formatter.formatCoinWithCode(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -297,7 +300,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
new StringConverter<Fiat>() {
|
new StringConverter<Fiat>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Fiat value) {
|
public String toString(Fiat value) {
|
||||||
return model.formatPrice(value);
|
return formatter.formatPriceWithCode(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -313,7 +316,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
new StringConverter<Fiat>() {
|
new StringConverter<Fiat>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Fiat value) {
|
public String toString(Fiat value) {
|
||||||
return model.formatTradeVolume(value);
|
return formatter.formatFiatWithCode(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,8 +34,6 @@ import io.bitsquare.trade.offer.Offer;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import org.bitcoinj.core.BlockChainListener;
|
import org.bitcoinj.core.BlockChainListener;
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
import org.bitcoinj.utils.Fiat;
|
|
||||||
import org.fxmisc.easybind.EasyBind;
|
import org.fxmisc.easybind.EasyBind;
|
||||||
import org.fxmisc.easybind.Subscription;
|
import org.fxmisc.easybind.Subscription;
|
||||||
|
|
||||||
|
@ -225,21 +223,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
}
|
}
|
||||||
|
|
||||||
// columns
|
// columns
|
||||||
String formatTradeId(String value) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
String formatTradeAmount(Coin value) {
|
|
||||||
return formatter.formatCoinWithCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
String formatPrice(Fiat value) {
|
|
||||||
return formatter.formatFiat(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
String formatTradeVolume(Fiat value) {
|
|
||||||
return formatter.formatFiatWithCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemainingTime() {
|
public String getRemainingTime() {
|
||||||
return formatter.getPeriodBetweenBlockHeights(getBestChainHeight(),
|
return formatter.getPeriodBetweenBlockHeights(getBestChainHeight(),
|
||||||
|
@ -255,10 +238,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getDate(PendingTradesListItem item) {
|
|
||||||
return formatter.formatDateTime(item.getTrade().getDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean showWarning(Trade trade) {
|
public boolean showWarning(Trade trade) {
|
||||||
return getBestChainHeight() >= trade.getCheckPaymentTimeAsBlockHeight();
|
return getBestChainHeight() >= trade.getCheckPaymentTimeAsBlockHeight();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue