Skip to content

Commit

Permalink
Proposed fix for issue 1184. OfferBook caches buy & sell offer counts…
Browse files Browse the repository at this point in the history
… for each trade currency when OfferBook's fillOfferBookListItems method is called, and the appropriate cache is passed to the modified GIUUtil's getTradeCurrencyConverter. Currency ComboBox.setConverter call was moved from OfferBookView's initialize() to activate() because it depends on a non null direction field value.
  • Loading branch information
author committed Feb 8, 2018
1 parent c8283af commit cedefba
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@
import lombok.extern.slf4j.Slf4j;

import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static io.bisq.core.offer.OfferPayload.Direction.BUY;

/**
* Holds and manages the unsorted and unfiltered offerbook list of both buy and sell offers.
* It is handled as singleton by Guice and is used by 2 instances of OfferBookDataModel (one for Buy one for Sell).
Expand All @@ -40,7 +44,8 @@
public class OfferBook {
private final OfferBookService offerBookService;
private final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();

private final Map<String, Integer> buyOfferCountMap = new HashMap<>();
private final Map<String, Integer> sellOfferCountMap = new HashMap<>();

///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
Expand Down Expand Up @@ -113,9 +118,37 @@ public void fillOfferBookListItems() {
Log.logIfStressTests("OfferPayload filled: No. of offers = " + offerBookListItems.size());

log.debug("offerBookListItems.size " + offerBookListItems.size());
fillOfferCountMaps();
} catch (Throwable t) {
t.printStackTrace();
log.error("Error at fillOfferBookListItems: " + t.toString());
}
}

public Map<String, Integer> getBuyOfferCountMap() {
return buyOfferCountMap;
}

public Map<String, Integer> getSellOfferCountMap() {
return sellOfferCountMap;
}

private void fillOfferCountMaps() {
buyOfferCountMap.clear();
sellOfferCountMap.clear();
final String[] ccyCode = new String[1];
final int[] offerCount = new int[1];
offerBookListItems.forEach(o -> {
ccyCode[0] = o.getOffer().getCurrencyCode();
if (o.getOffer().getDirection() == BUY) {
offerCount[0] = buyOfferCountMap.getOrDefault(ccyCode[0], 0) + 1;
buyOfferCountMap.put(ccyCode[0], offerCount[0]);
} else {
offerCount[0] = sellOfferCountMap.getOrDefault(ccyCode[0], 0) + 1;
sellOfferCountMap.put(ccyCode[0], offerCount[0]);
}
});
log.debug("buyOfferCountMap.size {} sellOfferCountMap.size {}",
buyOfferCountMap.size(), sellOfferCountMap.size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ public void initialize() {
//noinspection unchecked
currencyComboBox = addLabelComboBox(root, gridRow, Res.get("offerbook.filterByCurrency"), Layout.FIRST_ROW_DISTANCE).second;
currencyComboBox.setPromptText(Res.get("list.currency.select"));
currencyComboBox.setConverter(GUIUtil.getTradeCurrencyConverter());

//noinspection unchecked
paymentMethodComboBox = addLabelComboBox(root, ++gridRow, Res.getWithCol("offerbook.filterByPaymentMethod")).second;
Expand Down Expand Up @@ -222,6 +221,10 @@ public PaymentMethod fromString(String s) {
@Override
protected void activate() {
currencyComboBox.setItems(model.getTradeCurrencies());
currencyComboBox.setConverter(GUIUtil.getTradeCurrencyConverter(
Res.get("shared.offer"),
Res.get("shared.offers"),
(model.getDirection() == OfferPayload.Direction.BUY ? model.getSellOfferCounts() : model.getBuyOfferCounts())));
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
currencyComboBox.setOnAction(e -> model.onSetTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.bitcoinj.core.Coin;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -240,6 +241,14 @@ SortedList<OfferBookListItem> getOfferList() {
return sortedItems;
}

Map<String, Integer> getBuyOfferCounts() {
return offerBook.getBuyOfferCountMap();
}

Map<String, Integer> getSellOfferCounts() {
return offerBook.getSellOfferCountMap();
}

boolean isMyOffer(Offer offer) {
return openOfferManager.isMyOffer(offer);
}
Expand Down
34 changes: 34 additions & 0 deletions gui/src/main/java/io/bisq/gui/util/GUIUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Slf4j
Expand Down Expand Up @@ -240,6 +242,38 @@ public CurrencyListItem fromString(String s) {
};
}

public static StringConverter<TradeCurrency> getTradeCurrencyConverter(
String postFixSingle,
String postFixMulti,
Map<String, Integer> offerCounts) {
return new StringConverter<TradeCurrency>() {
@Override
public String toString(TradeCurrency tradeCurrency) {
String code = tradeCurrency.getCode();
Optional<Integer> offerCountOptional = Optional.ofNullable(offerCounts.get(code));
final String displayString;
if (offerCountOptional.isPresent()) {
displayString = CurrencyUtil.getNameAndCode(code)
+ " - " + offerCountOptional.get() + " " + (offerCountOptional.get() == 1 ? postFixSingle : postFixMulti);
} else {
displayString = CurrencyUtil.getNameAndCode(code);
}
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
if (code.equals(GUIUtil.SHOW_ALL_FLAG))
return "▶ " + Res.get("list.currency.showAll");
else if (code.equals(GUIUtil.EDIT_FLAG))
return "▼ " + Res.get("list.currency.editList");
return tradeCurrency.getDisplayPrefix() + displayString;
}

@Override
public TradeCurrency fromString(String s) {
return null;
}
};
}

@Deprecated
public static StringConverter<TradeCurrency> getTradeCurrencyConverter() {
return new StringConverter<TradeCurrency>() {
@Override
Expand Down
16 changes: 13 additions & 3 deletions gui/src/test/java/io/bisq/gui/util/GUIUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
Expand All @@ -25,10 +27,18 @@ public void setup() {

@Test
public void testTradeCurrencyConverter() {
StringConverter<TradeCurrency> tradeCurrencyConverter = GUIUtil.getTradeCurrencyConverter();
Res.setBaseCurrencyCode("EUR");
Res.setBaseCurrencyName("Euro");
Map<String, Integer> offerCounts = new HashMap<String, Integer>() {{
put("EUR", 10);
}};
StringConverter<TradeCurrency> tradeCurrencyConverter = GUIUtil.getTradeCurrencyConverter(
Res.get("shared.offer"),
Res.get("shared.offers"),
offerCounts
);

assertEquals("✦ BTC (BTC)", tradeCurrencyConverter.toString(bitcoin));
assertEquals("★ Euro (EUR)", tradeCurrencyConverter.toString(euro));
assertEquals("★ Euro (EUR) - 10 offers", tradeCurrencyConverter.toString(euro));
}

@Test
Expand Down

0 comments on commit cedefba

Please sign in to comment.