mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 02:12:00 +01:00
Merge branch 'feature/refactor-fill-currency-list-items' of https://github.com/tau3/exchange into tau3-feature/refactor-fill-currency-list-items
This commit is contained in:
commit
f49e0effb3
@ -34,6 +34,7 @@ import io.bisq.gui.main.offer.offerbook.OfferBook;
|
||||
import io.bisq.gui.main.offer.offerbook.OfferBookListItem;
|
||||
import io.bisq.gui.main.settings.SettingsView;
|
||||
import io.bisq.gui.main.settings.preferences.PreferencesView;
|
||||
import io.bisq.gui.util.CurrencyList;
|
||||
import io.bisq.gui.util.CurrencyListItem;
|
||||
import io.bisq.gui.util.GUIUtil;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@ -53,8 +54,6 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(OfferBookChartViewModel.class);
|
||||
|
||||
private static final int TAB_INDEX = 0;
|
||||
|
||||
private final OfferBook offerBook;
|
||||
@ -67,7 +66,7 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
private final List<XYChart.Data> sellData = new ArrayList<>();
|
||||
private final ObservableList<OfferBookListItem> offerBookListItems;
|
||||
private final ListChangeListener<OfferBookListItem> offerBookListItemsListener;
|
||||
final ObservableList<CurrencyListItem> currencyListItems = FXCollections.observableArrayList();
|
||||
final CurrencyList currencyListItems;
|
||||
private final ObservableList<OfferListItem> topBuyOfferList = FXCollections.observableArrayList();
|
||||
private final ObservableList<OfferListItem> topSellOfferList = FXCollections.observableArrayList();
|
||||
private final ChangeListener<Number> currenciesUpdatedListener;
|
||||
@ -120,6 +119,8 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.currencyListItems = new CurrencyList(preferences);
|
||||
}
|
||||
|
||||
private void fillTradeCurrencies() {
|
||||
@ -137,7 +138,7 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
.filter(e -> e != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, null, preferences);
|
||||
currencyListItems.updateWithCurrencies(tradeCurrencyList, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,6 +36,7 @@ import io.bisq.gui.main.market.trades.charts.CandleData;
|
||||
import io.bisq.gui.main.settings.SettingsView;
|
||||
import io.bisq.gui.main.settings.preferences.PreferencesView;
|
||||
import io.bisq.gui.util.BSFormatter;
|
||||
import io.bisq.gui.util.CurrencyList;
|
||||
import io.bisq.gui.util.CurrencyListItem;
|
||||
import io.bisq.gui.util.GUIUtil;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
@ -82,7 +83,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||
private final SetChangeListener<TradeStatistics2> setChangeListener;
|
||||
final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>();
|
||||
final BooleanProperty showAllTradeCurrenciesProperty = new SimpleBooleanProperty(false);
|
||||
private final ObservableList<CurrencyListItem> currencyListItems = FXCollections.observableArrayList();
|
||||
private final CurrencyList currencyListItems;
|
||||
private final CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG), -1);
|
||||
final ObservableList<TradeStatistics2> tradeStatisticsByCurrency = FXCollections.observableArrayList();
|
||||
final ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
|
||||
@ -119,6 +120,8 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||
selectedTradeCurrencyProperty.set(GlobalSettings.getDefaultTradeCurrency());
|
||||
|
||||
tickUnit = TickUnit.values()[preferences.getTradeStatisticsTickUnitIndex()];
|
||||
|
||||
currencyListItems = new CurrencyList(this.preferences);
|
||||
}
|
||||
|
||||
private void fillTradeCurrencies() {
|
||||
@ -135,7 +138,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||
.filter(e -> e != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, showAllCurrencyListItem, preferences);
|
||||
currencyListItems.updateWithCurrencies(tradeCurrencyList, showAllCurrencyListItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
103
gui/src/main/java/io/bisq/gui/util/CurrencyList.java
Normal file
103
gui/src/main/java/io/bisq/gui/util/CurrencyList.java
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bisq.gui.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sun.javafx.collections.ObservableListWrapper;
|
||||
import io.bisq.common.locale.TradeCurrency;
|
||||
import io.bisq.core.user.Preferences;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class CurrencyList extends ObservableListWrapper<CurrencyListItem> {
|
||||
private final CurrencyPredicates predicates;
|
||||
private final Preferences preferences;
|
||||
|
||||
public CurrencyList(Preferences preferences) {
|
||||
this(new ArrayList<>(), preferences, new CurrencyPredicates());
|
||||
}
|
||||
|
||||
CurrencyList(List<CurrencyListItem> delegate, Preferences preferences, CurrencyPredicates predicates) {
|
||||
super(delegate);
|
||||
this.predicates = predicates;
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
public void updateWithCurrencies(List<TradeCurrency> currencies, @Nullable CurrencyListItem first) {
|
||||
List<CurrencyListItem> result = Lists.newLinkedList();
|
||||
Optional.ofNullable(first).ifPresent(result::add);
|
||||
result.addAll(getPartitionedSortedItems(currencies));
|
||||
setAll(result);
|
||||
}
|
||||
|
||||
private List<CurrencyListItem> getPartitionedSortedItems(List<TradeCurrency> currencies) {
|
||||
Map<TradeCurrency, Integer> tradesPerCurrency = countTrades(currencies);
|
||||
|
||||
Comparator<CurrencyListItem> comparator = getComparator();
|
||||
Queue<CurrencyListItem> fiatCurrencies = new PriorityQueue<>(comparator);
|
||||
Queue<CurrencyListItem> cryptoCurrencies = new PriorityQueue<>(comparator);
|
||||
|
||||
for (Map.Entry<TradeCurrency, Integer> entry : tradesPerCurrency.entrySet()) {
|
||||
TradeCurrency currency = entry.getKey();
|
||||
Integer count = entry.getValue();
|
||||
CurrencyListItem item = new CurrencyListItem(currency, count);
|
||||
|
||||
if (predicates.isFiatCurrency(currency)) {
|
||||
fiatCurrencies.add(item);
|
||||
}
|
||||
|
||||
if (predicates.isCryptoCurrency(currency)) {
|
||||
cryptoCurrencies.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
List<CurrencyListItem> result = Lists.newLinkedList();
|
||||
result.addAll(fiatCurrencies);
|
||||
result.addAll(cryptoCurrencies);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Comparator<CurrencyListItem> getComparator() {
|
||||
Comparator<CurrencyListItem> result;
|
||||
if (preferences.isSortMarketCurrenciesNumerically()) {
|
||||
Comparator<CurrencyListItem> byCount = Comparator.comparingInt(left -> left.numTrades);
|
||||
result = byCount.reversed();
|
||||
} else {
|
||||
result = Comparator.comparing(item -> item.tradeCurrency);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<TradeCurrency, Integer> countTrades(List<TradeCurrency> currencies) {
|
||||
Map<TradeCurrency, Integer> result = new HashMap<>();
|
||||
|
||||
BiFunction<TradeCurrency, Integer, Integer> incrementCurrentOrOne =
|
||||
(key, value) -> value == null ? 1 : value + 1;
|
||||
currencies.forEach(currency -> result.compute(currency, incrementCurrentOrOne));
|
||||
|
||||
Set<TradeCurrency> preferred = new HashSet<>();
|
||||
preferred.addAll(preferences.getFiatCurrencies());
|
||||
preferred.addAll(preferences.getCryptoCurrencies());
|
||||
preferred.forEach(currency -> result.putIfAbsent(currency, 0));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
31
gui/src/main/java/io/bisq/gui/util/CurrencyPredicates.java
Normal file
31
gui/src/main/java/io/bisq/gui/util/CurrencyPredicates.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bisq.gui.util;
|
||||
|
||||
import io.bisq.common.locale.CurrencyUtil;
|
||||
import io.bisq.common.locale.TradeCurrency;
|
||||
|
||||
class CurrencyPredicates {
|
||||
boolean isCryptoCurrency(TradeCurrency currency) {
|
||||
return CurrencyUtil.isCryptoCurrency(currency.getCode());
|
||||
}
|
||||
|
||||
boolean isFiatCurrency(TradeCurrency currency) {
|
||||
return CurrencyUtil.isFiatCurrency(currency.getCode());
|
||||
}
|
||||
}
|
@ -255,60 +255,6 @@ public class GUIUtil {
|
||||
};
|
||||
}
|
||||
|
||||
// TODO could be done more elegantly...
|
||||
public static void fillCurrencyListItems(List<TradeCurrency> tradeCurrencyList,
|
||||
ObservableList<CurrencyListItem> currencyListItems,
|
||||
@Nullable CurrencyListItem showAllCurrencyListItem,
|
||||
Preferences preferences) {
|
||||
Map<String, Integer> tradesPerCurrencyMap = new HashMap<>();
|
||||
Set<TradeCurrency> tradeCurrencySet = new HashSet<>();
|
||||
|
||||
// We get the list of all offers or trades. We want to find out how many items at each currency we have.
|
||||
tradeCurrencyList.stream().forEach(tradeCurrency -> {
|
||||
tradeCurrencySet.add(tradeCurrency);
|
||||
String code = tradeCurrency.getCode();
|
||||
if (tradesPerCurrencyMap.containsKey(code))
|
||||
tradesPerCurrencyMap.put(code, tradesPerCurrencyMap.get(code) + 1);
|
||||
else
|
||||
tradesPerCurrencyMap.put(code, 1);
|
||||
});
|
||||
|
||||
Set<TradeCurrency> userSet = new HashSet<>(preferences.getFiatCurrencies());
|
||||
userSet.addAll(preferences.getCryptoCurrencies());
|
||||
// Now all those items which are not in the offers or trades list but comes from the user preferred currency list
|
||||
// will get set to 0
|
||||
userSet.stream().forEach(tradeCurrency -> {
|
||||
tradeCurrencySet.add(tradeCurrency);
|
||||
String code = tradeCurrency.getCode();
|
||||
if (!tradesPerCurrencyMap.containsKey(code))
|
||||
tradesPerCurrencyMap.put(code, 0);
|
||||
});
|
||||
|
||||
List<CurrencyListItem> list = tradeCurrencySet.stream()
|
||||
.filter(e -> CurrencyUtil.isFiatCurrency(e.getCode()))
|
||||
.map(e -> new CurrencyListItem(e, tradesPerCurrencyMap.get(e.getCode())))
|
||||
.collect(Collectors.toList());
|
||||
List<CurrencyListItem> cryptoList = tradeCurrencySet.stream()
|
||||
.filter(e -> CurrencyUtil.isCryptoCurrency(e.getCode()))
|
||||
.map(e -> new CurrencyListItem(e, tradesPerCurrencyMap.get(e.getCode())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (preferences.isSortMarketCurrenciesNumerically()) {
|
||||
list.sort((o1, o2) -> new Integer(o2.numTrades).compareTo(o1.numTrades));
|
||||
cryptoList.sort((o1, o2) -> new Integer(o2.numTrades).compareTo(o1.numTrades));
|
||||
} else {
|
||||
list.sort((o1, o2) -> o1.tradeCurrency.compareTo(o2.tradeCurrency));
|
||||
cryptoList.sort((o1, o2) -> o1.tradeCurrency.compareTo(o2.tradeCurrency));
|
||||
}
|
||||
|
||||
list.addAll(cryptoList);
|
||||
|
||||
if (showAllCurrencyListItem != null)
|
||||
list.add(0, showAllCurrencyListItem);
|
||||
|
||||
currencyListItems.setAll(list);
|
||||
}
|
||||
|
||||
public static void updateConfidence(TransactionConfidence confidence, Tooltip tooltip, TxConfidenceIndicator txConfidenceIndicator) {
|
||||
if (confidence != null) {
|
||||
switch (confidence.getConfidenceType()) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.bisq.common.locale;
|
||||
|
||||
import com.natpryce.makeiteasy.Instantiator;
|
||||
import com.natpryce.makeiteasy.Maker;
|
||||
import com.natpryce.makeiteasy.Property;
|
||||
|
||||
import static com.natpryce.makeiteasy.MakeItEasy.a;
|
||||
|
104
gui/src/test/java/io/bisq/gui/util/CurrencyListTest.java
Normal file
104
gui/src/test/java/io/bisq/gui/util/CurrencyListTest.java
Normal file
@ -0,0 +1,104 @@
|
||||
package io.bisq.gui.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.bisq.common.locale.CryptoCurrency;
|
||||
import io.bisq.common.locale.FiatCurrency;
|
||||
import io.bisq.common.locale.TradeCurrency;
|
||||
import io.bisq.core.user.Preferences;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest(Preferences.class)
|
||||
public class CurrencyListTest {
|
||||
private static final TradeCurrency USD = new FiatCurrency("USD");
|
||||
private static final TradeCurrency RUR = new FiatCurrency("RUR");
|
||||
private static final TradeCurrency BTC = new CryptoCurrency("BTC", "Bitcoin");
|
||||
private static final TradeCurrency ETH = new CryptoCurrency("ETH", "Ether");
|
||||
private static final TradeCurrency BSQ = new CryptoCurrency("BSQ", "Bisq Token");
|
||||
|
||||
private Preferences preferences;
|
||||
private List<CurrencyListItem> delegate;
|
||||
private CurrencyList testedEntity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Locale.setDefault(new Locale("en", "US"));
|
||||
|
||||
CurrencyPredicates predicates = mock(CurrencyPredicates.class);
|
||||
when(predicates.isCryptoCurrency(USD)).thenReturn(false);
|
||||
when(predicates.isCryptoCurrency(RUR)).thenReturn(false);
|
||||
when(predicates.isCryptoCurrency(BTC)).thenReturn(true);
|
||||
when(predicates.isCryptoCurrency(ETH)).thenReturn(true);
|
||||
|
||||
when(predicates.isFiatCurrency(USD)).thenReturn(true);
|
||||
when(predicates.isFiatCurrency(RUR)).thenReturn(true);
|
||||
when(predicates.isFiatCurrency(BTC)).thenReturn(false);
|
||||
when(predicates.isFiatCurrency(ETH)).thenReturn(false);
|
||||
|
||||
this.preferences = mock(Preferences.class);
|
||||
this.delegate = new ArrayList<>();
|
||||
this.testedEntity = new CurrencyList(delegate, preferences, predicates);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWhenSortNumerically() {
|
||||
when(preferences.isSortMarketCurrenciesNumerically()).thenReturn(true);
|
||||
|
||||
List<TradeCurrency> currencies = Lists.newArrayList(USD, RUR, USD, ETH, ETH, BTC);
|
||||
testedEntity.updateWithCurrencies(currencies, null);
|
||||
|
||||
List<CurrencyListItem> expected = Lists.newArrayList(
|
||||
new CurrencyListItem(USD, 2),
|
||||
new CurrencyListItem(RUR, 1),
|
||||
new CurrencyListItem(ETH, 2),
|
||||
new CurrencyListItem(BTC, 1));
|
||||
|
||||
assertEquals(expected, delegate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWhenNotSortNumerically() {
|
||||
when(preferences.isSortMarketCurrenciesNumerically()).thenReturn(false);
|
||||
|
||||
List<TradeCurrency> currencies = Lists.newArrayList(USD, RUR, USD, ETH, ETH, BTC);
|
||||
testedEntity.updateWithCurrencies(currencies, null);
|
||||
|
||||
List<CurrencyListItem> expected = Lists.newArrayList(
|
||||
new CurrencyListItem(RUR, 1),
|
||||
new CurrencyListItem(USD, 2),
|
||||
new CurrencyListItem(BTC, 1),
|
||||
new CurrencyListItem(ETH, 2));
|
||||
|
||||
assertEquals(expected, delegate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWhenSortNumericallyAndFirstSpecified() {
|
||||
when(preferences.isSortMarketCurrenciesNumerically()).thenReturn(true);
|
||||
|
||||
List<TradeCurrency> currencies = Lists.newArrayList(USD, RUR, USD, ETH, ETH, BTC);
|
||||
CurrencyListItem first = new CurrencyListItem(BSQ, 5);
|
||||
testedEntity.updateWithCurrencies(currencies, first);
|
||||
|
||||
List<CurrencyListItem> expected = Lists.newArrayList(
|
||||
first,
|
||||
new CurrencyListItem(USD, 2),
|
||||
new CurrencyListItem(RUR, 1),
|
||||
new CurrencyListItem(ETH, 2),
|
||||
new CurrencyListItem(BTC, 1));
|
||||
|
||||
assertEquals(expected, delegate);
|
||||
}
|
||||
}
|
@ -2,14 +2,10 @@ package io.bisq.gui.util;
|
||||
|
||||
import io.bisq.common.locale.Res;
|
||||
import io.bisq.common.locale.TradeCurrency;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.util.StringConverter;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.natpryce.makeiteasy.MakeItEasy.make;
|
||||
@ -17,10 +13,8 @@ import static com.natpryce.makeiteasy.MakeItEasy.with;
|
||||
import static io.bisq.common.locale.TradeCurrencyMakers.bitcoin;
|
||||
import static io.bisq.common.locale.TradeCurrencyMakers.euro;
|
||||
import static io.bisq.core.user.PreferenceMakers.empty;
|
||||
import static io.bisq.gui.util.CurrencyListItemMakers.bitcoinItem;
|
||||
import static io.bisq.gui.util.CurrencyListItemMakers.euroItem;
|
||||
import static io.bisq.gui.util.CurrencyListItemMakers.numberOfTrades;
|
||||
import static org.junit.Assert.*;
|
||||
import static io.bisq.gui.util.CurrencyListItemMakers.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class GUIUtilTest {
|
||||
|
||||
@ -50,15 +44,4 @@ public class GUIUtilTest {
|
||||
assertEquals("★ Euro (EUR) - 1 offer", currencyListItemConverter.toString(make(euroItem.but(with(numberOfTrades, 1)))));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFillCurrencyListItems() {
|
||||
ObservableList<CurrencyListItem> currencyListItems = FXCollections.observableArrayList();
|
||||
List<TradeCurrency> tradeCurrencyList = new ArrayList<>();
|
||||
tradeCurrencyList.add(euro);
|
||||
CurrencyListItem euroListItem = make(euroItem.but(with(numberOfTrades,1)));
|
||||
|
||||
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, null, empty );
|
||||
assertTrue(euroListItem.equals(currencyListItems.get(0)));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user