Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for outdated market price items [4] #1727

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -898,10 +898,12 @@ protected void addFooter() {
GridPane.setMargin(footerBox, new Insets(buttonDistance, 0, 0, 0));
gridPane.getChildren().add(footerBox);
for (int i = 0; i < messageHyperlinks.size(); i++) {
Label label = new Label(String.format("[%d]", i + 1));
Label enumeration = new Label(String.format("[%d]", i + 1));
enumeration.getStyleClass().add("overlay-message");
Hyperlink link = new Hyperlink(messageHyperlinks.get(i));
link.getStyleClass().add("overlay-message");
link.setOnAction(event -> Browser.open(link.getText()));
HBox hBox = new HBox(label, link);
HBox hBox = new HBox(5, enumeration, link);
hBox.setAlignment(Pos.CENTER_LEFT);
footerBox.getChildren().addAll(hBox);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import bisq.desktop.common.threading.UIThread;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.WeakChangeListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.SortedList;
Expand Down Expand Up @@ -53,7 +54,10 @@ public BisqTableView(ObservableList<T> list) {
public BisqTableView(SortedList<T> sortedList) {
super(sortedList);

sortedList.comparatorProperty().bind(comparatorProperty());
comparatorProperty().addListener(new WeakChangeListener<>((observable, oldValue, newValue) -> {
sortedList.setComparator(newValue);
}));

setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@
import bisq.desktop.ServiceProvider;
import bisq.network.identity.NetworkId;
import bisq.offer.bisq_easy.BisqEasyOffer;
import bisq.offer.options.OfferOptionUtil;
import bisq.settings.SettingsService;
import bisq.trade.Trade;
import bisq.trade.bisq_easy.BisqEasyTrade;
import bisq.user.identity.UserIdentity;
import bisq.user.identity.UserIdentityService;
import bisq.user.profile.UserProfile;
import bisq.user.profile.UserProfileService;
import bisq.user.reputation.ReputationService;

import java.util.Optional;

Expand All @@ -44,4 +49,29 @@ public static Optional<BisqEasyTrade> findTradeFromChannel(ServiceProvider servi
String tradeId = Trade.createId(bisqEasyOffer.getId(), takerNetworkId.getId());
return serviceProvider.getTradeService().getBisqEasyTradeService().findTrade(tradeId);
}

public static boolean offerMatchesMinRequiredReputationScore(ReputationService reputationService,
SettingsService settingsService,
UserIdentityService userIdentityService,
UserProfileService userProfileService,
BisqEasyOffer peersOffer) {
if (peersOffer.getDirection().isSell()) {
Optional<UserProfile> optionalMakersUserProfile = userProfileService.findUserProfile(peersOffer.getMakersUserProfileId());
if (optionalMakersUserProfile.isEmpty()) {
return false;
}
long makerAsSellersScore = reputationService.getReputationScore(optionalMakersUserProfile.get()).getTotalScore();
long myMinRequiredScore = settingsService.getMinRequiredReputationScore().get();
// Maker as seller's score must be > than my required score (as buyer)
return makerAsSellersScore >= myMinRequiredScore;
} else {
if (userIdentityService.getSelectedUserIdentity() == null) {
return false;
}
// My score (as offer is a buy offer, I am the seller) must be > as offers required score
long myScoreAsSeller = reputationService.getReputationScore(userIdentityService.getSelectedUserIdentity().getUserProfile()).getTotalScore();
long offersRequiredScore = OfferOptionUtil.findRequiredTotalReputationScore(peersOffer).orElse(0L);
return myScoreAsSeller >= offersRequiredScore;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package bisq.desktop.main.content.bisq_easy.offerbook;

import bisq.bisq_easy.NavigationTarget;
import bisq.bonded_roles.market_price.MarketPriceService;
import bisq.chat.ChatChannel;
import bisq.chat.ChatChannelDomain;
import bisq.chat.ChatMessage;
Expand All @@ -27,6 +28,7 @@
import bisq.common.currency.Market;
import bisq.common.observable.Pin;
import bisq.common.observable.collection.ObservableArray;
import bisq.common.util.ProtobufUtils;
import bisq.desktop.ServiceProvider;
import bisq.desktop.common.observable.FxBindings;
import bisq.desktop.common.threading.UIThread;
Expand All @@ -35,6 +37,7 @@
import bisq.desktop.main.content.chat.ChatController;
import bisq.desktop.main.content.components.MarketImageComposition;
import bisq.offer.bisq_easy.BisqEasyOffer;
import bisq.settings.CookieKey;
import bisq.settings.SettingsService;
import javafx.scene.layout.StackPane;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -49,16 +52,18 @@
@Slf4j
public final class BisqEasyOfferbookController extends ChatController<BisqEasyOfferbookView, BisqEasyOfferbookModel> {
private final SettingsService settingsService;
private final MarketPriceService marketPriceService;
private final BisqEasyOfferbookChannelService bisqEasyOfferbookChannelService;
private final BisqEasyOfferbookModel bisqEasyOfferbookModel;
private Pin offerOnlySettingsPin, bisqEasyPrivateTradeChatChannelsPin, selectedChannelPin;
private Subscription marketSelectorSearchPin, selectedMarketFilterPin, selectedOffersFilterPin;
private Pin offerOnlySettingsPin, bisqEasyPrivateTradeChatChannelsPin, selectedChannelPin, marketPriceByCurrencyMapPin;
private Subscription marketSelectorSearchPin, selectedMarketFilterPin, selectedOffersFilterPin, selectedMarketSortTypePin;

public BisqEasyOfferbookController(ServiceProvider serviceProvider) {
super(serviceProvider, ChatChannelDomain.BISQ_EASY_OFFERBOOK, NavigationTarget.BISQ_EASY_OFFERBOOK);

bisqEasyOfferbookChannelService = chatService.getBisqEasyOfferbookChannelService();
settingsService = serviceProvider.getSettingsService();
marketPriceService = serviceProvider.getBondedRolesService().getMarketPriceService();
bisqEasyOfferbookModel = getModel();

createMarketChannels();
Expand Down Expand Up @@ -92,28 +97,40 @@ public void onActivate() {
selectedChannelPin = FxBindings.subscribe(selectionService.getSelectedChannel(), this::selectedChannelChanged);

marketSelectorSearchPin = EasyBind.subscribe(model.getMarketSelectorSearchText(), searchText -> {
if (searchText == null || searchText.isEmpty()) {
model.getFilteredMarketChannelItems().setPredicate(item -> true);
if (searchText == null || searchText.trim().isEmpty()) {
model.setMarketSearchTextPredicate(item -> true);
} else {
String search = searchText.toLowerCase();
model.getFilteredMarketChannelItems().setPredicate(item ->
String search = searchText.trim().toLowerCase();
model.setMarketSearchTextPredicate(item ->
item != null &&
(item.getMarket().getQuoteCurrencyCode().toLowerCase().contains(search) ||
item.getMarket().getQuoteCurrencyName().toLowerCase().contains(search))
);
}
updateFilteredMarketChannelItems();
});

Filters.Markets persistedMarketsFilter = settingsService.getCookie().asString(CookieKey.MARKETS_FILTER).map(name ->
ProtobufUtils.enumFromProto(Filters.Markets.class, name, Filters.Markets.WITH_OFFERS))
.orElse(Filters.Markets.WITH_OFFERS);
model.getSelectedMarketsFilter().set(persistedMarketsFilter);

selectedMarketFilterPin = EasyBind.subscribe(model.getSelectedMarketsFilter(), filter -> {
if (filter == null) {
// By default, show only markets with offers
model.getSelectedMarketsFilter().set(Filters.Markets.WITH_OFFERS);
model.getFilteredMarketChannelItems().setPredicate(model.getSelectedMarketsFilter().get().getPredicate());
} else {
model.getFilteredMarketChannelItems().setPredicate(filter.getPredicate());
if (filter != null) {
model.setMarketFilterPredicate(filter.getPredicate());
settingsService.setCookie(CookieKey.MARKETS_FILTER, model.getSelectedMarketsFilter().get().name());
updateFilteredMarketChannelItems();
}
});

marketPriceByCurrencyMapPin = marketPriceService.getMarketPriceByCurrencyMap().addObserver(() -> {
UIThread.run(() -> {
model.setMarketPricePredicate(item -> marketPriceService.getMarketPriceByCurrencyMap().isEmpty() ||
marketPriceService.getMarketPriceByCurrencyMap().containsKey(item.getMarket()));
updateFilteredMarketChannelItems();
});
});

selectedOffersFilterPin = EasyBind.subscribe(model.getSelectedOffersFilter(), filter -> {
if (filter == null) {
// By default, show all offers
Expand All @@ -124,7 +141,18 @@ public void onActivate() {
}
});

updateMarketItemsPredicate();
MarketSortType persistedMarketSortType = settingsService.getCookie().asString(CookieKey.MARKET_SORT_TYPE).map(name ->
ProtobufUtils.enumFromProto(MarketSortType.class, name, MarketSortType.NUM_OFFERS))
.orElse(MarketSortType.NUM_OFFERS);
model.getSelectedMarketSortType().set(persistedMarketSortType);
selectedMarketSortTypePin = EasyBind.subscribe(model.getSelectedMarketSortType(), marketSortType -> {
if (marketSortType != null) {
settingsService.setCookie(CookieKey.MARKET_SORT_TYPE, marketSortType.name());
}
});

model.getSortedMarketChannelItems().setComparator(model.getSelectedMarketSortType().get().getComparator());

maybeSelectFirst();
}

Expand All @@ -138,6 +166,8 @@ public void onDeactivate() {
marketSelectorSearchPin.unsubscribe();
selectedMarketFilterPin.unsubscribe();
selectedOffersFilterPin.unsubscribe();
marketPriceByCurrencyMapPin.unbind();
selectedMarketSortTypePin.unsubscribe();

resetSelectedChildTarget();
}
Expand All @@ -161,8 +191,6 @@ protected void selectedChannelChanged(ChatChannel<? extends ChatMessage> chatCha
.findAny()
.ifPresent(item -> model.getSelectedMarketChannelItem().set(item));

updateMarketItemsPredicate();

model.getSearchText().set("");
resetSelectedChildTarget();

Expand Down Expand Up @@ -201,8 +229,16 @@ void onCloseFilter() {
bisqEasyOfferbookModel.getShowFilterOverlay().set(false);
}

private void updateMarketItemsPredicate() {
//model.getFilteredMarketChannelItems().setPredicate(item -> !bisqEasyOfferbookChannelService.isVisible(item.getChannel()));
void onSortMarkets(MarketSortType marketSortType) {
model.getSelectedMarketSortType().set(marketSortType);
model.getSortedMarketChannelItems().setComparator(marketSortType.getComparator());
}

private void updateFilteredMarketChannelItems() {
model.getFilteredMarketChannelItems().setPredicate(item ->
model.getMarketFilterPredicate().test(item) &&
model.getMarketSearchTextPredicate().test(item) &&
model.getMarketPricePredicate().test(item));
}

private boolean isMaker(BisqEasyOffer bisqEasyOffer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Predicate;

@Slf4j
@Getter
public final class BisqEasyOfferbookModel extends ChatModel {
Expand All @@ -40,6 +43,15 @@ public final class BisqEasyOfferbookModel extends ChatModel {
private final StringProperty marketSelectorSearchText = new SimpleStringProperty();
private final ObjectProperty<Filters.Markets> selectedMarketsFilter = new SimpleObjectProperty<>();
private final ObjectProperty<Filters.Offers> selectedOffersFilter = new SimpleObjectProperty<>();
private final ObjectProperty<MarketSortType> selectedMarketSortType = new SimpleObjectProperty<>(MarketSortType.NUM_OFFERS);

@Setter
private Predicate<MarketChannelItem> marketPricePredicate = marketChannelItem -> true;
@Setter
private Predicate<MarketChannelItem> marketSearchTextPredicate = marketChannelItem -> true;
@Setter
private Predicate<MarketChannelItem> marketFilterPredicate = marketChannelItem -> true;

public BisqEasyOfferbookModel(ChatChannelDomain chatChannelDomain) {
super(chatChannelDomain);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import javafx.beans.binding.StringExpression;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.control.*;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
Expand All @@ -19,30 +22,30 @@
public class BisqEasyOfferbookUtil {
private static final List<Market> majorMarkets = MarketRepository.getMajorMarkets();

public static Comparator<MarketChannelItem> SortByNumOffers() {
public static Comparator<MarketChannelItem> sortByNumOffers() {
return (lhs, rhs) -> Integer.compare(rhs.getNumOffers().get(), lhs.getNumOffers().get());
}

public static Comparator<MarketChannelItem> SortByMajorMarkets() {
public static Comparator<MarketChannelItem> sortByMajorMarkets() {
return (lhs, rhs) -> {
int index1 = majorMarkets.indexOf(lhs.getMarket());
int index2 = majorMarkets.indexOf(rhs.getMarket());
return Integer.compare(index1, index2);
};
}

public static Comparator<MarketChannelItem> SortByMarketNameAsc() {
public static Comparator<MarketChannelItem> sortByMarketNameAsc() {
return Comparator.comparing(MarketChannelItem::getMarketString);
}

public static Comparator<MarketChannelItem> SortByMarketNameDesc() {
public static Comparator<MarketChannelItem> sortByMarketNameDesc() {
return Comparator.comparing(MarketChannelItem::getMarketString).reversed();
}

public static Comparator<MarketChannelItem> SortByMarketActivity() {
return (lhs, rhs) -> BisqEasyOfferbookUtil.SortByNumOffers()
.thenComparing(BisqEasyOfferbookUtil.SortByMajorMarkets())
.thenComparing(BisqEasyOfferbookUtil.SortByMarketNameAsc())
public static Comparator<MarketChannelItem> sortByMarketActivity() {
return (lhs, rhs) -> BisqEasyOfferbookUtil.sortByNumOffers()
.thenComparing(BisqEasyOfferbookUtil.sortByMajorMarkets())
.thenComparing(BisqEasyOfferbookUtil.sortByMarketNameAsc())
.compare(lhs, rhs);
}

Expand Down
Loading
Loading