From 5cc853f7d26e9741831af5683b43d6859cf1e973 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Sat, 24 Aug 2024 11:31:55 +0200 Subject: [PATCH 1/7] Fix direction filter dropdown menu in offerlist --- .../java/bisq/desktop/components/controls/DropdownMenu.java | 3 +-- .../bisq_easy/offerbook/offerbook_list/OfferbookListItem.java | 1 - .../bisq_easy/offerbook/offerbook_list/OfferbookListView.java | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java index 4e5ee43126..a4c54e037c 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java @@ -164,8 +164,7 @@ private void attachListeners() { // Once the contextMenu has calculated the width on the first render time we update the items // so that they all have the same size. for (MenuItem item : contextMenu.getItems()) { - if (item instanceof DropdownMenuItem) { - DropdownMenuItem dropdownMenuItem = (DropdownMenuItem) item; + if (item instanceof DropdownMenuItem dropdownMenuItem) { dropdownMenuItem.updateWidth(contextMenu.getWidth() - 18); // Remove margins } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListItem.java index 6abd0f1c37..9f3af8040d 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListItem.java @@ -123,7 +123,6 @@ private void updatePriceSpecAsPercent() { } } - private List retrieveAndSortFiatPaymentMethods() { List paymentMethods = PaymentMethodSpecUtil.getPaymentMethods(bisqEasyOffer.getQuoteSidePaymentMethodSpecs()); diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java index 4b6c2402ea..45226971be 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java @@ -92,6 +92,7 @@ public class OfferbookListView extends bisq.desktop.common.view.View Date: Sat, 24 Aug 2024 11:46:24 +0200 Subject: [PATCH 2/7] Refactor: rename filter to directionFilter --- .../offerbook_list/OfferbookListView.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java index 45226971be..05da4659f3 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java @@ -67,7 +67,7 @@ public class OfferbookListView extends bisq.desktop.common.view.View(model.getSortedOfferbookListItems()); tableView.getStyleClass().add("offers-list"); @@ -122,8 +122,8 @@ protected void onViewAttached() { if (showOfferListExpanded != null) { tableView.setVisible(showOfferListExpanded); tableView.setManaged(showOfferListExpanded); - filterDropdownMenu.setVisible(showOfferListExpanded); - filterDropdownMenu.setManaged(showOfferListExpanded); + directionFilterDropdownMenu.setVisible(showOfferListExpanded); + directionFilterDropdownMenu.setManaged(showOfferListExpanded); title.setGraphic(offerListGreyIcon); if (showOfferListExpanded) { header.setAlignment(Pos.CENTER_LEFT); From a49e82241e33153785529ecc1c8b4b300bb13c50 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:50:59 +0200 Subject: [PATCH 3/7] Add payment methods filter --- .../offerbook_list/OfferbookListView.java | 45 ++++++++++++------- .../src/main/resources/css/bisq_easy.css | 5 +++ i18n/src/main/resources/bisq_easy.properties | 1 + 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java index 05da4659f3..75f7e23964 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java @@ -62,13 +62,14 @@ public class OfferbookListView extends bisq.desktop.common.view.View tableView; private final BisqTooltip titleTooltip; private final HBox header; private final ImageView offerListWhiteIcon, offerListGreyIcon, offerListGreenIcon; - private final DropdownMenu directionFilterDropdownMenu; - private final DropdownMenuItem buyFromOffers, sellToOffers; + private final DropdownMenu offersDirectionFilterMenu, paymentsFilterMenu; + private DropdownMenuItem buyFromOffers, sellToOffers; + private Label offerListByDirectionFilter; private Subscription showOfferListExpandedPin, showBuyFromOffersPin, offerListTableViewSelectionPin; OfferbookListView(OfferbookListModel model, OfferbookListController controller) { @@ -90,19 +91,13 @@ public class OfferbookListView extends bisq.desktop.common.view.View(model.getSortedOfferbookListItems()); tableView.getStyleClass().add("offers-list"); @@ -122,8 +117,8 @@ protected void onViewAttached() { if (showOfferListExpanded != null) { tableView.setVisible(showOfferListExpanded); tableView.setManaged(showOfferListExpanded); - directionFilterDropdownMenu.setVisible(showOfferListExpanded); - directionFilterDropdownMenu.setManaged(showOfferListExpanded); + offersDirectionFilterMenu.setVisible(showOfferListExpanded); + offersDirectionFilterMenu.setManaged(showOfferListExpanded); title.setGraphic(offerListGreyIcon); if (showOfferListExpanded) { header.setAlignment(Pos.CENTER_LEFT); @@ -196,6 +191,26 @@ protected void onViewDetached() { title.setTooltip(null); } + private DropdownMenu createAndGetOffersDirectionFilterMenu() { + DropdownMenu menu = new DropdownMenu("chevron-drop-menu-grey", "chevron-drop-menu-white", false); + menu.getStyleClass().add("dropdown-offer-list-direction-filter-menu"); + menu.setOpenToTheRight(true); + offerListByDirectionFilter = new Label(); + menu.setLabel(offerListByDirectionFilter); + buyFromOffers = new DropdownMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom")); + sellToOffers = new DropdownMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo")); + menu.addMenuItems(buyFromOffers, sellToOffers); + return menu; + } + + private DropdownMenu createAndGetPaymentsFilterDropdownMenu() { + DropdownMenu menu = new DropdownMenu("chevron-drop-menu-grey", "chevron-drop-menu-white", false); + menu.getStyleClass().add("dropdown-offer-list-payment-filter-menu"); + menu.setOpenToTheRight(true); + menu.setLabel(new Label(Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.title"))); + return menu; + } + private void configOffersTableView() { tableView.getColumns().add(tableView.getSelectionMarkerColumn()); diff --git a/apps/desktop/desktop/src/main/resources/css/bisq_easy.css b/apps/desktop/desktop/src/main/resources/css/bisq_easy.css index 6bf57eea85..bcbc2d3a1f 100644 --- a/apps/desktop/desktop/src/main/resources/css/bisq_easy.css +++ b/apps/desktop/desktop/src/main/resources/css/bisq_easy.css @@ -328,6 +328,11 @@ -fx-text-fill: -bisq2-red-lit-40; } +/* PAYMENT METHODS FILTER */ +.dropdown-offer-list-payment-filter-menu { + -fx-padding: 0 5 0 5; +} + /* COLLAPSE AND EXPAND COLUMNS */ .collapsed-offer-list-container { -fx-background-color: -bisq-dark-grey-20; diff --git a/i18n/src/main/resources/bisq_easy.properties b/i18n/src/main/resources/bisq_easy.properties index 6550e2d8dd..1326531a5a 100644 --- a/i18n/src/main/resources/bisq_easy.properties +++ b/i18n/src/main/resources/bisq_easy.properties @@ -453,6 +453,7 @@ bisqEasy.offerbook.offerList.table.columns.paymentMethod=Payment bisqEasy.offerbook.offerList.table.columns.settlementMethod=Settlement bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom=Buy from bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo=Sell to +bisqEasy.offerbook.offerList.table.filters.paymentMethods.title=Payments bisqEasy.offerbook.offerList.table.columns.price.tooltip.fixPrice=Fixed price: {0}\nPercentage from current market price: {1} bisqEasy.offerbook.offerList.table.columns.price.tooltip.marketPrice=Market price: {0} From 0413687a516451fa3022fc96749804209b8c52ba Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Sat, 24 Aug 2024 19:16:34 +0200 Subject: [PATCH 4/7] Show all payments available in that market as filters --- .../components/controls/DropdownMenuItem.java | 2 +- .../OfferbookListController.java | 13 ++- .../offerbook_list/OfferbookListModel.java | 8 ++ .../offerbook_list/OfferbookListView.java | 97 ++++++++++++++++--- i18n/src/main/resources/bisq_easy.properties | 3 +- 5 files changed, 106 insertions(+), 17 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java index f393743676..6bf0e3eabf 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java @@ -22,8 +22,8 @@ import javafx.scene.control.CustomMenuItem; import lombok.Getter; +@Getter public class DropdownMenuItem extends CustomMenuItem { - @Getter private final BisqMenuItem bisqMenuItem; public DropdownMenuItem(String defaultIconId, String activeIconId, String text) { diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java index d89260cfd3..c126a7b87a 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java @@ -17,6 +17,7 @@ package bisq.desktop.main.content.bisq_easy.offerbook.offerbook_list; +import bisq.account.payment_method.FiatPaymentMethodUtil; import bisq.bonded_roles.market_price.MarketPriceService; import bisq.chat.bisqeasy.offerbook.BisqEasyOfferbookChannel; import bisq.chat.bisqeasy.offerbook.BisqEasyOfferbookMessage; @@ -48,7 +49,7 @@ public class OfferbookListController implements bisq.desktop.common.view.Control private final MarketPriceService marketPriceService; private final ReputationService reputationService; private Pin showBuyOffersPin, showOfferListExpandedSettingsPin, offerMessagesPin; - private Subscription showBuyOffersFromModelPin; + private Subscription showBuyOffersFromModelPin, activeMarketPaymentsCountPin; public OfferbookListController(ServiceProvider serviceProvider, ChatMessageContainerController chatMessageContainerController) { @@ -71,8 +72,13 @@ public void onActivate() { showOfferListExpandedSettingsPin = FxBindings.bindBiDir(model.getShowOfferListExpanded()).to(settingsService.getShowOfferListExpanded()); showBuyOffersFromModelPin = EasyBind.subscribe(model.getShowBuyOffers(), showBuyOffers -> model.getFilteredOfferbookListItems().setPredicate(item -> + // TODO: compare as well selectedMarkets if any showBuyOffers == item.isBuyOffer() )); + activeMarketPaymentsCountPin = EasyBind.subscribe(model.getActiveMarketPaymentsCount(), count -> { + String hint = count.intValue() == 0 ? Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.title.all") : count.toString(); + model.getPaymentFilterTitle().set(Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.title", hint)); + }); } @Override @@ -82,6 +88,7 @@ public void onDeactivate() { showBuyOffersPin.unbind(); showOfferListExpandedSettingsPin.unbind(); showBuyOffersFromModelPin.unsubscribe(); + activeMarketPaymentsCountPin.unsubscribe(); if (offerMessagesPin != null) { offerMessagesPin.unbind(); } @@ -96,6 +103,10 @@ public void setSelectedChannel(BisqEasyOfferbookChannel channel) { model.getFiatAmountTitle().set(Res.get("bisqEasy.offerbook.offerList.table.columns.fiatAmount", channel.getMarket().getQuoteCurrencyCode()).toUpperCase()); + model.getAvailableMarketPayments().setAll(FiatPaymentMethodUtil.getPaymentMethods(channel.getMarket().getQuoteCurrencyCode())); + model.getSelectedMarketPayments().clear(); + model.getActiveMarketPaymentsCount().set(0); + offerMessagesPin = channel.getChatMessages().addObserver(new CollectionObserver<>() { @Override public void add(BisqEasyOfferbookMessage bisqEasyOfferbookMessage) { diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java index 50af67bd0d..777f19fe4f 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java @@ -17,12 +17,16 @@ package bisq.desktop.main.content.bisq_easy.offerbook.offerbook_list; +import bisq.account.payment_method.FiatPaymentMethod; import javafx.beans.property.BooleanProperty; +import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.collections.ObservableSet; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; import lombok.Getter; @@ -35,6 +39,10 @@ class OfferbookListModel implements bisq.desktop.common.view.Model { private final StringProperty fiatAmountTitle = new SimpleStringProperty(); private final BooleanProperty showBuyOffers = new SimpleBooleanProperty(); private final BooleanProperty showOfferListExpanded = new SimpleBooleanProperty(); + private final StringProperty paymentFilterTitle = new SimpleStringProperty(); + private final ObservableList availableMarketPayments = FXCollections.observableArrayList(); + private final ObservableSet selectedMarketPayments = FXCollections.observableSet(); + private final IntegerProperty activeMarketPaymentsCount = new SimpleIntegerProperty(); OfferbookListModel() { } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java index 75f7e23964..67c51c48a9 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java @@ -35,6 +35,8 @@ import bisq.desktop.main.content.components.UserProfileIcon; import bisq.i18n.Res; import com.google.common.base.Joiner; +import javafx.collections.ListChangeListener; +import javafx.css.PseudoClass; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Cursor; @@ -67,9 +69,10 @@ public class OfferbookListView extends bisq.desktop.common.view.View listChangeListener; private DropdownMenuItem buyFromOffers, sellToOffers; - private Label offerListByDirectionFilter; + private Label offerDirectionFilterLabel, paymentsFilterLabel; private Subscription showOfferListExpandedPin, showBuyFromOffersPin, offerListTableViewSelectionPin; OfferbookListView(OfferbookListModel model, OfferbookListController controller) { @@ -91,13 +94,14 @@ public class OfferbookListView extends bisq.desktop.common.view.View updateMarketPaymentFilters(); + offerDirectionFilterMenu = createAndGetOffersDirectionFilterMenu(); paymentsFilterMenu = createAndGetPaymentsFilterDropdownMenu(); HBox subheader = new HBox(10); subheader.setAlignment(Pos.CENTER_LEFT); subheader.getStyleClass().add("offer-list-subheader"); - subheader.getChildren().addAll(offersDirectionFilterMenu, paymentsFilterMenu); + subheader.getChildren().addAll(offerDirectionFilterMenu, paymentsFilterMenu); tableView = new BisqTableView<>(model.getSortedOfferbookListItems()); tableView.getStyleClass().add("offers-list"); @@ -113,12 +117,14 @@ public class OfferbookListView extends bisq.desktop.common.view.View { if (showOfferListExpanded != null) { tableView.setVisible(showOfferListExpanded); tableView.setManaged(showOfferListExpanded); - offersDirectionFilterMenu.setVisible(showOfferListExpanded); - offersDirectionFilterMenu.setManaged(showOfferListExpanded); + offerDirectionFilterMenu.setVisible(showOfferListExpanded); + offerDirectionFilterMenu.setManaged(showOfferListExpanded); title.setGraphic(offerListGreyIcon); if (showOfferListExpanded) { header.setAlignment(Pos.CENTER_LEFT); @@ -157,17 +163,20 @@ protected void onViewAttached() { showBuyFromOffersPin = EasyBind.subscribe(model.getShowBuyOffers(), showBuyFromOffers -> { if (showBuyFromOffers != null) { - offerListByDirectionFilter.getStyleClass().clear(); + offerDirectionFilterLabel.getStyleClass().clear(); if (showBuyFromOffers) { - offerListByDirectionFilter.setText(sellToOffers.getLabelText()); - offerListByDirectionFilter.getStyleClass().add("sell-to-offers"); + offerDirectionFilterLabel.setText(sellToOffers.getLabelText()); + offerDirectionFilterLabel.getStyleClass().add("sell-to-offers"); } else { - offerListByDirectionFilter.setText(buyFromOffers.getLabelText()); - offerListByDirectionFilter.getStyleClass().add("buy-from-offers"); + offerDirectionFilterLabel.setText(buyFromOffers.getLabelText()); + offerDirectionFilterLabel.getStyleClass().add("buy-from-offers"); } } }); + model.getAvailableMarketPayments().addListener(listChangeListener); + updateMarketPaymentFilters(); + title.setOnMouseEntered(e -> title.setGraphic(offerListWhiteIcon)); title.setOnMouseClicked(e -> controller.toggleOfferList()); buyFromOffers.setOnAction(e -> controller.onSelectBuyFromFilter()); @@ -178,10 +187,14 @@ protected void onViewAttached() { @Override protected void onViewDetached() { + paymentsFilterLabel.textProperty().unbind(); + showOfferListExpandedPin.unsubscribe(); offerListTableViewSelectionPin.unsubscribe(); showBuyFromOffersPin.unsubscribe(); + model.getAvailableMarketPayments().removeListener(listChangeListener); + title.setOnMouseEntered(null); title.setOnMouseExited(null); title.setOnMouseClicked(null); @@ -189,14 +202,16 @@ protected void onViewDetached() { sellToOffers.setOnAction(null); title.setTooltip(null); + + cleanUpPaymentsFilterMenu(); } private DropdownMenu createAndGetOffersDirectionFilterMenu() { DropdownMenu menu = new DropdownMenu("chevron-drop-menu-grey", "chevron-drop-menu-white", false); menu.getStyleClass().add("dropdown-offer-list-direction-filter-menu"); menu.setOpenToTheRight(true); - offerListByDirectionFilter = new Label(); - menu.setLabel(offerListByDirectionFilter); + offerDirectionFilterLabel = new Label(); + menu.setLabel(offerDirectionFilterLabel); buyFromOffers = new DropdownMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom")); sellToOffers = new DropdownMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo")); menu.addMenuItems(buyFromOffers, sellToOffers); @@ -207,10 +222,36 @@ private DropdownMenu createAndGetPaymentsFilterDropdownMenu() { DropdownMenu menu = new DropdownMenu("chevron-drop-menu-grey", "chevron-drop-menu-white", false); menu.getStyleClass().add("dropdown-offer-list-payment-filter-menu"); menu.setOpenToTheRight(true); - menu.setLabel(new Label(Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.title"))); + paymentsFilterLabel = new Label(); + menu.setLabel(paymentsFilterLabel); return menu; } + private void updateMarketPaymentFilters() { + cleanUpPaymentsFilterMenu(); + model.getAvailableMarketPayments().forEach(payment -> { + PaymentMenuItem item = new PaymentMenuItem(payment); + item.setOnAction(e -> { + item.updateSelection(!item.isSelected()); + if (item.isSelected()) { + model.getSelectedMarketPayments().add(payment); + } else { + model.getSelectedMarketPayments().remove(payment); + } + model.getActiveMarketPaymentsCount().set(model.getSelectedMarketPayments().size()); + }); + paymentsFilterMenu.addMenuItems(item); + }); + } + + private void cleanUpPaymentsFilterMenu() { + paymentsFilterMenu.getMenuItems().stream() + .filter(item -> item instanceof PaymentMenuItem) + .map(item -> (PaymentMenuItem) item) + .forEach(PaymentMenuItem::dispose); + paymentsFilterMenu.clearMenuItems(); + } + private void configOffersTableView() { tableView.getColumns().add(tableView.getSelectionMarkerColumn()); @@ -422,4 +463,32 @@ protected void updateItem(OfferbookListItem item, boolean empty) { } }; } + + private static final class PaymentMenuItem extends DropdownMenuItem { + private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected"); + + PaymentMenuItem(FiatPaymentMethod fiatPaymentMethod) { + // TODO: Update code so that we can pass label instead of text + super("check-white", "check-white", fiatPaymentMethod.getDisplayString()); + + getStyleClass().add("dropdown-menu-item"); + updateSelection(false); + initialize(); + } + + public void initialize() { + } + + public void dispose() { + setOnAction(null); + } + + void updateSelection(boolean isSelected) { + getContent().pseudoClassStateChanged(SELECTED_PSEUDO_CLASS, isSelected); + } + + boolean isSelected() { + return getContent().getPseudoClassStates().contains(SELECTED_PSEUDO_CLASS); + } + } } diff --git a/i18n/src/main/resources/bisq_easy.properties b/i18n/src/main/resources/bisq_easy.properties index 1326531a5a..a8fe2670d9 100644 --- a/i18n/src/main/resources/bisq_easy.properties +++ b/i18n/src/main/resources/bisq_easy.properties @@ -453,7 +453,8 @@ bisqEasy.offerbook.offerList.table.columns.paymentMethod=Payment bisqEasy.offerbook.offerList.table.columns.settlementMethod=Settlement bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom=Buy from bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo=Sell to -bisqEasy.offerbook.offerList.table.filters.paymentMethods.title=Payments +bisqEasy.offerbook.offerList.table.filters.paymentMethods.title=Payments ({0}) +bisqEasy.offerbook.offerList.table.filters.paymentMethods.title.all=all bisqEasy.offerbook.offerList.table.columns.price.tooltip.fixPrice=Fixed price: {0}\nPercentage from current market price: {1} bisqEasy.offerbook.offerList.table.columns.price.tooltip.marketPrice=Market price: {0} From dae4b20305693769028f83ca3cb402b89da830cf Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Sat, 24 Aug 2024 19:42:24 +0200 Subject: [PATCH 5/7] Add support to filter by custom methods --- .../OfferbookListController.java | 32 +++++++++++++++++-- .../offerbook_list/OfferbookListModel.java | 1 + .../offerbook_list/OfferbookListView.java | 22 +++++++------ i18n/src/main/resources/bisq_easy.properties | 1 + 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java index c126a7b87a..3aa94ebd5a 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java @@ -17,6 +17,7 @@ package bisq.desktop.main.content.bisq_easy.offerbook.offerbook_list; +import bisq.account.payment_method.FiatPaymentMethod; import bisq.account.payment_method.FiatPaymentMethodUtil; import bisq.bonded_roles.market_price.MarketPriceService; import bisq.chat.bisqeasy.offerbook.BisqEasyOfferbookChannel; @@ -104,8 +105,7 @@ public void setSelectedChannel(BisqEasyOfferbookChannel channel) { channel.getMarket().getQuoteCurrencyCode()).toUpperCase()); model.getAvailableMarketPayments().setAll(FiatPaymentMethodUtil.getPaymentMethods(channel.getMarket().getQuoteCurrencyCode())); - model.getSelectedMarketPayments().clear(); - model.getActiveMarketPaymentsCount().set(0); + resetPaymentFilters(); offerMessagesPin = channel.getChatMessages().addObserver(new CollectionObserver<>() { @Override @@ -169,4 +169,32 @@ void onSelectBuyFromFilter() { void onSelectSellToFilter() { model.getShowBuyOffers().set(true); } + + void toggleMethodFilter(FiatPaymentMethod paymentMethod, boolean isSelected) { + if (isSelected) { + model.getSelectedMarketPayments().add(paymentMethod); + } else { + model.getSelectedMarketPayments().remove(paymentMethod); + } + updateActiveMarketPaymentsCount(); + } + + void toggleCustomMethodFilter(boolean isSelected) { + model.getIsCustomPaymentsSelected().set(isSelected); + updateActiveMarketPaymentsCount(); + } + + private void resetPaymentFilters() { + model.getSelectedMarketPayments().clear(); + model.getIsCustomPaymentsSelected().set(false); + updateActiveMarketPaymentsCount(); + } + + private void updateActiveMarketPaymentsCount() { + int count = model.getSelectedMarketPayments().size(); + if (model.getIsCustomPaymentsSelected().get()) { + ++count; + } + model.getActiveMarketPaymentsCount().set(count); + } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java index 777f19fe4f..504b695eb7 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListModel.java @@ -42,6 +42,7 @@ class OfferbookListModel implements bisq.desktop.common.view.Model { private final StringProperty paymentFilterTitle = new SimpleStringProperty(); private final ObservableList availableMarketPayments = FXCollections.observableArrayList(); private final ObservableSet selectedMarketPayments = FXCollections.observableSet(); + private final BooleanProperty isCustomPaymentsSelected = new SimpleBooleanProperty(); private final IntegerProperty activeMarketPaymentsCount = new SimpleIntegerProperty(); OfferbookListModel() { diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java index 67c51c48a9..b7f21e5f8d 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java @@ -229,19 +229,22 @@ private DropdownMenu createAndGetPaymentsFilterDropdownMenu() { private void updateMarketPaymentFilters() { cleanUpPaymentsFilterMenu(); + model.getAvailableMarketPayments().forEach(payment -> { - PaymentMenuItem item = new PaymentMenuItem(payment); + PaymentMenuItem item = new PaymentMenuItem(payment.getDisplayString()); item.setOnAction(e -> { item.updateSelection(!item.isSelected()); - if (item.isSelected()) { - model.getSelectedMarketPayments().add(payment); - } else { - model.getSelectedMarketPayments().remove(payment); - } - model.getActiveMarketPaymentsCount().set(model.getSelectedMarketPayments().size()); + controller.toggleMethodFilter(payment, item.isSelected()); }); paymentsFilterMenu.addMenuItems(item); }); + + PaymentMenuItem customItem = new PaymentMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.customMethod")); + customItem.setOnAction(e -> { + customItem.updateSelection(!customItem.isSelected()); + controller.toggleCustomMethodFilter(customItem.isSelected()); + }); + paymentsFilterMenu.addMenuItems(customItem); } private void cleanUpPaymentsFilterMenu() { @@ -306,7 +309,6 @@ private void configOffersTableView() { .build()); } - private Callback, TableCell> getUserProfileCellFactory() { return column -> new TableCell<>() { @@ -467,9 +469,9 @@ protected void updateItem(OfferbookListItem item, boolean empty) { private static final class PaymentMenuItem extends DropdownMenuItem { private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected"); - PaymentMenuItem(FiatPaymentMethod fiatPaymentMethod) { + PaymentMenuItem(String displayName) { // TODO: Update code so that we can pass label instead of text - super("check-white", "check-white", fiatPaymentMethod.getDisplayString()); + super("check-white", "check-white", displayName); getStyleClass().add("dropdown-menu-item"); updateSelection(false); diff --git a/i18n/src/main/resources/bisq_easy.properties b/i18n/src/main/resources/bisq_easy.properties index a8fe2670d9..0586100ed5 100644 --- a/i18n/src/main/resources/bisq_easy.properties +++ b/i18n/src/main/resources/bisq_easy.properties @@ -455,6 +455,7 @@ bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom=Buy from bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo=Sell to bisqEasy.offerbook.offerList.table.filters.paymentMethods.title=Payments ({0}) bisqEasy.offerbook.offerList.table.filters.paymentMethods.title.all=all +bisqEasy.offerbook.offerList.table.filters.paymentMethods.customMethod=Custom methods bisqEasy.offerbook.offerList.table.columns.price.tooltip.fixPrice=Fixed price: {0}\nPercentage from current market price: {1} bisqEasy.offerbook.offerList.table.columns.price.tooltip.marketPrice=Market price: {0} From 7025d167d816974e622826fc550b6a3ae899276e Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Sat, 24 Aug 2024 20:04:29 +0200 Subject: [PATCH 6/7] Add payment filter logic to offers predicate --- .../OfferbookListController.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java index 3aa94ebd5a..9da7d2961f 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListController.java @@ -71,14 +71,11 @@ public ReadOnlyBooleanProperty getShowOfferListExpanded() { public void onActivate() { showBuyOffersPin = FxBindings.bindBiDir(model.getShowBuyOffers()).to(settingsService.getShowBuyOffers()); showOfferListExpandedSettingsPin = FxBindings.bindBiDir(model.getShowOfferListExpanded()).to(settingsService.getShowOfferListExpanded()); - showBuyOffersFromModelPin = EasyBind.subscribe(model.getShowBuyOffers(), showBuyOffers -> - model.getFilteredOfferbookListItems().setPredicate(item -> - // TODO: compare as well selectedMarkets if any - showBuyOffers == item.isBuyOffer() - )); + showBuyOffersFromModelPin = EasyBind.subscribe(model.getShowBuyOffers(), showBuyOffers -> applyPredicate()); activeMarketPaymentsCountPin = EasyBind.subscribe(model.getActiveMarketPaymentsCount(), count -> { String hint = count.intValue() == 0 ? Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.title.all") : count.toString(); model.getPaymentFilterTitle().set(Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.title", hint)); + applyPredicate(); }); } @@ -197,4 +194,17 @@ private void updateActiveMarketPaymentsCount() { } model.getActiveMarketPaymentsCount().set(count); } + + private void applyPredicate() { + model.getFilteredOfferbookListItems().setPredicate(this::shouldShowListItem); + } + + private boolean shouldShowListItem(OfferbookListItem item) { + boolean matchesDirection = model.getShowBuyOffers().get() == item.isBuyOffer(); + boolean paymentFiltersApplied = model.getActiveMarketPaymentsCount().get() != 0; + boolean matchesPaymentFilters = paymentFiltersApplied && item.getFiatPaymentMethods().stream() + .anyMatch(payment -> (payment.isCustomPaymentMethod() && model.getIsCustomPaymentsSelected().get()) + || model.getSelectedMarketPayments().contains(payment)); + return matchesDirection && (!paymentFiltersApplied || matchesPaymentFilters); + } } From 891e78adf0333f67a2c5926643f2bf39656fa81d Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Sat, 24 Aug 2024 20:09:24 +0200 Subject: [PATCH 7/7] Add capital letter to all string --- i18n/src/main/resources/bisq_easy.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/src/main/resources/bisq_easy.properties b/i18n/src/main/resources/bisq_easy.properties index 0586100ed5..1026853046 100644 --- a/i18n/src/main/resources/bisq_easy.properties +++ b/i18n/src/main/resources/bisq_easy.properties @@ -454,7 +454,7 @@ bisqEasy.offerbook.offerList.table.columns.settlementMethod=Settlement bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom=Buy from bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo=Sell to bisqEasy.offerbook.offerList.table.filters.paymentMethods.title=Payments ({0}) -bisqEasy.offerbook.offerList.table.filters.paymentMethods.title.all=all +bisqEasy.offerbook.offerList.table.filters.paymentMethods.title.all=All bisqEasy.offerbook.offerList.table.filters.paymentMethods.customMethod=Custom methods bisqEasy.offerbook.offerList.table.columns.price.tooltip.fixPrice=Fixed price: {0}\nPercentage from current market price: {1}