diff --git a/core/src/main/java/bisq/core/trade/bisq_v1/TradeUtil.java b/core/src/main/java/bisq/core/trade/bisq_v1/TradeUtil.java
index 9d8212a060b..492b36c9093 100644
--- a/core/src/main/java/bisq/core/trade/bisq_v1/TradeUtil.java
+++ b/core/src/main/java/bisq/core/trade/bisq_v1/TradeUtil.java
@@ -175,16 +175,6 @@ public String getMarketDescription(Trade trade) {
return getCurrencyPair(trade.getOffer().getCurrencyCode());
}
- public String getPaymentMethodNameWithCountryCode(Trade trade) {
- if (trade == null)
- return "";
-
- Offer offer = trade.getOffer();
- checkNotNull(offer);
- checkNotNull(offer.getPaymentMethod());
- return offer.getPaymentMethodNameWithCountryCode();
- }
-
/**
* Returns a string describing a trader's role for a given trade.
* @param trade Trade
diff --git a/desktop/src/main/java/bisq/desktop/components/list/FilterBox.java b/desktop/src/main/java/bisq/desktop/components/list/FilterBox.java
new file mode 100644
index 00000000000..91aca5721a7
--- /dev/null
+++ b/desktop/src/main/java/bisq/desktop/components/list/FilterBox.java
@@ -0,0 +1,73 @@
+/*
+ * 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 .
+ */
+
+package bisq.desktop.components.list;
+
+import bisq.desktop.components.AutoTooltipLabel;
+import bisq.desktop.components.InputTextField;
+import bisq.desktop.util.filtering.FilterableListItem;
+
+import bisq.core.locale.Res;
+
+import javafx.scene.control.TableView;
+import javafx.scene.layout.HBox;
+
+import javafx.geometry.Insets;
+import javafx.beans.value.ChangeListener;
+import javafx.collections.transformation.FilteredList;
+
+public class FilterBox extends HBox {
+ private final InputTextField textField;
+ private FilteredList extends FilterableListItem> filteredList;
+
+ private ChangeListener listener;
+
+ public FilterBox() {
+ super();
+ setSpacing(5.0);
+
+ AutoTooltipLabel label = new AutoTooltipLabel(Res.get("shared.filter"));
+ HBox.setMargin(label, new Insets(5.0, 0, 0, 10.0));
+
+ textField = new InputTextField();
+ textField.setMinWidth(500);
+
+ getChildren().addAll(label, textField);
+ }
+
+ public void initialize(FilteredList extends FilterableListItem> filteredList,
+ TableView extends FilterableListItem> tableView) {
+ this.filteredList = filteredList;
+ listener = (observable, oldValue, newValue) -> {
+ tableView.getSelectionModel().clearSelection();
+ applyFilteredListPredicate(textField.getText());
+ };
+ }
+
+ public void activate() {
+ textField.textProperty().addListener(listener);
+ applyFilteredListPredicate(textField.getText());
+ }
+
+ public void deactivate() {
+ textField.textProperty().removeListener(listener);
+ }
+
+ private void applyFilteredListPredicate(String filterString) {
+ filteredList.setPredicate(item -> item.match(filterString));
+ }
+}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java
index 94b486addd2..722b5a8c8bc 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java
@@ -17,6 +17,7 @@
package bisq.desktop.main.funds.deposit;
+import bisq.desktop.util.filtering.FilterableListItem;
import bisq.desktop.components.indicator.TxConfidenceIndicator;
import bisq.desktop.util.GUIUtil;
@@ -34,6 +35,8 @@
import com.google.common.base.Suppliers;
+import org.apache.commons.lang3.StringUtils;
+
import javafx.scene.control.Tooltip;
import javafx.beans.property.SimpleStringProperty;
@@ -44,7 +47,7 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-class DepositListItem {
+class DepositListItem implements FilterableListItem {
private final StringProperty balance = new SimpleStringProperty();
private final BtcWalletService walletService;
private Coin balanceAsCoin;
@@ -149,4 +152,18 @@ public Coin getBalanceAsCoin() {
public int getNumTxOutputs() {
return numTxOutputs;
}
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAddressString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getUsage(), filterString)) {
+ return true;
+ }
+ return getBalance().contains(filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.fxml b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.fxml
index bde328b7160..a4d9235a568 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.fxml
@@ -23,12 +23,13 @@
+
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java
index cc2c4fed018..e291ad99618 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java
@@ -25,6 +25,7 @@
import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.InputTextField;
import bisq.desktop.components.TitledGroupBg;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.QRCodeWindow;
import bisq.desktop.util.GUIUtil;
@@ -80,6 +81,7 @@
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
@@ -91,7 +93,10 @@
import org.jetbrains.annotations.NotNull;
-import static bisq.desktop.util.FormBuilder.*;
+import static bisq.desktop.util.FormBuilder.addAddressTextField;
+import static bisq.desktop.util.FormBuilder.addButtonCheckBoxWithBox;
+import static bisq.desktop.util.FormBuilder.addInputTextField;
+import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
@FxmlView
public class DepositView extends ActivatableView {
@@ -99,6 +104,8 @@ public class DepositView extends ActivatableView {
@FXML
GridPane gridPane;
@FXML
+ FilterBox filterBox;
+ @FXML
TableView tableView;
@FXML
TableColumn addressColumn, balanceColumn, confirmationsColumn, usageColumn;
@@ -114,7 +121,8 @@ public class DepositView extends ActivatableView {
private final CoinFormatter formatter;
private String paymentLabelString;
private final ObservableList observableList = FXCollections.observableArrayList();
- private final SortedList sortedList = new SortedList<>(observableList);
+ private final FilteredList filteredList = new FilteredList<>(observableList);
+ private final SortedList sortedList = new SortedList<>(filteredList);
private BalanceListener balanceListener;
private Subscription amountTextFieldSubscription;
private ChangeListener tableViewSelectionListener;
@@ -135,7 +143,7 @@ private DepositView(BtcWalletService walletService,
@Override
public void initialize() {
-
+ filterBox.initialize(filteredList, tableView);
paymentLabelString = Res.get("funds.deposit.fundBisqWallet");
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
balanceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.balanceWithCur", Res.getBaseCurrencyCode())));
@@ -238,6 +246,8 @@ public void onBalanceChanged(Coin balance, Transaction tx) {
@Override
protected void activate() {
+ filterBox.activate();
+
tableView.getSelectionModel().selectedItemProperty().addListener(tableViewSelectionListener);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
@@ -255,6 +265,7 @@ protected void activate() {
@Override
protected void deactivate() {
+ filterBox.deactivate();
tableView.getSelectionModel().selectedItemProperty().removeListener(tableViewSelectionListener);
sortedList.comparatorProperty().unbind();
observableList.forEach(DepositListItem::cleanup);
@@ -267,7 +278,6 @@ protected void deactivate() {
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
-
private void fillForm(String address) {
titledGroupBg.setVisible(true);
titledGroupBg.setManaged(true);
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedListItem.java
index e7f483078dd..bf234e96e01 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedListItem.java
@@ -17,8 +17,10 @@
package bisq.desktop.main.funds.locked;
+import bisq.desktop.util.filtering.FilterableListItem;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.util.DisplayUtils;
+import bisq.desktop.util.filtering.FilteringUtils;
import bisq.core.btc.listeners.BalanceListener;
import bisq.core.btc.model.AddressEntry;
@@ -32,13 +34,15 @@
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
+import org.apache.commons.lang3.StringUtils;
+
import javafx.scene.control.Label;
import lombok.Getter;
import javax.annotation.Nullable;
-class LockedListItem {
+class LockedListItem implements FilterableListItem {
private final BalanceListener balanceListener;
private final BtcWalletService btcWalletService;
private final CoinFormatter formatter;
@@ -117,4 +121,28 @@ public String getDateString() {
DisplayUtils.formatDateTime(trade.getDate()) :
Res.get("shared.noDateAvailable");
}
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty())
+ return true;
+
+ if (StringUtils.containsIgnoreCase(getDetails(), filterString)) {
+ return true;
+ }
+
+ if (StringUtils.containsIgnoreCase(getDateString(), filterString)) {
+ return true;
+ }
+
+ if (StringUtils.containsIgnoreCase(getAddressString(), filterString)) {
+ return true;
+ }
+
+ if (StringUtils.containsIgnoreCase(getBalanceString(), filterString)) {
+ return true;
+ }
+
+ return FilteringUtils.match(getTrade(), filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.fxml b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.fxml
index 623c3e99f67..622a8aeafb6 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.fxml
@@ -25,12 +25,13 @@
+
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java
index 45544d09e48..fc52fad5736 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java
@@ -23,6 +23,7 @@
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.ExternalHyperlink;
import bisq.desktop.components.HyperlinkWithIcon;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
import bisq.desktop.util.GUIUtil;
@@ -71,6 +72,7 @@
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
@@ -83,6 +85,8 @@
@FxmlView
public class LockedView extends ActivatableView {
+ @FXML
+ FilterBox filterBox;
@FXML
TableView tableView;
@FXML
@@ -102,7 +106,8 @@ public class LockedView extends ActivatableView {
private final OfferDetailsWindow offerDetailsWindow;
private final TradeDetailsWindow tradeDetailsWindow;
private final ObservableList observableList = FXCollections.observableArrayList();
- private final SortedList sortedList = new SortedList<>(observableList);
+ private final FilteredList filteredList = new FilteredList<>(observableList);
+ private final SortedList sortedList = new SortedList<>(filteredList);
private BalanceListener balanceListener;
private ListChangeListener openOfferListChangeListener;
private ListChangeListener tradeListChangeListener;
@@ -131,6 +136,7 @@ private LockedView(BtcWalletService btcWalletService,
@Override
public void initialize() {
+ filterBox.initialize(filteredList, tableView);
dateColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.dateTime")));
detailsColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.details")));
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
@@ -168,6 +174,7 @@ public void onBalanceChanged(Coin balance, Transaction tx) {
@Override
protected void activate() {
+ filterBox.activate();
openOfferManager.getObservableList().addListener(openOfferListChangeListener);
tradeManager.getObservableList().addListener(tradeListChangeListener);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
@@ -206,6 +213,7 @@ protected void activate() {
@Override
protected void deactivate() {
+ filterBox.deactivate();
openOfferManager.getObservableList().removeListener(openOfferListChangeListener);
tradeManager.getObservableList().removeListener(tradeListChangeListener);
sortedList.comparatorProperty().unbind();
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedListItem.java
index 04d7ad75a2e..b0b127b5f61 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedListItem.java
@@ -17,8 +17,10 @@
package bisq.desktop.main.funds.reserved;
+import bisq.desktop.util.filtering.FilterableListItem;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.util.DisplayUtils;
+import bisq.desktop.util.filtering.FilteringUtils;
import bisq.core.btc.listeners.BalanceListener;
import bisq.core.btc.model.AddressEntry;
@@ -31,13 +33,15 @@
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
+import org.apache.commons.lang3.StringUtils;
+
import javafx.scene.control.Label;
import java.util.Optional;
import lombok.Getter;
-class ReservedListItem {
+class ReservedListItem implements FilterableListItem {
private final BalanceListener balanceListener;
private final BtcWalletService btcWalletService;
private final CoinFormatter formatter;
@@ -114,4 +118,24 @@ public String getDetails() {
Res.get("funds.reserved.reserved", openOffer.getShortId()) :
Res.get("shared.noDetailsAvailable");
}
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDetails(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAddressString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDateAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getBalanceString(), filterString)) {
+ return true;
+ }
+ return FilteringUtils.match(getOpenOffer().getOffer(), filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.fxml b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.fxml
index 8a43556b99e..0a2e01cd988 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.fxml
@@ -25,12 +25,13 @@
+
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java
index ab42a4fd745..31404bc1e1b 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java
@@ -23,6 +23,7 @@
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.ExternalHyperlink;
import bisq.desktop.components.HyperlinkWithIcon;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
import bisq.desktop.util.GUIUtil;
@@ -71,6 +72,7 @@
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
@@ -83,6 +85,8 @@
@FxmlView
public class ReservedView extends ActivatableView {
+ @FXML
+ FilterBox filterBox;
@FXML
TableView tableView;
@FXML
@@ -102,7 +106,8 @@ public class ReservedView extends ActivatableView {
private final OfferDetailsWindow offerDetailsWindow;
private final TradeDetailsWindow tradeDetailsWindow;
private final ObservableList observableList = FXCollections.observableArrayList();
- private final SortedList sortedList = new SortedList<>(observableList);
+ private final FilteredList filteredList = new FilteredList<>(observableList);
+ private final SortedList sortedList = new SortedList<>(filteredList);
private BalanceListener balanceListener;
private ListChangeListener openOfferListChangeListener;
private ListChangeListener tradeListChangeListener;
@@ -131,6 +136,7 @@ private ReservedView(BtcWalletService btcWalletService,
@Override
public void initialize() {
+ filterBox.initialize(filteredList, tableView);
dateColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.dateTime")));
detailsColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.details")));
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
@@ -168,6 +174,7 @@ public void onBalanceChanged(Coin balance, Transaction tx) {
@Override
protected void activate() {
+ filterBox.activate();
openOfferManager.getObservableList().addListener(openOfferListChangeListener);
tradeManager.getObservableList().addListener(tradeListChangeListener);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
@@ -206,6 +213,7 @@ protected void activate() {
@Override
protected void deactivate() {
+ filterBox.deactivate();
openOfferManager.getObservableList().removeListener(openOfferListChangeListener);
tradeManager.getObservableList().removeListener(tradeListChangeListener);
sortedList.comparatorProperty().unbind();
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/DisplayedTransactions.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/DisplayedTransactions.java
deleted file mode 100644
index a94466f9cc4..00000000000
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/DisplayedTransactions.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 .
- */
-
-package bisq.desktop.main.funds.transactions;
-
-import bisq.core.btc.wallet.BtcWalletService;
-import bisq.core.trade.model.Tradable;
-
-import org.bitcoinj.core.Transaction;
-
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-class DisplayedTransactions extends ObservableListDecorator {
- private final BtcWalletService btcWalletService;
- private final TradableRepository tradableRepository;
- private final TransactionListItemFactory transactionListItemFactory;
- private final TransactionAwareTradableFactory transactionAwareTradableFactory;
-
- DisplayedTransactions(BtcWalletService btcWalletService, TradableRepository tradableRepository,
- TransactionListItemFactory transactionListItemFactory,
- TransactionAwareTradableFactory transactionAwareTradableFactory) {
- this.btcWalletService = btcWalletService;
- this.tradableRepository = tradableRepository;
- this.transactionListItemFactory = transactionListItemFactory;
- this.transactionAwareTradableFactory = transactionAwareTradableFactory;
- }
-
- void update() {
- List transactionsListItems = getTransactionListItems();
- // are sorted by getRecentTransactions
- forEach(TransactionsListItem::cleanup);
- setAll(transactionsListItems);
- }
-
- private List getTransactionListItems() {
- Set transactions = btcWalletService.getTransactions(false);
- return transactions.stream()
- .map(this::convertTransactionToListItem)
- .collect(Collectors.toList());
- }
-
- private TransactionsListItem convertTransactionToListItem(Transaction transaction) {
- Set tradables = tradableRepository.getAll();
-
- TransactionAwareTradable maybeTradable = tradables.stream()
- .map(transactionAwareTradableFactory::create)
- .filter(tradable -> tradable.isRelatedToTransaction(transaction))
- .findAny()
- .orElse(null);
-
- return transactionListItemFactory.create(transaction, maybeTradable);
- }
-}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/DisplayedTransactionsFactory.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/DisplayedTransactionsFactory.java
deleted file mode 100644
index 049b8efe6b4..00000000000
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/DisplayedTransactionsFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 .
- */
-
-package bisq.desktop.main.funds.transactions;
-
-import bisq.core.btc.wallet.BtcWalletService;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-public class DisplayedTransactionsFactory {
- private final BtcWalletService btcWalletService;
- private final TradableRepository tradableRepository;
- private final TransactionListItemFactory transactionListItemFactory;
- private final TransactionAwareTradableFactory transactionAwareTradableFactory;
-
- @Inject
- DisplayedTransactionsFactory(BtcWalletService btcWalletService,
- TradableRepository tradableRepository,
- TransactionListItemFactory transactionListItemFactory,
- TransactionAwareTradableFactory transactionAwareTradableFactory) {
- this.btcWalletService = btcWalletService;
- this.tradableRepository = tradableRepository;
- this.transactionListItemFactory = transactionListItemFactory;
- this.transactionAwareTradableFactory = transactionAwareTradableFactory;
- }
-
- DisplayedTransactions create() {
- return new DisplayedTransactions(btcWalletService, tradableRepository, transactionListItemFactory,
- transactionAwareTradableFactory);
- }
-}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/ObservableListDecorator.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/ObservableListDecorator.java
deleted file mode 100644
index f5f6ea3d649..00000000000
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/ObservableListDecorator.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 .
- */
-
-package bisq.desktop.main.funds.transactions;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import javafx.collections.transformation.SortedList;
-
-import java.util.AbstractList;
-import java.util.Collection;
-
-class ObservableListDecorator extends AbstractList {
- private final ObservableList delegate = FXCollections.observableArrayList();
-
- SortedList asSortedList() {
- return new SortedList<>(delegate);
- }
-
- void setAll(Collection extends T> elements) {
- delegate.setAll(elements);
- }
-
- @Override
- public T get(int index) {
- return delegate.get(index);
- }
-
- @Override
- public int size() {
- return delegate.size();
- }
-}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTradableFactory.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTradableFactory.java
deleted file mode 100644
index 3c699d9a0f0..00000000000
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTradableFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 .
- */
-
-package bisq.desktop.main.funds.transactions;
-
-import bisq.core.btc.wallet.BtcWalletService;
-import bisq.core.offer.OpenOffer;
-import bisq.core.support.dispute.arbitration.ArbitrationManager;
-import bisq.core.support.dispute.refund.RefundManager;
-import bisq.core.trade.model.Tradable;
-import bisq.core.trade.model.TradeModel;
-
-import bisq.common.crypto.PubKeyRing;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-
-@Singleton
-public class TransactionAwareTradableFactory {
- private final ArbitrationManager arbitrationManager;
- private final RefundManager refundManager;
- private final BtcWalletService btcWalletService;
- private final PubKeyRing pubKeyRing;
-
- @Inject
- TransactionAwareTradableFactory(ArbitrationManager arbitrationManager,
- RefundManager refundManager,
- BtcWalletService btcWalletService,
- PubKeyRing pubKeyRing) {
- this.arbitrationManager = arbitrationManager;
- this.refundManager = refundManager;
- this.btcWalletService = btcWalletService;
- this.pubKeyRing = pubKeyRing;
- }
-
- TransactionAwareTradable create(Tradable tradable) {
- if (tradable instanceof OpenOffer) {
- return new TransactionAwareOpenOffer((OpenOffer) tradable);
- } else if (tradable instanceof TradeModel) {
- return new TransactionAwareTrade((TradeModel) tradable,
- arbitrationManager,
- refundManager,
- btcWalletService,
- pubKeyRing);
- } else {
- return new DummyTransactionAwareTradable(tradable);
- }
- }
-}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java
deleted file mode 100644
index 55234b486cd..00000000000
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 .
- */
-
-package bisq.desktop.main.funds.transactions;
-
-import bisq.core.btc.wallet.BsqWalletService;
-import bisq.core.btc.wallet.BtcWalletService;
-import bisq.core.dao.DaoFacade;
-import bisq.core.user.Preferences;
-import bisq.core.util.FormattingUtils;
-import bisq.core.util.coin.CoinFormatter;
-
-import org.bitcoinj.core.Transaction;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import javax.annotation.Nullable;
-
-
-@Singleton
-public class TransactionListItemFactory {
- private final BtcWalletService btcWalletService;
- private final BsqWalletService bsqWalletService;
- private final DaoFacade daoFacade;
- private final CoinFormatter formatter;
- private final Preferences preferences;
-
- @Inject
- TransactionListItemFactory(BtcWalletService btcWalletService,
- BsqWalletService bsqWalletService,
- DaoFacade daoFacade,
- @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
- Preferences preferences) {
- this.btcWalletService = btcWalletService;
- this.bsqWalletService = bsqWalletService;
- this.daoFacade = daoFacade;
- this.formatter = formatter;
- this.preferences = preferences;
- }
-
- TransactionsListItem create(Transaction transaction, @Nullable TransactionAwareTradable tradable) {
- return new TransactionsListItem(transaction,
- btcWalletService,
- bsqWalletService,
- tradable,
- daoFacade,
- formatter,
- preferences.getIgnoreDustThreshold());
- }
-}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java
index d6a41f76f3b..2f3ada6b383 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java
@@ -17,6 +17,7 @@
package bisq.desktop.main.funds.transactions;
+import bisq.desktop.util.filtering.FilterableListItem;
import bisq.desktop.components.indicator.TxConfidenceIndicator;
import bisq.desktop.util.DisplayUtils;
import bisq.desktop.util.GUIUtil;
@@ -43,6 +44,8 @@
import com.google.common.base.Suppliers;
+import org.apache.commons.lang3.StringUtils;
+
import javafx.scene.control.Tooltip;
import java.util.Date;
@@ -55,7 +58,7 @@
import javax.annotation.Nullable;
@Slf4j
-class TransactionsListItem {
+class TransactionsListItem implements FilterableListItem {
private final BtcWalletService btcWalletService;
private final CoinFormatter formatter;
private String dateString;
@@ -377,4 +380,30 @@ public String getNumConfirmations() {
public String getMemo() {
return memo;
}
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getTxId(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDetails(), filterString)) {
+ return true;
+ }
+ if (getMemo() != null && StringUtils.containsIgnoreCase(getMemo(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDirection(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDateString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAmount(), filterString)) {
+ return true;
+ }
+ return StringUtils.containsIgnoreCase(getAddressString(), filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.fxml b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.fxml
index b2554dfca6d..ea8d8e5d678 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.fxml
@@ -25,11 +25,13 @@
+
+
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
index 49e307f1b07..20075212c57 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
@@ -24,6 +24,7 @@
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.ExternalHyperlink;
import bisq.desktop.components.HyperlinkWithIcon;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.BsqTradeDetailsWindow;
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
@@ -31,16 +32,24 @@
import bisq.desktop.util.GUIUtil;
import bisq.core.btc.setup.WalletsSetup;
+import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.dao.DaoFacade;
import bisq.core.locale.Res;
import bisq.core.offer.OpenOffer;
+import bisq.core.support.dispute.arbitration.ArbitrationManager;
+import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.trade.model.Tradable;
+import bisq.core.trade.model.TradeModel;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
import bisq.core.user.Preferences;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.coin.CoinFormatter;
import bisq.network.p2p.P2PService;
+import bisq.common.crypto.PubKeyRing;
import bisq.common.util.Utilities;
import org.bitcoinj.core.TransactionConfidence;
@@ -49,6 +58,7 @@
import com.googlecode.jcsv.writer.CSVEntryConverter;
import javax.inject.Inject;
+import javax.inject.Named;
import de.jensd.fx.fontawesome.AwesomeIcon;
@@ -76,17 +86,24 @@
import javafx.event.EventHandler;
+import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
@FxmlView
public class TransactionsView extends ActivatableView {
+ @FXML
+ FilterBox filterBox;
@FXML
TableView tableView;
@FXML
@@ -98,13 +115,21 @@ public class TransactionsView extends ActivatableView {
@FXML
AutoTooltipButton exportButton;
- private final DisplayedTransactions displayedTransactions;
- private final SortedList sortedDisplayedTransactions;
+ private final ObservableList observableList = FXCollections.observableArrayList();
+ private final FilteredList filteredList = new FilteredList<>(observableList);
+ private final SortedList sortedList = new SortedList<>(filteredList);
private final BtcWalletService btcWalletService;
+ private final BsqWalletService bsqWalletService;
+ private final CoinFormatter formatter;
+ private final DaoFacade daoFacade;
private final P2PService p2PService;
private final WalletsSetup walletsSetup;
private final Preferences preferences;
+ private final TradableRepository tradableRepository;
+ private final ArbitrationManager arbitrationManager;
+ private final RefundManager refundManager;
+ private final PubKeyRing pubKeyRing;
private final TradeDetailsWindow tradeDetailsWindow;
private final BsqTradeDetailsWindow bsqTradeDetailsWindow;
private final OfferDetailsWindow offerDetailsWindow;
@@ -120,26 +145,38 @@ public class TransactionsView extends ActivatableView {
@Inject
private TransactionsView(BtcWalletService btcWalletService,
+ BsqWalletService bsqWalletService,
+ DaoFacade daoFacade,
+ @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
P2PService p2PService,
WalletsSetup walletsSetup,
Preferences preferences,
+ TradableRepository tradableRepository,
+ ArbitrationManager arbitrationManager,
+ RefundManager refundManager,
+ PubKeyRing pubKeyRing,
TradeDetailsWindow tradeDetailsWindow,
BsqTradeDetailsWindow bsqTradeDetailsWindow,
- OfferDetailsWindow offerDetailsWindow,
- DisplayedTransactionsFactory displayedTransactionsFactory) {
+ OfferDetailsWindow offerDetailsWindow) {
this.btcWalletService = btcWalletService;
+ this.bsqWalletService = bsqWalletService;
+ this.daoFacade = daoFacade;
+ this.formatter = formatter;
this.p2PService = p2PService;
this.walletsSetup = walletsSetup;
this.preferences = preferences;
+ this.tradableRepository = tradableRepository;
+ this.arbitrationManager = arbitrationManager;
+ this.refundManager = refundManager;
+ this.pubKeyRing = pubKeyRing;
this.tradeDetailsWindow = tradeDetailsWindow;
this.bsqTradeDetailsWindow = bsqTradeDetailsWindow;
this.offerDetailsWindow = offerDetailsWindow;
- this.displayedTransactions = displayedTransactionsFactory.create();
- this.sortedDisplayedTransactions = displayedTransactions.asSortedList();
}
@Override
public void initialize() {
+ filterBox.initialize(filteredList, tableView);
dateColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.dateTime")));
detailsColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.details")));
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
@@ -179,7 +216,7 @@ public void initialize() {
tableView.getSortOrder().add(dateColumn);
walletChangeEventListener = wallet -> {
- displayedTransactions.update();
+ updateList();
};
keyEventEventHandler = event -> {
@@ -202,9 +239,10 @@ public void initialize() {
@Override
protected void activate() {
- sortedDisplayedTransactions.comparatorProperty().bind(tableView.comparatorProperty());
- tableView.setItems(sortedDisplayedTransactions);
- displayedTransactions.update();
+ filterBox.activate();
+ sortedList.comparatorProperty().bind(tableView.comparatorProperty());
+ tableView.setItems(sortedList);
+ updateList();
btcWalletService.addChangeEventListener(walletChangeEventListener);
@@ -212,7 +250,7 @@ protected void activate() {
if (scene != null)
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
- numItems.setText(Res.get("shared.numItemsLabel", sortedDisplayedTransactions.size()));
+ numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
exportButton.setOnAction(event -> {
final ObservableList> tableColumns = tableView.getColumns();
final int reportColumns = tableColumns.size() - 1; // CSV report excludes the last column (an icon)
@@ -235,14 +273,15 @@ protected void activate() {
};
GUIUtil.exportCSV("transactions.csv", headerConverter, contentConverter,
- new TransactionsListItem(), sortedDisplayedTransactions, (Stage) root.getScene().getWindow());
+ new TransactionsListItem(), sortedList, (Stage) root.getScene().getWindow());
});
}
@Override
protected void deactivate() {
- sortedDisplayedTransactions.comparatorProperty().unbind();
- displayedTransactions.forEach(TransactionsListItem::cleanup);
+ filterBox.deactivate();
+ sortedList.comparatorProperty().unbind();
+ observableList.forEach(TransactionsListItem::cleanup);
btcWalletService.removeChangeEventListener(walletChangeEventListener);
if (scene != null)
@@ -251,6 +290,48 @@ protected void deactivate() {
exportButton.setOnAction(null);
}
+ private void updateList() {
+ List transactionsListItems = btcWalletService.getTransactions(false)
+ .stream()
+ .map(transaction -> {
+ Set tradables = tradableRepository.getAll();
+
+ TransactionAwareTradable maybeTradable = tradables.stream()
+ .map(tradable -> {
+ if (tradable instanceof OpenOffer) {
+ return new TransactionAwareOpenOffer((OpenOffer) tradable);
+ } else if (tradable instanceof TradeModel) {
+ return new TransactionAwareTrade(
+ (TradeModel) tradable,
+ arbitrationManager,
+ refundManager,
+ btcWalletService,
+ pubKeyRing
+ );
+ } else {
+ return null;
+ }
+ })
+ .filter(tradable -> tradable != null && tradable.isRelatedToTransaction(transaction))
+ .findAny()
+ .orElse(null);
+
+ return new TransactionsListItem(
+ transaction,
+ btcWalletService,
+ bsqWalletService,
+ maybeTradable,
+ daoFacade,
+ formatter,
+ preferences.getIgnoreDustThreshold()
+ );
+ })
+ .collect(Collectors.toList());
+ // are sorted by getRecentTransactions
+ transactionsListItems.forEach(TransactionsListItem::cleanup);
+ observableList.setAll(transactionsListItems);
+ }
+
private void openTxInBlockExplorer(TransactionsListItem item) {
if (item.getTxId() != null)
GUIUtil.openWebPage(preferences.getBlockChainExplorer().txUrl + item.getTxId(), false);
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java
index 0aebe8e23ae..4c50c070153 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java
@@ -17,6 +17,7 @@
package bisq.desktop.main.funds.withdrawal;
+import bisq.desktop.util.filtering.FilterableListItem;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.core.btc.listeners.BalanceListener;
@@ -29,12 +30,14 @@
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
+import org.apache.commons.lang3.StringUtils;
+
import javafx.scene.control.Label;
import lombok.Getter;
import lombok.Setter;
-class WithdrawalListItem {
+class WithdrawalListItem implements FilterableListItem {
private final BalanceListener balanceListener;
private final Label balanceLabel;
private final AddressEntry addressEntry;
@@ -118,7 +121,23 @@ public Coin getBalance() {
return balance;
}
+ public String getBalanceAsString() {
+ return formatter.formatCoin(balance);
+ }
+
public String getAddressString() {
return addressString;
}
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getBalanceAsString(), filterString)) {
+ return true;
+ }
+ return StringUtils.containsIgnoreCase(getAddressString(), filterString);
+
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.fxml b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.fxml
index e3755d40145..1d78c5844df 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.fxml
@@ -23,12 +23,14 @@
+
+
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java
index 35dbd66154d..2b1a8011144 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java
@@ -25,6 +25,7 @@
import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.InputTextField;
import bisq.desktop.components.TitledGroupBg;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.TxDetails;
import bisq.desktop.main.overlays.windows.WalletPasswordWindow;
@@ -96,6 +97,7 @@
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
@@ -117,10 +119,11 @@
@FxmlView
public class WithdrawalView extends ActivatableView {
-
@FXML
GridPane gridPane;
@FXML
+ FilterBox filterBox;
+ @FXML
TableView tableView;
@FXML
TableColumn addressColumn, balanceColumn, selectColumn;
@@ -138,7 +141,8 @@ public class WithdrawalView extends ActivatableView {
private final BtcAddressValidator btcAddressValidator;
private final WalletPasswordWindow walletPasswordWindow;
private final ObservableList observableList = FXCollections.observableArrayList();
- private final SortedList sortedList = new SortedList<>(observableList);
+ private final FilteredList filteredList = new FilteredList<>(observableList);
+ private final SortedList sortedList = new SortedList<>(filteredList);
private final Set selectedItems = new HashSet<>();
private BalanceListener balanceListener;
private Set fromAddresses = new HashSet<>();
@@ -183,7 +187,7 @@ private WithdrawalView(BtcWalletService btcWalletService,
@Override
public void initialize() {
-
+ filterBox.initialize(filteredList, tableView);
final TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, rowIndex, 4, Res.get("funds.deposit.withdrawFromWallet"));
titledGroupBg.getStyleClass().add("last");
@@ -343,6 +347,7 @@ private void updateInputSelection() {
@Override
protected void activate() {
+ filterBox.activate();
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
tableView.setItems(sortedList);
updateList();
@@ -374,6 +379,7 @@ protected void activate() {
@Override
protected void deactivate() {
+ filterBox.deactivate();
sortedList.comparatorProperty().unbind();
observableList.forEach(WithdrawalListItem::cleanup);
btcWalletService.removeBalanceListener(balanceListener);
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsDataModel.java
index 3f01e7b9db2..32e24600772 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsDataModel.java
@@ -21,13 +21,17 @@
import bisq.core.btc.listeners.BsqBalanceListener;
import bisq.core.btc.wallet.BsqWalletService;
-import bisq.core.offer.Offer;
-import bisq.core.offer.OfferDirection;
+import bisq.core.trade.ClosedTradableManager;
import bisq.core.trade.bsq_swap.BsqSwapTradeManager;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.coin.BsqFormatter;
+import bisq.core.util.coin.CoinFormatter;
import com.google.inject.Inject;
+import javax.inject.Named;
+
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
@@ -36,17 +40,26 @@
class UnconfirmedBsqSwapsDataModel extends ActivatableDataModel {
- final BsqSwapTradeManager bsqSwapTradeManager;
+ private final BsqSwapTradeManager bsqSwapTradeManager;
private final BsqWalletService bsqWalletService;
private final ObservableList list = FXCollections.observableArrayList();
private final ListChangeListener tradesListChangeListener;
private final BsqBalanceListener bsqBalanceListener;
+ private final BsqFormatter bsqFormatter;
+ private final CoinFormatter btcFormatter;
+ private final ClosedTradableManager closedTradableManager;
@Inject
public UnconfirmedBsqSwapsDataModel(BsqSwapTradeManager bsqSwapTradeManager,
- BsqWalletService bsqWalletService) {
+ BsqWalletService bsqWalletService,
+ BsqFormatter bsqFormatter,
+ @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
+ ClosedTradableManager closedTradableManager) {
this.bsqSwapTradeManager = bsqSwapTradeManager;
this.bsqWalletService = bsqWalletService;
+ this.bsqFormatter = bsqFormatter;
+ this.btcFormatter = btcFormatter;
+ this.closedTradableManager = closedTradableManager;
tradesListChangeListener = change -> applyList();
bsqBalanceListener = (availableBalance, availableNonBsqBalance, unverifiedBalance,
@@ -71,15 +84,18 @@ public ObservableList getList() {
return list;
}
- public OfferDirection getDirection(Offer offer) {
- return bsqSwapTradeManager.wasMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
- }
-
private void applyList() {
list.clear();
list.addAll(bsqSwapTradeManager.getUnconfirmedBsqSwapTrades()
- .map(bsqSwapTrade -> new UnconfirmedBsqSwapsListItem(bsqWalletService, bsqSwapTrade))
+ .map(bsqSwapTrade -> new UnconfirmedBsqSwapsListItem(
+ bsqSwapTrade,
+ bsqWalletService,
+ btcFormatter,
+ bsqFormatter,
+ bsqSwapTradeManager,
+ closedTradableManager
+ ))
.collect(Collectors.toList()));
// we sort by date, the earliest first
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsListItem.java b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsListItem.java
index 5ccc33f71d2..a6c02257ebb 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsListItem.java
@@ -18,34 +18,63 @@
package bisq.desktop.main.portfolio.bsqswaps;
import bisq.desktop.components.indicator.TxConfidenceIndicator;
+import bisq.desktop.util.DisplayUtils;
import bisq.desktop.util.GUIUtil;
+import bisq.desktop.util.filtering.FilterableListItem;
+import bisq.desktop.util.filtering.FilteringUtils;
import bisq.core.btc.listeners.TxConfidenceListener;
import bisq.core.btc.wallet.BsqWalletService;
+import bisq.core.locale.CurrencyUtil;
+import bisq.core.offer.Offer;
+import bisq.core.offer.OfferDirection;
+import bisq.core.trade.ClosedTradableManager;
+import bisq.core.trade.bsq_swap.BsqSwapTradeManager;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.VolumeUtil;
+import bisq.core.util.coin.BsqFormatter;
+import bisq.core.util.coin.CoinFormatter;
+import org.bitcoinj.core.Coin;
import org.bitcoinj.core.TransactionConfidence;
+import org.apache.commons.lang3.StringUtils;
+
import javafx.scene.control.Tooltip;
import lombok.Getter;
import javax.annotation.Nullable;
-class UnconfirmedBsqSwapsListItem {
+class UnconfirmedBsqSwapsListItem implements FilterableListItem {
@Getter
private final BsqSwapTrade bsqSwapTrade;
private final BsqWalletService bsqWalletService;
+ private final CoinFormatter btcFormatter;
+ private final BsqFormatter bsqFormatter;
+ private final BsqSwapTradeManager bsqSwapTradeManager;
+ private final ClosedTradableManager closedTradableManager;
private final String txId;
@Getter
private int confirmations = 0;
@Getter
- private TxConfidenceIndicator txConfidenceIndicator;
- private TxConfidenceListener txConfidenceListener;
-
- UnconfirmedBsqSwapsListItem(BsqWalletService bsqWalletService, BsqSwapTrade bsqSwapTrade) {
+ private final TxConfidenceIndicator txConfidenceIndicator;
+ private final TxConfidenceListener txConfidenceListener;
+
+ UnconfirmedBsqSwapsListItem(
+ BsqSwapTrade bsqSwapTrade,
+ BsqWalletService bsqWalletService,
+ CoinFormatter btcFormatter,
+ BsqFormatter bsqFormatter,
+ BsqSwapTradeManager bsqSwapTradeManager,
+ ClosedTradableManager closedTradableManager) {
this.bsqSwapTrade = bsqSwapTrade;
this.bsqWalletService = bsqWalletService;
+ this.btcFormatter = btcFormatter;
+ this.bsqFormatter = bsqFormatter;
+ this.bsqSwapTradeManager = bsqSwapTradeManager;
+ this.closedTradableManager = closedTradableManager;
txId = bsqSwapTrade.getTxId();
txConfidenceIndicator = new TxConfidenceIndicator();
@@ -65,13 +94,6 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(bsqWalletService.getConfidenceForTxId(txId), tooltip);
}
- UnconfirmedBsqSwapsListItem() {
- bsqSwapTrade = null;
- bsqWalletService = null;
- txId = null;
-
- }
-
private void updateConfidence(@Nullable TransactionConfidence confidence, Tooltip tooltip) {
if (confidence != null) {
GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator);
@@ -83,4 +105,91 @@ public void cleanup() {
bsqWalletService.removeTxConfidenceListener(txConfidenceListener);
}
+ public String getTradeId() {
+ return bsqSwapTrade.getShortId();
+ }
+
+ public String getAmountAsString() {
+ return btcFormatter.formatCoin(bsqSwapTrade.getAmount());
+ }
+
+ public String getPriceAsString() {
+ return FormattingUtils.formatPrice(bsqSwapTrade.getPrice());
+ }
+
+ public String getVolumeAsString() {
+ return VolumeUtil.formatVolumeWithCode(bsqSwapTrade.getVolume());
+ }
+
+ public String getTxFeeAsString() {
+ return btcFormatter.formatCoinWithCode(Coin.valueOf(bsqSwapTrade.getBsqSwapProtocolModel().getTxFee()));
+ }
+
+ public String getTradeFeeAsString() {
+ if (bsqSwapTradeManager.wasMyOffer(bsqSwapTrade.getOffer())) {
+ return bsqFormatter.formatCoinWithCode(bsqSwapTrade.getMakerFeeAsLong());
+ } else {
+ return bsqFormatter.formatCoinWithCode(bsqSwapTrade.getTakerFeeAsLong());
+ }
+ }
+
+ public String getDirectionLabel() {
+ Offer offer = bsqSwapTrade.getOffer();
+ OfferDirection direction = bsqSwapTradeManager.wasMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
+ return DisplayUtils.getDirectionWithCode(direction, bsqSwapTrade.getOffer().getCurrencyCode());
+ }
+
+ public String getDateAsString() {
+ return DisplayUtils.formatDateTime(bsqSwapTrade.getDate());
+ }
+
+ public String getMarketLabel() {
+ return CurrencyUtil.getCurrencyPair(bsqSwapTrade.getOffer().getCurrencyCode());
+ }
+
+ public int getConfidence() {
+ return getConfirmations();
+ }
+
+ public int getNumPastTrades() {
+ return closedTradableManager.getNumPastTrades(bsqSwapTrade);
+ }
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDateAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getMarketLabel(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPriceAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getVolumeAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAmountAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getTradeFeeAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getTxFeeAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(String.valueOf(getConfidence()), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDirectionLabel(), filterString)) {
+ return true;
+ }
+ if (FilteringUtils.match(getBsqSwapTrade(), filterString)) {
+ return true;
+ }
+ return FilteringUtils.match(getBsqSwapTrade().getOffer(), filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.fxml b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.fxml
index 0231c587eec..56c2c030ea6 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.fxml
@@ -18,28 +18,21 @@
-->
-
-
-
+
-
-
-
-
-
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.java
index 9dfd8c7941d..4c3e056f4b2 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsView.java
@@ -22,14 +22,14 @@
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.HyperlinkWithIcon;
-import bisq.desktop.components.InputTextField;
import bisq.desktop.components.PeerInfoIconTrading;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.windows.BsqTradeDetailsWindow;
import bisq.desktop.util.GUIUtil;
+import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.locale.Res;
-import bisq.core.offer.Offer;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
import bisq.core.user.Preferences;
@@ -53,7 +53,6 @@
import javafx.scene.control.TableView;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
@@ -115,13 +114,7 @@ public String toString() {
confidenceColumn,
avatarColumn;
@FXML
- HBox searchBox;
- @FXML
- AutoTooltipLabel filterLabel;
- @FXML
- InputTextField filterTextField;
- @FXML
- Pane searchBoxSpacer;
+ FilterBox filterBox;
@FXML
AutoTooltipButton exportButton;
@FXML
@@ -132,9 +125,9 @@ public String toString() {
private final BsqTradeDetailsWindow window;
private final Preferences preferences;
private final PrivateNotificationManager privateNotificationManager;
+ private final AccountAgeWitnessService accountAgeWitnessService;
private SortedList sortedList;
private FilteredList filteredList;
- private ChangeListener filterTextFieldListener;
private ChangeListener widthListener;
@Inject
@@ -142,11 +135,13 @@ public UnconfirmedBsqSwapsView(UnconfirmedBsqSwapsViewModel model,
BsqTradeDetailsWindow bsqTradeDetailsWindow,
Preferences preferences,
PrivateNotificationManager privateNotificationManager,
+ AccountAgeWitnessService accountAgeWitnessService,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(model);
this.window = bsqTradeDetailsWindow;
this.preferences = preferences;
this.privateNotificationManager = privateNotificationManager;
+ this.accountAgeWitnessService = accountAgeWitnessService;
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
}
@@ -183,20 +178,17 @@ public void initialize() {
tradeIdColumn.setComparator(Comparator.comparing(o -> o.getBsqSwapTrade().getId()));
dateColumn.setComparator(Comparator.comparing(o -> o.getBsqSwapTrade().getDate()));
directionColumn.setComparator(Comparator.comparing(o -> o.getBsqSwapTrade().getOffer().getDirection()));
- marketColumn.setComparator(Comparator.comparing(model::getMarketLabel));
- priceColumn.setComparator(Comparator.comparing(model::getPrice, Comparator.nullsFirst(Comparator.naturalOrder())));
+ marketColumn.setComparator(Comparator.comparing(UnconfirmedBsqSwapsListItem::getMarketLabel));
+ priceColumn.setComparator(Comparator.comparing(UnconfirmedBsqSwapsListItem::getPriceAsString, Comparator.nullsFirst(Comparator.naturalOrder())));
volumeColumn.setComparator(nullsFirstComparingAsTrade(BsqSwapTrade::getVolume));
- amountColumn.setComparator(Comparator.comparing(model::getAmount, Comparator.nullsFirst(Comparator.naturalOrder())));
- avatarColumn.setComparator(Comparator.comparing(
- o -> model.getNumPastTrades(o.getBsqSwapTrade()),
- Comparator.nullsFirst(Comparator.naturalOrder())
- ));
+ amountColumn.setComparator(Comparator.comparing(UnconfirmedBsqSwapsListItem::getAmountAsString, Comparator.nullsFirst(Comparator.naturalOrder())));
+ avatarColumn.setComparator(Comparator.comparing(UnconfirmedBsqSwapsListItem::getNumPastTrades, Comparator.nullsFirst(Comparator.naturalOrder())));
txFeeColumn.setComparator(nullsFirstComparing(BsqSwapTrade::getTxFeePerVbyte));
- txFeeColumn.setComparator(Comparator.comparing(model::getTxFee, Comparator.nullsFirst(Comparator.naturalOrder())));
+ txFeeColumn.setComparator(Comparator.comparing(UnconfirmedBsqSwapsListItem::getTxFeeAsString, Comparator.nullsFirst(Comparator.naturalOrder())));
//
tradeFeeColumn.setComparator(Comparator.comparing(item -> {
- String tradeFee = model.getTradeFee(item);
+ String tradeFee = item.getTradeFeeAsString();
// We want to separate BSQ and BTC fees so we use a prefix
if (item.getBsqSwapTrade().getOffer().isCurrencyForMakerFeeBtc()) {
return "BTC" + tradeFee;
@@ -204,17 +196,11 @@ public void initialize() {
return "BSQ" + tradeFee;
}
}, Comparator.nullsFirst(Comparator.naturalOrder())));
- confidenceColumn.setComparator(Comparator.comparing(model::getConfidence));
+ confidenceColumn.setComparator(Comparator.comparing(UnconfirmedBsqSwapsListItem::getConfidence));
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
tableView.getSortOrder().add(dateColumn);
- filterLabel.setText(Res.get("shared.filter"));
- HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
- filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
- searchBox.setSpacing(5);
- HBox.setHgrow(searchBoxSpacer, Priority.ALWAYS);
-
numItems.setId("num-offers");
numItems.setPadding(new Insets(-5, 0, 0, 10));
HBox.setHgrow(footerSpacer, Priority.ALWAYS);
@@ -224,13 +210,16 @@ public void initialize() {
@Override
protected void activate() {
- filteredList = new FilteredList<>(model.getList());
+ filteredList = new FilteredList<>(model.dataModel.getList());
sortedList = new SortedList<>(filteredList);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
tableView.setItems(sortedList);
+ filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
+ filterBox.activate();
+
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
exportButton.setOnAction(event -> {
CSVEntryConverter headerConverter = item -> {
@@ -242,25 +231,23 @@ protected void activate() {
};
CSVEntryConverter contentConverter = item -> {
String[] columns = new String[ColumnNames.values().length];
- columns[ColumnNames.TRADE_ID.ordinal()] = model.getTradeId(item);
- columns[ColumnNames.DATE.ordinal()] = model.getDate(item);
- columns[ColumnNames.MARKET.ordinal()] = model.getMarketLabel(item);
- columns[ColumnNames.PRICE.ordinal()] = model.getPrice(item);
- columns[ColumnNames.AMOUNT.ordinal()] = model.getAmount(item);
- columns[ColumnNames.VOLUME.ordinal()] = model.getVolume(item);
- columns[ColumnNames.TX_FEE.ordinal()] = model.getTxFee(item);
- columns[ColumnNames.TRADE_FEE.ordinal()] = model.getTradeFee(item);
- columns[ColumnNames.OFFER_TYPE.ordinal()] = model.getDirectionLabel(item);
- columns[ColumnNames.CONF.ordinal()] = String.valueOf(model.getConfidence(item));
+ columns[ColumnNames.TRADE_ID.ordinal()] = item.getTradeId();
+ columns[ColumnNames.DATE.ordinal()] = item.getDateAsString();
+ columns[ColumnNames.MARKET.ordinal()] = item.getMarketLabel();
+ columns[ColumnNames.PRICE.ordinal()] = item.getPriceAsString();
+ columns[ColumnNames.AMOUNT.ordinal()] = item.getAmountAsString();
+ columns[ColumnNames.VOLUME.ordinal()] = item.getVolumeAsString();
+ columns[ColumnNames.TX_FEE.ordinal()] = item.getTxFeeAsString();
+ columns[ColumnNames.TRADE_FEE.ordinal()] = item.getTradeFeeAsString();
+ columns[ColumnNames.OFFER_TYPE.ordinal()] = item.getDirectionLabel();
+ columns[ColumnNames.CONF.ordinal()] = String.valueOf(item.getConfidence());
return columns;
};
GUIUtil.exportCSV("bsqSwapHistory.csv", headerConverter, contentConverter,
- new UnconfirmedBsqSwapsListItem(), sortedList, (Stage) root.getScene().getWindow());
+ null, sortedList, (Stage) root.getScene().getWindow());
});
- filterTextField.textProperty().addListener(filterTextFieldListener);
- applyFilteredListPredicate(filterTextField.getText());
root.widthProperty().addListener(widthListener);
onWidthChange(root.getWidth());
}
@@ -270,7 +257,7 @@ protected void deactivate() {
sortedList.comparatorProperty().unbind();
exportButton.setOnAction(null);
- filterTextField.textProperty().removeListener(filterTextFieldListener);
+ filterBox.deactivate();
root.widthProperty().removeListener(widthListener);
}
@@ -295,57 +282,6 @@ private void onWidthChange(double width) {
tradeFeeColumn.setVisible(width > 1300);
}
- private void applyFilteredListPredicate(String filterString) {
- filteredList.setPredicate(item -> {
- if (filterString.isEmpty())
- return true;
-
- BsqSwapTrade bsqSwapTrade = item.getBsqSwapTrade();
- Offer offer = bsqSwapTrade.getOffer();
- if (offer.getId().contains(filterString)) {
- return true;
- }
- if (model.getDate(item).contains(filterString)) {
- return true;
- }
- if (model.getMarketLabel(item).contains(filterString)) {
- return true;
- }
- if (model.getPrice(item).contains(filterString)) {
- return true;
- }
- if (model.getVolume(item).contains(filterString)) {
- return true;
- }
- if (model.getAmount(item).contains(filterString)) {
- return true;
- }
- if (model.getTradeFee(item).contains(filterString)) {
- return true;
- }
- if (model.getTxFee(item).contains(filterString)) {
- return true;
- }
- if (String.valueOf(model.getConfidence(item)).contains(filterString)) {
- return true;
- }
- if (model.getDirectionLabel(item).contains(filterString)) {
- return true;
- }
- if (offer.getPaymentMethod().getDisplayString().contains(filterString)) {
- return true;
- }
- if (bsqSwapTrade.getTxId() != null && bsqSwapTrade.getTxId().contains(filterString)) {
- return true;
- }
- if (bsqSwapTrade.getTradingPeerNodeAddress().getFullAddress().contains(filterString)) {
- return true;
- }
-
- return false;
- });
- }
-
private void setTradeIdColumnCellFactory() {
tradeIdColumn.getStyleClass().add("first-column");
tradeIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
@@ -362,7 +298,7 @@ public TableCell call(
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
- field = new HyperlinkWithIcon(model.getTradeId(item));
+ field = new HyperlinkWithIcon(item.getTradeId());
field.setOnAction(event -> {
window.show(item.getBsqSwapTrade());
});
@@ -390,8 +326,8 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- if (item != null)
- setGraphic(new AutoTooltipLabel(model.getDate(item)));
+ if (item != null && !empty)
+ setGraphic(new AutoTooltipLabel(item.getDateAsString()));
else
setGraphic(null);
}
@@ -411,7 +347,11 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getMarketLabel(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getMarketLabel()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -457,7 +397,7 @@ public void updateItem(final UnconfirmedBsqSwapsListItem newItem, boolean empty)
if (newItem != null && !empty/* && newItem.getAtomicTrade() instanceof Trade*/) {
var bsqSwapTrade = newItem.getBsqSwapTrade();
- int numPastTrades = model.getNumPastTrades(bsqSwapTrade);
+ int numPastTrades = newItem.getNumPastTrades();
final NodeAddress tradingPeerNodeAddress = bsqSwapTrade.getTradingPeerNodeAddress();
String role = Res.get("peerInfoIcon.tooltip.tradePeer");
Node peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
@@ -466,7 +406,7 @@ public void updateItem(final UnconfirmedBsqSwapsListItem newItem, boolean empty)
privateNotificationManager,
bsqSwapTrade.getOffer(),
preferences,
- model.accountAgeWitnessService,
+ accountAgeWitnessService,
useDevPrivilegeKeys);
setPadding(new Insets(1, 15, 0, 0));
setGraphic(peerInfoIcon);
@@ -491,7 +431,11 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getAmount(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getAmountAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -509,7 +453,11 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getPrice(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getPriceAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -527,8 +475,8 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- if (item != null)
- setGraphic(new AutoTooltipLabel(model.getVolume(item)));
+ if (item != null && !empty)
+ setGraphic(new AutoTooltipLabel(item.getVolumeAsString()));
else
setGraphic(null);
}
@@ -548,7 +496,10 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getDirectionLabel(item)));
+ if (item != null && !empty)
+ setGraphic(new AutoTooltipLabel(item.getDirectionLabel()));
+ else
+ setGraphic(null);
}
};
}
@@ -566,7 +517,10 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getTxFee(item)));
+ if (item != null && !empty)
+ setGraphic(new AutoTooltipLabel(item.getTxFeeAsString()));
+ else
+ setGraphic(null);
}
};
}
@@ -584,7 +538,10 @@ public TableCell call(
@Override
public void updateItem(final UnconfirmedBsqSwapsListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getTradeFee(item)));
+ if (item != null && !empty)
+ setGraphic(new AutoTooltipLabel(item.getTradeFeeAsString()));
+ else
+ setGraphic(null);
}
};
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsViewModel.java
index 78ff626177d..0cdff0249d7 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/bsqswaps/UnconfirmedBsqSwapsViewModel.java
@@ -19,121 +19,12 @@
import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.model.ViewModel;
-import bisq.desktop.util.DisplayUtils;
-
-import bisq.core.account.witness.AccountAgeWitnessService;
-import bisq.core.locale.CurrencyUtil;
-import bisq.core.trade.ClosedTradableManager;
-import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
-import bisq.core.util.FormattingUtils;
-import bisq.core.util.VolumeUtil;
-import bisq.core.util.coin.BsqFormatter;
-import bisq.core.util.coin.CoinFormatter;
-
-import org.bitcoinj.core.Coin;
import com.google.inject.Inject;
-import javax.inject.Named;
-
-import javafx.collections.ObservableList;
-
class UnconfirmedBsqSwapsViewModel extends ActivatableWithDataModel implements ViewModel {
- private final BsqFormatter bsqFormatter;
- private final CoinFormatter btcFormatter;
- final AccountAgeWitnessService accountAgeWitnessService;
- private final ClosedTradableManager closedTradableManager;
-
@Inject
- public UnconfirmedBsqSwapsViewModel(UnconfirmedBsqSwapsDataModel dataModel,
- AccountAgeWitnessService accountAgeWitnessService,
- ClosedTradableManager closedTradableManager,
- BsqFormatter bsqFormatter,
- @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter) {
+ public UnconfirmedBsqSwapsViewModel(UnconfirmedBsqSwapsDataModel dataModel) {
super(dataModel);
- this.accountAgeWitnessService = accountAgeWitnessService;
- this.closedTradableManager = closedTradableManager;
- this.bsqFormatter = bsqFormatter;
- this.btcFormatter = btcFormatter;
- }
-
- public ObservableList getList() {
- return dataModel.getList();
- }
-
- String getTradeId(UnconfirmedBsqSwapsListItem item) {
- return item.getBsqSwapTrade().getShortId();
- }
-
- String getAmount(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- return btcFormatter.formatCoin(item.getBsqSwapTrade().getAmount());
- }
-
- String getPrice(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- return FormattingUtils.formatPrice(item.getBsqSwapTrade().getPrice());
- }
-
- String getVolume(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- return VolumeUtil.formatVolumeWithCode(item.getBsqSwapTrade().getVolume());
- }
-
- String getTxFee(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- return btcFormatter.formatCoinWithCode(Coin.valueOf(item.getBsqSwapTrade().getBsqSwapProtocolModel().getTxFee()));
- }
-
- String getTradeFee(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- if (wasMyOffer(item.getBsqSwapTrade())) {
- return bsqFormatter.formatCoinWithCode(item.getBsqSwapTrade().getMakerFeeAsLong());
- } else {
- return bsqFormatter.formatCoinWithCode(item.getBsqSwapTrade().getTakerFeeAsLong());
- }
- }
-
- String getDirectionLabel(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- return DisplayUtils.getDirectionWithCode(dataModel.getDirection(item.getBsqSwapTrade().getOffer()),
- item.getBsqSwapTrade().getOffer().getCurrencyCode());
- }
-
- String getDate(UnconfirmedBsqSwapsListItem item) {
- return DisplayUtils.formatDateTime(item.getBsqSwapTrade().getDate());
- }
-
- String getMarketLabel(UnconfirmedBsqSwapsListItem item) {
- if (item == null)
- return "";
-
- return CurrencyUtil.getCurrencyPair(item.getBsqSwapTrade().getOffer().getCurrencyCode());
- }
-
- int getConfidence(UnconfirmedBsqSwapsListItem item) {
- if ((item == null))
- return 0;
- return item.getConfirmations();
- }
-
- int getNumPastTrades(BsqSwapTrade bsqSwapTrade) {
- return closedTradableManager.getNumPastTrades(bsqSwapTrade);
- }
-
- boolean wasMyOffer(BsqSwapTrade bsqSwapTrade) {
- return dataModel.bsqSwapTradeManager.wasMyOffer(bsqSwapTrade.getOffer());
}
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesDataModel.java
index 406a816edde..eb06164bb0d 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesDataModel.java
@@ -24,10 +24,9 @@
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.monetary.Price;
import bisq.core.monetary.Volume;
-import bisq.core.offer.Offer;
-import bisq.core.offer.OfferDirection;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
+import bisq.core.trade.ClosedTradableFormatter;
import bisq.core.trade.ClosedTradableManager;
import bisq.core.trade.ClosedTradableUtil;
import bisq.core.trade.bsq_swap.BsqSwapTradeManager;
@@ -44,30 +43,33 @@
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
class ClosedTradesDataModel extends ActivatableDataModel {
final ClosedTradableManager closedTradableManager;
+ final ClosedTradableFormatter closedTradableFormatter;
private final BsqWalletService bsqWalletService;
private final BsqSwapTradeManager bsqSwapTradeManager;
private final Preferences preferences;
private final PriceFeedService priceFeedService;
final AccountAgeWitnessService accountAgeWitnessService;
- private final ObservableList list = FXCollections.observableArrayList();
+ private final ObservableList list = FXCollections.observableArrayList();
private final ListChangeListener tradesListChangeListener;
private final BsqBalanceListener bsqBalanceListener;
@Inject
public ClosedTradesDataModel(ClosedTradableManager closedTradableManager,
+ ClosedTradableFormatter closedTradableFormatter,
BsqSwapTradeManager bsqSwapTradeManager,
BsqWalletService bsqWalletService,
Preferences preferences,
PriceFeedService priceFeedService,
AccountAgeWitnessService accountAgeWitnessService) {
this.closedTradableManager = closedTradableManager;
+ this.closedTradableFormatter = closedTradableFormatter;
this.bsqSwapTradeManager = bsqSwapTradeManager;
this.bsqWalletService = bsqWalletService;
this.preferences = preferences;
@@ -95,16 +97,16 @@ protected void deactivate() {
bsqWalletService.removeBsqBalanceListener(bsqBalanceListener);
}
- ObservableList getList() {
+ ObservableList getList() {
return list;
}
- OfferDirection getDirection(Offer offer) {
- return closedTradableManager.wasMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
+ List getListAsTradables() {
+ return list.stream().map(ClosedTradesListItem::getTradable).collect(Collectors.toList());
}
Coin getTotalAmount() {
- return ClosedTradableUtil.getTotalAmount(list);
+ return ClosedTradableUtil.getTotalAmount(getListAsTradables());
}
Optional getVolumeInUserFiatCurrency(Coin amount) {
@@ -126,15 +128,11 @@ Volume getBsqVolumeInUsdWithAveragePrice(Coin amount) {
}
Coin getTotalTxFee() {
- return ClosedTradableUtil.getTotalTxFee(list);
+ return ClosedTradableUtil.getTotalTxFee(getListAsTradables());
}
Coin getTotalTradeFee(boolean expectBtcFee) {
- return closedTradableManager.getTotalTradeFee(list, expectBtcFee);
- }
-
- int getNumPastTrades(Tradable tradable) {
- return closedTradableManager.getNumPastTrades(tradable);
+ return closedTradableManager.getTotalTradeFee(getListAsTradables(), expectBtcFee);
}
boolean isCurrencyForTradeFeeBtc(Tradable item) {
@@ -143,13 +141,17 @@ boolean isCurrencyForTradeFeeBtc(Tradable item) {
private void applyList() {
list.clear();
- list.addAll(getTradableStream().collect(Collectors.toList()));
+ list.addAll(
+ bsqSwapTradeManager.getConfirmedBsqSwapTrades()
+ .map(tradable -> new ClosedTradesListItem(tradable, closedTradableFormatter, closedTradableManager))
+ .collect(Collectors.toList())
+ );
+ list.addAll(
+ closedTradableManager.getObservableList().stream()
+ .map(tradable -> new ClosedTradesListItem(tradable, closedTradableFormatter, closedTradableManager))
+ .collect(Collectors.toList())
+ );
// We sort by date, the earliest first
- list.sort((o1, o2) -> o2.getDate().compareTo(o1.getDate()));
- }
-
- private Stream getTradableStream() {
- return Stream.concat(bsqSwapTradeManager.getConfirmedBsqSwapTrades(),
- closedTradableManager.getObservableList().stream());
+ list.sort((o1, o2) -> o2.getTradable().getDate().compareTo(o1.getTradable().getDate()));
}
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesListItem.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesListItem.java
new file mode 100644
index 00000000000..9a683c80e68
--- /dev/null
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesListItem.java
@@ -0,0 +1,167 @@
+/*
+ * 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 .
+ */
+
+package bisq.desktop.main.portfolio.closedtrades;
+
+import bisq.desktop.util.DisplayUtils;
+import bisq.desktop.util.filtering.FilterableListItem;
+import bisq.desktop.util.filtering.FilteringUtils;
+
+import bisq.core.locale.CurrencyUtil;
+import bisq.core.offer.Offer;
+import bisq.core.offer.OfferDirection;
+import bisq.core.trade.ClosedTradableFormatter;
+import bisq.core.trade.ClosedTradableManager;
+import bisq.core.trade.model.Tradable;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
+
+import org.apache.commons.lang3.StringUtils;
+
+import lombok.Getter;
+
+public class ClosedTradesListItem implements FilterableListItem {
+ @Getter
+ private final Tradable tradable;
+ private final ClosedTradableFormatter closedTradableFormatter;
+ private final ClosedTradableManager closedTradableManager;
+
+ public ClosedTradesListItem(
+ Tradable tradable,
+ ClosedTradableFormatter closedTradableFormatter,
+ ClosedTradableManager closedTradableManager) {
+
+ this.tradable = tradable;
+ this.closedTradableFormatter = closedTradableFormatter;
+ this.closedTradableManager = closedTradableManager;
+ }
+
+ public String getTradeId() {
+ return tradable.getShortId();
+ }
+
+ public String getAmountAsString() {
+ return closedTradableFormatter.getAmountAsString(tradable);
+ }
+
+ public String getPriceAsString() {
+ return closedTradableFormatter.getPriceAsString(tradable);
+ }
+
+ public String getPriceDeviationAsString() {
+ return closedTradableFormatter.getPriceDeviationAsString(tradable);
+ }
+
+ public String getVolumeAsString(boolean appendCode) {
+ return closedTradableFormatter.getVolumeAsString(tradable, appendCode);
+ }
+
+ public String getVolumeCurrencyAsString() {
+ return closedTradableFormatter.getVolumeCurrencyAsString(tradable);
+ }
+
+ public String getTxFeeAsString() {
+ return closedTradableFormatter.getTxFeeAsString(tradable);
+ }
+
+ public String getTradeFeeAsString(boolean appendCode) {
+ return closedTradableFormatter.getTradeFeeAsString(tradable, appendCode);
+ }
+
+ public String getBuyerSecurityDepositAsString() {
+ return closedTradableFormatter.getBuyerSecurityDepositAsString(tradable);
+ }
+
+ public String getSellerSecurityDepositAsString() {
+ return closedTradableFormatter.getSellerSecurityDepositAsString(tradable);
+ }
+
+ public String getDirectionLabel() {
+ Offer offer = tradable.getOffer();
+ OfferDirection direction = closedTradableManager.wasMyOffer(offer)
+ ? offer.getDirection()
+ : offer.getMirroredDirection();
+ String currencyCode = tradable.getOffer().getCurrencyCode();
+ return DisplayUtils.getDirectionWithCode(direction, currencyCode);
+ }
+
+ public String getDateAsString() {
+ return DisplayUtils.formatDateTime(tradable.getDate());
+ }
+
+ public String getMarketLabel() {
+ return CurrencyUtil.getCurrencyPair(tradable.getOffer().getCurrencyCode());
+ }
+
+ public String getState() {
+ return closedTradableFormatter.getStateAsString(tradable);
+ }
+
+ public int getNumPastTrades() {
+ return closedTradableManager.getNumPastTrades(tradable);
+ }
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDateAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getMarketLabel(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPriceAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPriceDeviationAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getVolumeAsString(true), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAmountAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getTradeFeeAsString(true), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getTxFeeAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getBuyerSecurityDepositAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getSellerSecurityDepositAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getState(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDirectionLabel(), filterString)) {
+ return true;
+ }
+ if (FilteringUtils.match(getTradable().getOffer(), filterString)) {
+ return true;
+ }
+ if (getTradable() instanceof BsqSwapTrade && FilteringUtils.match((BsqSwapTrade) getTradable(), filterString)) {
+ return true;
+ }
+ return getTradable() instanceof Trade && FilteringUtils.match((Trade) getTradable(), filterString);
+ }
+}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml
index 0bdd24821a8..9e86f8a2413 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml
@@ -18,28 +18,21 @@
-->
-
-
-
+
-
-
-
-
-
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java
index 0d5b2445e6f..5078d06c939 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java
@@ -24,8 +24,8 @@
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.AutoTooltipTableColumn;
import bisq.desktop.components.HyperlinkWithIcon;
-import bisq.desktop.components.InputTextField;
import bisq.desktop.components.PeerInfoIconTrading;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.BsqTradeDetailsWindow;
import bisq.desktop.main.overlays.windows.ClosedTradesSummaryWindow;
@@ -41,7 +41,6 @@
import bisq.core.offer.OpenOffer;
import bisq.core.trade.model.Tradable;
import bisq.core.trade.model.TradeModel;
-import bisq.core.trade.model.bisq_v1.Contract;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
import bisq.core.user.Preferences;
@@ -51,8 +50,6 @@
import bisq.common.config.Config;
import bisq.common.crypto.KeyRing;
-import com.google.protobuf.Message;
-
import com.googlecode.jcsv.writer.CSVEntryConverter;
import javax.inject.Inject;
@@ -75,7 +72,6 @@
import javafx.scene.control.TableView;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
@@ -94,7 +90,6 @@
import javafx.util.Callback;
import java.util.Comparator;
-import java.util.Date;
import java.util.function.Function;
import static bisq.desktop.util.FormBuilder.getRegularIconButton;
@@ -133,20 +128,14 @@ public String toString() {
}
@FXML
- TableView tableView;
+ TableView tableView;
@FXML
- TableColumn priceColumn, deviationColumn, amountColumn, volumeColumn,
+ TableColumn priceColumn, deviationColumn, amountColumn, volumeColumn,
txFeeColumn, tradeFeeColumn, buyerSecurityDepositColumn, sellerSecurityDepositColumn,
marketColumn, directionColumn, dateColumn, tradeIdColumn, stateColumn,
duplicateColumn, avatarColumn;
@FXML
- HBox searchBox;
- @FXML
- AutoTooltipLabel filterLabel;
- @FXML
- InputTextField filterTextField;
- @FXML
- Pane searchBoxSpacer;
+ FilterBox filterBox;
@FXML
AutoTooltipButton exportButton, summaryButton;
@FXML
@@ -161,9 +150,8 @@ public String toString() {
private final Preferences preferences;
private final TradeDetailsWindow tradeDetailsWindow;
private final PrivateNotificationManager privateNotificationManager;
- private SortedList sortedList;
- private FilteredList filteredList;
- private ChangeListener filterTextFieldListener;
+ private SortedList sortedList;
+ private FilteredList filteredList;
private ChangeListener widthListener;
@Inject
@@ -226,52 +214,49 @@ public void initialize() {
setDuplicateColumnCellFactory();
setAvatarColumnCellFactory();
- tradeIdColumn.setComparator(Comparator.comparing(Tradable::getId));
- dateColumn.setComparator(Comparator.comparing(Tradable::getDate));
- directionColumn.setComparator(Comparator.comparing(o -> o.getOffer().getDirection()));
- marketColumn.setComparator(Comparator.comparing(model::getMarketLabel));
- priceColumn.setComparator(Comparator.comparing(model::getPrice, Comparator.nullsFirst(Comparator.naturalOrder())));
+ tradeIdColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getTradeId));
+ dateColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getDateAsString));
+ directionColumn.setComparator(Comparator.comparing(o -> o.getTradable().getOffer().getDirection()));
+ marketColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getMarketLabel));
+ priceColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getPriceAsString, Comparator.nullsFirst(Comparator.naturalOrder())));
deviationColumn.setComparator(Comparator.comparing(o ->
- o.getOffer().isUseMarketBasedPrice() ? o.getOffer().getMarketPriceMargin() : 1,
+ o.getTradable().getOffer().isUseMarketBasedPrice() ? o.getTradable().getOffer().getMarketPriceMargin() : 1,
Comparator.nullsFirst(Comparator.naturalOrder())));
volumeColumn.setComparator(nullsFirstComparingAsTrade(TradeModel::getVolume));
- amountColumn.setComparator(Comparator.comparing(model::getAmount, Comparator.nullsFirst(Comparator.naturalOrder())));
- avatarColumn.setComparator(Comparator.comparing(
- model.dataModel::getNumPastTrades,
- Comparator.nullsFirst(Comparator.naturalOrder())
- ));
+ amountColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getAmountAsString, Comparator.nullsFirst(Comparator.naturalOrder())));
+ avatarColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getNumPastTrades, Comparator.nullsFirst(Comparator.naturalOrder())));
txFeeColumn.setComparator(nullsFirstComparing(o ->
- o instanceof TradeModel ? ((TradeModel) o).getTxFee() : o.getOffer().getTxFee()
+ o.getTradable() instanceof TradeModel ? ((TradeModel) o.getTradable()).getTxFee() : o.getTradable().getOffer().getTxFee()
));
- txFeeColumn.setComparator(Comparator.comparing(model::getTxFee, Comparator.nullsFirst(Comparator.naturalOrder())));
+ txFeeColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getTxFeeAsString, Comparator.nullsFirst(Comparator.naturalOrder())));
//
tradeFeeColumn.setComparator(Comparator.comparing(item -> {
- String tradeFee = model.getTradeFee(item, true);
+ String tradeFee = item.getTradeFeeAsString(true);
// We want to separate BSQ and BTC fees so we use a prefix
- if (item.getOffer().isCurrencyForMakerFeeBtc()) {
+ if (item.getTradable().getOffer().isCurrencyForMakerFeeBtc()) {
return "BTC" + tradeFee;
} else {
return "BSQ" + tradeFee;
}
}, Comparator.nullsFirst(Comparator.naturalOrder())));
buyerSecurityDepositColumn.setComparator(nullsFirstComparing(o ->
- o.getOffer() != null ? o.getOffer().getBuyerSecurityDeposit() : null
+ o.getTradable().getOffer() != null ? o.getTradable().getOffer().getBuyerSecurityDeposit() : null
));
sellerSecurityDepositColumn.setComparator(nullsFirstComparing(o ->
- o.getOffer() != null ? o.getOffer().getSellerSecurityDeposit() : null
+ o.getTradable().getOffer() != null ? o.getTradable().getOffer().getSellerSecurityDeposit() : null
));
- stateColumn.setComparator(Comparator.comparing(model::getState));
+ stateColumn.setComparator(Comparator.comparing(ClosedTradesListItem::getState));
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
tableView.getSortOrder().add(dateColumn);
tableView.setRowFactory(
tableView -> {
- TableRow row = new TableRow<>();
+ TableRow row = new TableRow<>();
ContextMenu rowMenu = new ContextMenu();
MenuItem duplicateItem = new MenuItem(Res.get("portfolio.context.offerLikeThis"));
- duplicateItem.setOnAction((ActionEvent event) -> onDuplicateOffer(row.getItem().getOffer()));
+ duplicateItem.setOnAction((ActionEvent event) -> onDuplicateOffer(row.getItem().getTradable().getOffer()));
rowMenu.getItems().add(duplicateItem);
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
@@ -280,12 +265,6 @@ public void initialize() {
return row;
});
- filterLabel.setText(Res.get("shared.filter"));
- HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
- filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
- searchBox.setSpacing(5);
- HBox.setHgrow(searchBoxSpacer, Priority.ALWAYS);
-
numItems.setId("num-offers");
numItems.setPadding(new Insets(-5, 0, 0, 10));
HBox.setHgrow(footerSpacer, Priority.ALWAYS);
@@ -303,48 +282,49 @@ protected void activate() {
tableView.setItems(sortedList);
+ filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
+ filterBox.activate();
+
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
exportButton.setOnAction(event -> {
- CSVEntryConverter headerConverter = item -> {
+ CSVEntryConverter headerConverter = item -> {
String[] columns = new String[ColumnNames.values().length];
for (ColumnNames m : ColumnNames.values()) {
columns[m.ordinal()] = m.toString();
}
return columns;
};
- CSVEntryConverter contentConverter = item -> {
+ CSVEntryConverter contentConverter = item -> {
String[] columns = new String[ColumnNames.values().length];
- columns[ColumnNames.TRADE_ID.ordinal()] = model.getTradeId(item);
- columns[ColumnNames.DATE.ordinal()] = model.getDate(item);
- columns[ColumnNames.MARKET.ordinal()] = model.getMarketLabel(item);
- columns[ColumnNames.PRICE.ordinal()] = model.getPrice(item);
- columns[ColumnNames.DEVIATION.ordinal()] = model.getPriceDeviation(item);
- columns[ColumnNames.AMOUNT.ordinal()] = model.getAmount(item);
- columns[ColumnNames.VOLUME.ordinal()] = model.getVolume(item, false);
- columns[ColumnNames.VOLUME_CURRENCY.ordinal()] = model.getVolumeCurrency(item);
- columns[ColumnNames.TX_FEE.ordinal()] = model.getTxFee(item);
- if (model.dataModel.isCurrencyForTradeFeeBtc(item)) {
- columns[ColumnNames.TRADE_FEE_BTC.ordinal()] = model.getTradeFee(item, false);
+ columns[ColumnNames.TRADE_ID.ordinal()] = item.getTradeId();
+ columns[ColumnNames.DATE.ordinal()] = item.getDateAsString();
+ columns[ColumnNames.MARKET.ordinal()] = item.getMarketLabel();
+ columns[ColumnNames.PRICE.ordinal()] = item.getPriceAsString();
+ columns[ColumnNames.DEVIATION.ordinal()] = item.getPriceDeviationAsString();
+ columns[ColumnNames.AMOUNT.ordinal()] = item.getAmountAsString();
+ columns[ColumnNames.VOLUME.ordinal()] = item.getVolumeAsString(false);
+ columns[ColumnNames.VOLUME_CURRENCY.ordinal()] = item.getVolumeCurrencyAsString();
+ columns[ColumnNames.TX_FEE.ordinal()] = item.getTxFeeAsString();
+ if (model.dataModel.isCurrencyForTradeFeeBtc(item.getTradable())) {
+ columns[ColumnNames.TRADE_FEE_BTC.ordinal()] = item.getTradeFeeAsString(false);
columns[ColumnNames.TRADE_FEE_BSQ.ordinal()] = "";
} else {
columns[ColumnNames.TRADE_FEE_BTC.ordinal()] = "";
- columns[ColumnNames.TRADE_FEE_BSQ.ordinal()] = model.getTradeFee(item, false);
+ columns[ColumnNames.TRADE_FEE_BSQ.ordinal()] = item.getTradeFeeAsString(false);
}
- columns[ColumnNames.BUYER_SEC.ordinal()] = model.getBuyerSecurityDeposit(item);
- columns[ColumnNames.SELLER_SEC.ordinal()] = model.getSellerSecurityDeposit(item);
- columns[ColumnNames.OFFER_TYPE.ordinal()] = model.getDirectionLabel(item);
- columns[ColumnNames.STATUS.ordinal()] = model.getState(item);
+ columns[ColumnNames.BUYER_SEC.ordinal()] = item.getBuyerSecurityDepositAsString();
+ columns[ColumnNames.SELLER_SEC.ordinal()] = item.getSellerSecurityDepositAsString();
+ columns[ColumnNames.OFFER_TYPE.ordinal()] = item.getDirectionLabel();
+ columns[ColumnNames.STATUS.ordinal()] = item.getState();
return columns;
};
GUIUtil.exportCSV("tradeHistory.csv", headerConverter, contentConverter,
- getDummyTradable(), sortedList, (Stage) root.getScene().getWindow());
+ null, sortedList, (Stage) root.getScene().getWindow());
});
summaryButton.setOnAction(event -> new ClosedTradesSummaryWindow(model).show());
- filterTextField.textProperty().addListener(filterTextFieldListener);
- applyFilteredListPredicate(filterTextField.getText());
root.widthProperty().addListener(widthListener);
onWidthChange(root.getWidth());
}
@@ -355,20 +335,20 @@ protected void deactivate() {
exportButton.setOnAction(null);
summaryButton.setOnAction(null);
- filterTextField.textProperty().removeListener(filterTextFieldListener);
+ filterBox.deactivate();
root.widthProperty().removeListener(widthListener);
}
- private static > Comparator nullsFirstComparing(Function keyExtractor) {
+ private static > Comparator nullsFirstComparing(Function keyExtractor) {
return Comparator.comparing(
o -> o != null ? keyExtractor.apply(o) : null,
Comparator.nullsFirst(Comparator.naturalOrder())
);
}
- private static > Comparator nullsFirstComparingAsTrade(Function keyExtractor) {
+ private static > Comparator nullsFirstComparingAsTrade(Function keyExtractor) {
return Comparator.comparing(
- o -> o instanceof TradeModel ? keyExtractor.apply((TradeModel) o) : null,
+ o -> o.getTradable() instanceof TradeModel ? keyExtractor.apply((TradeModel) o.getTradable()) : null,
Comparator.nullsFirst(Comparator.naturalOrder())
);
}
@@ -380,103 +360,6 @@ private void onWidthChange(double width) {
sellerSecurityDepositColumn.setVisible(width > 1500);
}
- private void applyFilteredListPredicate(String filterString) {
- filteredList.setPredicate(tradable -> {
- if (filterString.isEmpty())
- return true;
-
- Offer offer = tradable.getOffer();
- if (offer.getId().contains(filterString)) {
- return true;
- }
- if (model.getDate(tradable).contains(filterString)) {
- return true;
- }
- if (model.getMarketLabel(tradable).contains(filterString)) {
- return true;
- }
- if (model.getPrice(tradable).contains(filterString)) {
- return true;
- }
- if (model.getPriceDeviation(tradable).contains(filterString)) {
- return true;
- }
-
- if (model.getVolume(tradable, true).contains(filterString)) {
- return true;
- }
- if (model.getAmount(tradable).contains(filterString)) {
- return true;
- }
- if (model.getTradeFee(tradable, true).contains(filterString)) {
- return true;
- }
- if (model.getTxFee(tradable).contains(filterString)) {
- return true;
- }
- if (model.getBuyerSecurityDeposit(tradable).contains(filterString)) {
- return true;
- }
- if (model.getSellerSecurityDeposit(tradable).contains(filterString)) {
- return true;
- }
- if (model.getState(tradable).contains(filterString)) {
- return true;
- }
- if (model.getDirectionLabel(tradable).contains(filterString)) {
- return true;
- }
- if (offer.getPaymentMethod().getDisplayString().contains(filterString)) {
- return true;
- }
- if (offer.getOfferFeePaymentTxId() != null &&
- offer.getOfferFeePaymentTxId().contains(filterString)) {
- return true;
- }
-
- if (tradable instanceof BsqSwapTrade) {
- BsqSwapTrade bsqSwapTrade = (BsqSwapTrade) tradable;
- if (bsqSwapTrade.getTxId() != null && bsqSwapTrade.getTxId().contains(filterString)) {
- return true;
- }
- if (bsqSwapTrade.getTradingPeerNodeAddress().getFullAddress().contains(filterString)) {
- return true;
- }
- }
-
- if (tradable instanceof Trade) {
- Trade trade = (Trade) tradable;
- if (trade.getTakerFeeTxId() != null && trade.getTakerFeeTxId().contains(filterString)) {
- return true;
- }
- if (trade.getDepositTxId() != null && trade.getDepositTxId().contains(filterString)) {
- return true;
- }
- if (trade.getPayoutTxId() != null && trade.getPayoutTxId().contains(filterString)) {
- return true;
- }
-
- Contract contract = trade.getContract();
- boolean isBuyerOnion = false;
- boolean isSellerOnion = false;
- boolean matchesBuyersPaymentAccountData = false;
- boolean matchesSellersPaymentAccountData = false;
- if (contract != null) {
- isBuyerOnion = contract.getBuyerNodeAddress().getFullAddress().contains(filterString);
- isSellerOnion = contract.getSellerNodeAddress().getFullAddress().contains(filterString);
- matchesBuyersPaymentAccountData = contract.getBuyerPaymentAccountPayload() != null &&
- contract.getBuyerPaymentAccountPayload().getPaymentDetails().contains(filterString);
- matchesSellersPaymentAccountData = contract.getSellerPaymentAccountPayload() != null &&
- contract.getSellerPaymentAccountPayload().getPaymentDetails().contains(filterString);
- }
- return isBuyerOnion || isSellerOnion ||
- matchesBuyersPaymentAccountData || matchesSellersPaymentAccountData;
- } else {
- return false;
- }
- });
- }
-
private void setTradeIdColumnCellFactory() {
tradeIdColumn.getStyleClass().add("first-column");
tradeIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
@@ -484,17 +367,18 @@ private void setTradeIdColumnCellFactory() {
new Callback<>() {
@Override
- public TableCell call(TableColumn column) {
+ public TableCell call(TableColumn column) {
return new TableCell<>() {
private HyperlinkWithIcon field;
@Override
- public void updateItem(final Tradable tradable, boolean empty) {
- super.updateItem(tradable, empty);
- if (tradable != null && !empty) {
- field = new HyperlinkWithIcon(model.getTradeId(tradable));
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
+ super.updateItem(item, empty);
+ if (item != null && !empty) {
+ field = new HyperlinkWithIcon(item.getTradeId());
field.setOnAction(event -> {
+ Tradable tradable = item.getTradable();
if (tradable instanceof Trade) {
tradeDetailsWindow.show((Trade) tradable);
} else if (tradable instanceof BsqSwapTrade) {
@@ -517,18 +401,18 @@ public void updateItem(final Tradable tradable, boolean empty) {
}
private void setDateColumnCellFactory() {
- dateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ dateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
dateColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
- setGraphic(new AutoTooltipLabel(model.getDate(item)));
+ setGraphic(new AutoTooltipLabel(item.getDateAsString()));
else
setGraphic(null);
}
@@ -538,17 +422,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setMarketColumnCellFactory() {
- marketColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ marketColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
marketColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getMarketLabel(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getMarketLabel()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -556,18 +444,18 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setStateColumnCellFactory() {
- stateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ stateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
stateColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
- setGraphic(new AutoTooltipLabel(model.getState(item)));
+ setGraphic(new AutoTooltipLabel(item.getState()));
else
setGraphic(null);
}
@@ -582,21 +470,21 @@ private void setDuplicateColumnCellFactory() {
duplicateColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(TableColumn column) {
+ public TableCell call(TableColumn column) {
return new TableCell<>() {
Button button;
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- if (item != null && !empty && isMyOfferAsMaker(item.getOffer().getOfferPayloadBase())) {
+ if (item != null && !empty && isMyOfferAsMaker(item.getTradable().getOffer().getOfferPayloadBase())) {
if (button == null) {
button = getRegularIconButton(MaterialDesignIcon.CONTENT_COPY);
button.setTooltip(new Tooltip(Res.get("shared.duplicateOffer")));
setGraphic(button);
}
- button.setOnAction(event -> onDuplicateOffer(item.getOffer()));
+ button.setOnAction(event -> onDuplicateOffer(item.getTradable().getOffer()));
} else {
setGraphic(null);
if (button != null) {
@@ -611,22 +499,22 @@ public void updateItem(final Tradable item, boolean empty) {
}
@SuppressWarnings("UnusedReturnValue")
- private TableColumn setAvatarColumnCellFactory() {
+ private TableColumn setAvatarColumnCellFactory() {
avatarColumn.getStyleClass().addAll("last-column", "avatar-column");
- avatarColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ avatarColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
avatarColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(TableColumn column) {
+ public TableCell call(TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- if (!empty && item instanceof TradeModel) {
- TradeModel tradeModel = (TradeModel) item;
- int numPastTrades = model.dataModel.getNumPastTrades(tradeModel);
+ if (!empty && item != null && item.getTradable() instanceof TradeModel) {
+ TradeModel tradeModel = (TradeModel) item.getTradable();
+ int numPastTrades = item.getNumPastTrades();
NodeAddress tradingPeerNodeAddress = tradeModel.getTradingPeerNodeAddress();
String role = Res.get("peerInfoIcon.tooltip.tradePeer");
Node peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
@@ -650,17 +538,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setAmountColumnCellFactory() {
- amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ amountColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
amountColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getAmount(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getAmountAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -668,17 +560,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setPriceColumnCellFactory() {
- priceColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ priceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
priceColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getPrice(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getPriceAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -686,17 +582,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setDeviationColumnCellFactory() {
- deviationColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ deviationColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
deviationColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getPriceDeviation(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getPriceDeviationAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -704,18 +604,18 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setVolumeColumnCellFactory() {
- volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ volumeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
volumeColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
- setGraphic(new AutoTooltipLabel(model.getVolume(item, true)));
+ setGraphic(new AutoTooltipLabel(item.getVolumeAsString(true)));
else
setGraphic(null);
}
@@ -725,17 +625,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setDirectionColumnCellFactory() {
- directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ directionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
directionColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getDirectionLabel(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getDirectionLabel()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -743,17 +647,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setTxFeeColumnCellFactory() {
- txFeeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ txFeeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
txFeeColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getTxFee(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getTxFeeAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -761,17 +669,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setTradeFeeColumnCellFactory() {
- tradeFeeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ tradeFeeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
tradeFeeColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getTradeFee(item, true)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getTradeFeeAsString(true)));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -779,17 +691,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setBuyerSecurityDepositColumnCellFactory() {
- buyerSecurityDepositColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ buyerSecurityDepositColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
buyerSecurityDepositColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getBuyerSecurityDeposit(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getBuyerSecurityDepositAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -797,17 +713,21 @@ public void updateItem(final Tradable item, boolean empty) {
}
private void setSellerSecurityDepositColumnCellFactory() {
- sellerSecurityDepositColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
+ sellerSecurityDepositColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
sellerSecurityDepositColumn.setCellFactory(
new Callback<>() {
@Override
- public TableCell call(
- TableColumn column) {
+ public TableCell call(
+ TableColumn column) {
return new TableCell<>() {
@Override
- public void updateItem(final Tradable item, boolean empty) {
+ public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getSellerSecurityDeposit(item)));
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getSellerSecurityDepositAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -830,33 +750,4 @@ private void onDuplicateOffer(Offer offer) {
private boolean isMyOfferAsMaker(OfferPayloadBase offerPayloadBase) {
return offerPayloadBase.getPubKeyRing().equals(keyRing.getPubKeyRing());
}
-
- private Tradable getDummyTradable() {
- return new Tradable() {
- @Override
- public Offer getOffer() {
- return null;
- }
-
- @Override
- public Date getDate() {
- return null;
- }
-
- @Override
- public String getId() {
- return null;
- }
-
- @Override
- public String getShortId() {
- return null;
- }
-
- @Override
- public Message toProtoMessage() {
- return null;
- }
- };
- }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java
index 2ba1f9b7f82..1512a23e23f 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java
@@ -19,13 +19,9 @@
import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.model.ViewModel;
-import bisq.desktop.util.DisplayUtils;
-import bisq.core.locale.CurrencyUtil;
import bisq.core.monetary.Volume;
-import bisq.core.offer.OfferDirection;
import bisq.core.trade.ClosedTradableFormatter;
-import bisq.core.trade.model.Tradable;
import org.bitcoinj.core.Coin;
@@ -43,69 +39,6 @@ public ClosedTradesViewModel(ClosedTradesDataModel dataModel, ClosedTradableForm
this.closedTradableFormatter = closedTradableFormatter;
}
- String getTradeId(Tradable item) {
- return item.getShortId();
- }
-
- String getAmount(Tradable item) {
- return item != null ? closedTradableFormatter.getAmountAsString(item) : "";
- }
-
- String getPrice(Tradable item) {
- return item != null ? closedTradableFormatter.getPriceAsString(item) : "";
- }
-
- String getPriceDeviation(Tradable item) {
- return item != null ? closedTradableFormatter.getPriceDeviationAsString(item) : "";
- }
-
- String getVolume(Tradable item, boolean appendCode) {
- return item != null ? closedTradableFormatter.getVolumeAsString(item, appendCode) : "";
- }
-
- String getVolumeCurrency(Tradable item) {
- return item != null ? closedTradableFormatter.getVolumeCurrencyAsString(item) : "";
- }
-
- String getTxFee(Tradable item) {
- return item != null ? closedTradableFormatter.getTxFeeAsString(item) : "";
- }
-
- String getTradeFee(Tradable item, boolean appendCode) {
- return item != null ? closedTradableFormatter.getTradeFeeAsString(item, appendCode) : "";
- }
-
- String getBuyerSecurityDeposit(Tradable item) {
- return item != null ? closedTradableFormatter.getBuyerSecurityDepositAsString(item) : "";
- }
-
- String getSellerSecurityDeposit(Tradable item) {
- return item != null ? closedTradableFormatter.getSellerSecurityDepositAsString(item) : "";
- }
-
- String getDirectionLabel(Tradable item) {
- if ((item != null)) {
- OfferDirection direction = dataModel.getDirection(item.getOffer());
- String currencyCode = item.getOffer().getCurrencyCode();
- return DisplayUtils.getDirectionWithCode(direction, currencyCode);
- } else {
- return "";
- }
- }
-
- String getDate(Tradable item) {
- return DisplayUtils.formatDateTime(item.getDate());
- }
-
- String getMarketLabel(Tradable item) {
- return item != null ? CurrencyUtil.getCurrencyPair(item.getOffer().getCurrencyCode()) : "";
- }
-
- String getState(Tradable item) {
- return item != null ? closedTradableFormatter.getStateAsString(item) : "";
- }
-
-
///////////////////////////////////////////////////////////////////////////////////////////
// Used in ClosedTradesSummaryWindow
///////////////////////////////////////////////////////////////////////////////////////////
@@ -121,7 +54,7 @@ public String getTotalAmountWithVolume(Coin totalTradeAmount) {
}
public Map getTotalVolumeByCurrency() {
- return closedTradableFormatter.getTotalVolumeByCurrencyAsString(dataModel.getList());
+ return closedTradableFormatter.getTotalVolumeByCurrencyAsString(dataModel.getListAsTradables());
}
public String getTotalTxFee(Coin totalTradeAmount) {
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesDataModel.java
index ea658e1f935..69c6af27b39 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesDataModel.java
@@ -19,11 +19,11 @@
import bisq.desktop.common.model.ActivatableDataModel;
-import bisq.core.offer.Offer;
-import bisq.core.offer.OfferDirection;
import bisq.core.trade.TradeManager;
import bisq.core.trade.bisq_v1.FailedTradesManager;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.coin.CoinFormatter;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
@@ -32,6 +32,8 @@
import com.google.inject.Inject;
+import javax.inject.Named;
+
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
@@ -45,6 +47,7 @@ class FailedTradesDataModel extends ActivatableDataModel {
private final TradeManager tradeManager;
private final P2PService p2PService;
private final KeyRing keyRing;
+ private final CoinFormatter btcFormatter;
private final ObservableList list = FXCollections.observableArrayList();
private final ListChangeListener tradesListChangeListener;
@@ -53,11 +56,13 @@ class FailedTradesDataModel extends ActivatableDataModel {
public FailedTradesDataModel(FailedTradesManager failedTradesManager,
TradeManager tradeManager,
P2PService p2PService,
- KeyRing keyRing) {
+ KeyRing keyRing,
+ @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter) {
this.failedTradesManager = failedTradesManager;
this.tradeManager = tradeManager;
this.p2PService = p2PService;
this.keyRing = keyRing;
+ this.btcFormatter = btcFormatter;
tradesListChangeListener = change -> applyList();
}
@@ -77,14 +82,15 @@ public ObservableList getList() {
return list;
}
- public OfferDirection getDirection(Offer offer) {
- return failedTradesManager.wasMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
- }
private void applyList() {
list.clear();
- list.addAll(failedTradesManager.getObservableList().stream().map(FailedTradesListItem::new).collect(Collectors.toList()));
+ list.addAll(
+ failedTradesManager.getObservableList().stream()
+ .map(trade -> new FailedTradesListItem(trade, btcFormatter, failedTradesManager))
+ .collect(Collectors.toList())
+ );
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesListItem.java b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesListItem.java
index 52973a2316d..36e7b864601 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesListItem.java
@@ -17,19 +17,92 @@
package bisq.desktop.main.portfolio.failedtrades;
+import bisq.desktop.util.DisplayUtils;
+import bisq.desktop.util.filtering.FilterableListItem;
+import bisq.desktop.util.filtering.FilteringUtils;
+
+import bisq.core.locale.CurrencyUtil;
+import bisq.core.locale.Res;
+import bisq.core.offer.Offer;
+import bisq.core.offer.OfferDirection;
+import bisq.core.trade.bisq_v1.FailedTradesManager;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.VolumeUtil;
+import bisq.core.util.coin.CoinFormatter;
+
+import org.apache.commons.lang3.StringUtils;
import lombok.Getter;
-class FailedTradesListItem {
+class FailedTradesListItem implements FilterableListItem {
@Getter
private final Trade trade;
+ private final CoinFormatter btcFormatter;
+ private final FailedTradesManager failedTradesManager;
- FailedTradesListItem(Trade trade) {
+ FailedTradesListItem(Trade trade, CoinFormatter btcFormatter, FailedTradesManager failedTradesManager) {
this.trade = trade;
+ this.btcFormatter = btcFormatter;
+ this.failedTradesManager = failedTradesManager;
+ }
+
+ public String getDateAsString() {
+ return DisplayUtils.formatDateTime(trade.getDate());
+ }
+
+ public String getMarketLabel() {
+ return CurrencyUtil.getCurrencyPair(trade.getOffer().getCurrencyCode());
+ }
+
+ public String getAmountAsString() {
+ return btcFormatter.formatCoin(trade.getAmount());
+ }
+
+ public String getPriceAsString() {
+ return FormattingUtils.formatPrice(trade.getPrice());
+ }
+
+ public String getVolumeAsString() {
+ return VolumeUtil.formatVolumeWithCode(trade.getVolume());
+ }
+
+ public String getDirectionLabel() {
+ Offer offer = trade.getOffer();
+ OfferDirection direction = failedTradesManager.wasMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
+ return DisplayUtils.getDirectionWithCode(direction, trade.getOffer().getCurrencyCode());
+ }
+
+ public String getState() {
+ return Res.get("portfolio.failed.Failed");
}
- FailedTradesListItem() {
- this.trade = null;
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDateAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getMarketLabel(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPriceAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getVolumeAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAmountAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDirectionLabel(), filterString)) {
+ return true;
+ }
+ if (FilteringUtils.match(getTrade().getOffer(), filterString)) {
+ return true;
+ }
+ return FilteringUtils.match(getTrade(), filterString);
}
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.fxml b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.fxml
index d89bb0a5bba..aeab9a7fb71 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.fxml
@@ -18,26 +18,20 @@
-->
-
-
-
+
-
-
-
-
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.java
index bfc10599e40..7123744d268 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesView.java
@@ -22,15 +22,13 @@
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.HyperlinkWithIcon;
-import bisq.desktop.components.InputTextField;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.GUIUtil;
import bisq.core.locale.Res;
-import bisq.core.offer.Offer;
-import bisq.core.trade.model.bisq_v1.Contract;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.common.config.Config;
@@ -58,7 +56,6 @@
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
@@ -66,7 +63,6 @@
import javafx.geometry.Insets;
import javafx.beans.property.ReadOnlyObjectWrapper;
-import javafx.beans.value.ChangeListener;
import javafx.event.EventHandler;
@@ -87,13 +83,7 @@ public class FailedTradesView extends ActivatableViewAndModel priceColumn, amountColumn, volumeColumn,
marketColumn, directionColumn, dateColumn, tradeIdColumn, stateColumn, removeTradeColumn;
@FXML
- HBox searchBox;
- @FXML
- AutoTooltipLabel filterLabel;
- @FXML
- InputTextField filterTextField;
- @FXML
- Pane searchBoxSpacer;
+ FilterBox filterBox;
@FXML
Label numItems;
@FXML
@@ -105,7 +95,6 @@ public class FailedTradesView extends ActivatableViewAndModel sortedList;
private FilteredList filteredList;
private EventHandler keyEventEventHandler;
- private ChangeListener filterTextFieldListener;
private Scene scene;
private final boolean allowFaultyDelayedTxs;
@@ -147,8 +136,8 @@ public void initialize() {
priceColumn.setComparator(Comparator.comparing(o -> o.getTrade().getPrice()));
volumeColumn.setComparator(Comparator.comparing(o -> o.getTrade().getVolume(), Comparator.nullsFirst(Comparator.naturalOrder())));
amountColumn.setComparator(Comparator.comparing(o -> o.getTrade().getAmount(), Comparator.nullsFirst(Comparator.naturalOrder())));
- stateColumn.setComparator(Comparator.comparing(model::getState));
- marketColumn.setComparator(Comparator.comparing(model::getMarketLabel));
+ stateColumn.setComparator(Comparator.comparing(FailedTradesListItem::getState));
+ marketColumn.setComparator(Comparator.comparing(FailedTradesListItem::getMarketLabel));
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
tableView.getSortOrder().add(dateColumn);
@@ -173,12 +162,6 @@ public void initialize() {
}
};
- filterLabel.setText(Res.get("shared.filter"));
- HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
- filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
- searchBox.setSpacing(5);
- HBox.setHgrow(searchBoxSpacer, Priority.ALWAYS);
-
numItems.setId("num-offers");
numItems.setPadding(new Insets(-5, 0, 0, 10));
HBox.setHgrow(footerSpacer, Priority.ALWAYS);
@@ -193,11 +176,14 @@ protected void activate() {
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
}
- filteredList = new FilteredList<>(model.getList());
+ filteredList = new FilteredList<>(model.dataModel.getList());
sortedList = new SortedList<>(filteredList);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
tableView.setItems(sortedList);
+ filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
+ filterBox.activate();
+
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
exportButton.setOnAction(event -> {
ObservableList> tableColumns = tableView.getColumns();
@@ -210,27 +196,24 @@ protected void activate() {
};
CSVEntryConverter contentConverter = item -> {
String[] columns = new String[reportColumns];
- columns[0] = model.getTradeId(item);
- columns[1] = model.getDate(item);
- columns[2] = model.getMarketLabel(item);
- columns[3] = model.getPrice(item);
- columns[4] = model.getAmount(item);
- columns[5] = model.getVolume(item);
- columns[6] = model.getDirectionLabel(item);
- columns[7] = model.getState(item);
+ columns[0] = item.getTrade().getShortId();
+ columns[1] = item.getDateAsString();
+ columns[2] = item.getMarketLabel();
+ columns[3] = item.getPriceAsString();
+ columns[4] = item.getAmountAsString();
+ columns[5] = item.getVolumeAsString();
+ columns[6] = item.getDirectionLabel();
+ columns[7] = item.getState();
return columns;
};
GUIUtil.exportCSV("failedTrades.csv",
headerConverter,
contentConverter,
- new FailedTradesListItem(),
+ null,
sortedList,
(Stage) root.getScene().getWindow());
});
-
- filterTextField.textProperty().addListener(filterTextFieldListener);
- applyFilteredListPredicate(filterTextField.getText());
}
@Override
@@ -241,72 +224,7 @@ protected void deactivate() {
sortedList.comparatorProperty().unbind();
exportButton.setOnAction(null);
-
- filterTextField.textProperty().removeListener(filterTextFieldListener);
- }
-
- private void applyFilteredListPredicate(String filterString) {
- filteredList.setPredicate(item -> {
- if (filterString.isEmpty())
- return true;
-
- Offer offer = item.getTrade().getOffer();
-
- if (offer.getId().contains(filterString)) {
- return true;
- }
- if (model.getDate(item).contains(filterString)) {
- return true;
- }
- if (model.getMarketLabel(item).contains(filterString)) {
- return true;
- }
- if (model.getPrice(item).contains(filterString)) {
- return true;
- }
- if (model.getVolume(item).contains(filterString)) {
- return true;
- }
- if (model.getAmount(item).contains(filterString)) {
- return true;
- }
- if (model.getDirectionLabel(item).contains(filterString)) {
- return true;
- }
- if (offer.getOfferFeePaymentTxId() != null &&
- offer.getOfferFeePaymentTxId().contains(filterString)) {
- return true;
- }
-
- Trade trade = item.getTrade();
-
- if (trade.getTakerFeeTxId() != null && trade.getTakerFeeTxId().contains(filterString)) {
- return true;
- }
- if (trade.getDepositTxId() != null && trade.getDepositTxId().contains(filterString)) {
- return true;
- }
- if (trade.getPayoutTxId() != null && trade.getPayoutTxId().contains(filterString)) {
- return true;
- }
-
- Contract contract = trade.getContract();
-
- boolean isBuyerOnion = false;
- boolean isSellerOnion = false;
- boolean matchesBuyersPaymentAccountData = false;
- boolean matchesSellersPaymentAccountData = false;
- if (contract != null) {
- isBuyerOnion = contract.getBuyerNodeAddress().getFullAddress().contains(filterString);
- isSellerOnion = contract.getSellerNodeAddress().getFullAddress().contains(filterString);
- matchesBuyersPaymentAccountData = contract.getBuyerPaymentAccountPayload() != null &&
- contract.getBuyerPaymentAccountPayload().getPaymentDetails().contains(filterString);
- matchesSellersPaymentAccountData = contract.getSellerPaymentAccountPayload() != null &&
- contract.getSellerPaymentAccountPayload().getPaymentDetails().contains(filterString);
- }
- return isBuyerOnion || isSellerOnion ||
- matchesBuyersPaymentAccountData || matchesSellersPaymentAccountData;
- });
+ filterBox.deactivate();
}
private void onUnfail() {
@@ -367,7 +285,7 @@ public TableCell call(TableColumn tradeDetailsWindow.show(item.getTrade()));
field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails")));
setGraphic(field);
@@ -394,7 +312,7 @@ public TableCell call(
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
- setGraphic(new AutoTooltipLabel(model.getDate(item)));
+ setGraphic(new AutoTooltipLabel(item.getDateAsString()));
else
setGraphic(null);
}
@@ -414,7 +332,11 @@ public TableCell call(
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getMarketLabel(item)));
+ if (!empty && item != null) {
+ setGraphic(new AutoTooltipLabel(item.getMarketLabel()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -434,7 +356,7 @@ public TableCell call(
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
- setGraphic(new AutoTooltipLabel(model.getState(item)));
+ setGraphic(new AutoTooltipLabel(item.getState()));
else
setGraphic(null);
}
@@ -455,7 +377,11 @@ public TableCell call(
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getAmount(item)));
+ if (!empty && item != null) {
+ setGraphic(new AutoTooltipLabel(item.getAmountAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -473,7 +399,11 @@ public TableCell call(
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getPrice(item)));
+ if (!empty && item != null) {
+ setGraphic(new AutoTooltipLabel(item.getPriceAsString()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
@@ -492,7 +422,7 @@ public TableCell call(
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
- setGraphic(new AutoTooltipLabel(model.getVolume(item)));
+ setGraphic(new AutoTooltipLabel(item.getVolumeAsString()));
else
setGraphic(null);
}
@@ -512,7 +442,11 @@ public TableCell call(
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getDirectionLabel(item)));
+ if (!empty && item != null) {
+ setGraphic(new AutoTooltipLabel(item.getDirectionLabel()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java
index 0e747d54bf4..5775d7d57f5 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java
@@ -19,74 +19,12 @@
import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.model.ViewModel;
-import bisq.desktop.util.DisplayUtils;
-
-import bisq.core.locale.CurrencyUtil;
-import bisq.core.locale.Res;
-import bisq.core.util.FormattingUtils;
-import bisq.core.util.VolumeUtil;
-import bisq.core.util.coin.CoinFormatter;
import com.google.inject.Inject;
-import javax.inject.Named;
-
-import javafx.collections.ObservableList;
-
class FailedTradesViewModel extends ActivatableWithDataModel implements ViewModel {
- private final CoinFormatter formatter;
-
-
@Inject
- public FailedTradesViewModel(FailedTradesDataModel dataModel,
- @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter) {
+ public FailedTradesViewModel(FailedTradesDataModel dataModel) {
super(dataModel);
-
- this.formatter = formatter;
- }
-
- public ObservableList getList() {
- return dataModel.getList();
- }
-
- String getTradeId(FailedTradesListItem item) {
- return item.getTrade().getShortId();
- }
-
- String getAmount(FailedTradesListItem item) {
- if (item != null && item.getTrade() != null)
- return formatter.formatCoin(item.getTrade().getAmount());
- else
- return "";
- }
-
- String getPrice(FailedTradesListItem item) {
- return (item != null) ? FormattingUtils.formatPrice(item.getTrade().getPrice()) : "";
- }
-
- String getVolume(FailedTradesListItem item) {
- if (item != null && item.getTrade() != null)
- return VolumeUtil.formatVolumeWithCode(item.getTrade().getVolume());
- else
- return "";
- }
-
- String getDirectionLabel(FailedTradesListItem item) {
- return (item != null) ? DisplayUtils.getDirectionWithCode(dataModel.getDirection(item.getTrade().getOffer()), item.getTrade().getOffer().getCurrencyCode()) : "";
- }
-
- String getMarketLabel(FailedTradesListItem item) {
- if ((item == null))
- return "";
-
- return CurrencyUtil.getCurrencyPair(item.getTrade().getOffer().getCurrencyCode());
- }
-
- String getDate(FailedTradesListItem item) {
- return DisplayUtils.formatDateTime(item.getTrade().getDate());
- }
-
- String getState(FailedTradesListItem item) {
- return item != null ? Res.get("portfolio.failed.Failed") : "";
}
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOfferListItem.java b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOfferListItem.java
index 6640f2b0d10..11cf4266284 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOfferListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOfferListItem.java
@@ -17,27 +17,152 @@
package bisq.desktop.main.portfolio.openoffer;
+import bisq.desktop.util.DisplayUtils;
+import bisq.desktop.util.filtering.FilterableListItem;
+import bisq.desktop.util.filtering.FilteringUtils;
+
+import bisq.core.locale.CurrencyUtil;
+import bisq.core.locale.Res;
+import bisq.core.monetary.Price;
import bisq.core.offer.Offer;
+import bisq.core.offer.OfferDirection;
import bisq.core.offer.OpenOffer;
+import bisq.core.offer.OpenOfferManager;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.PriceUtil;
+import bisq.core.util.VolumeUtil;
+import bisq.core.util.coin.BsqFormatter;
+import bisq.core.util.coin.CoinFormatter;
+
+import org.apache.commons.lang3.StringUtils;
import lombok.Getter;
/**
* We could remove that wrapper if it is not needed for additional UI only fields.
*/
-class OpenOfferListItem {
+class OpenOfferListItem implements FilterableListItem {
@Getter
private final OpenOffer openOffer;
+ private final PriceUtil priceUtil;
+ private final CoinFormatter btcFormatter;
+ private final BsqFormatter bsqFormatter;
+ private final OpenOfferManager openOfferManager;
- OpenOfferListItem(OpenOffer openOffer) {
- this.openOffer = openOffer;
- }
- OpenOfferListItem() {
- openOffer = null;
+ OpenOfferListItem(OpenOffer openOffer, PriceUtil priceUtil, CoinFormatter btcFormatter, BsqFormatter bsqFormatter, OpenOfferManager openOfferManager) {
+ this.openOffer = openOffer;
+ this.priceUtil = priceUtil;
+ this.btcFormatter = btcFormatter;
+ this.bsqFormatter = bsqFormatter;
+ this.openOfferManager = openOfferManager;
}
public Offer getOffer() {
return openOffer.getOffer();
}
+
+ public String getDateAsString() {
+ return DisplayUtils.formatDateTime(getOffer().getDate());
+ }
+
+ public String getMarketDescription() {
+ return CurrencyUtil.getCurrencyPair(getOffer().getCurrencyCode());
+ }
+
+ public String getPriceAsString() {
+ Price price = getOffer().getPrice();
+ if (price != null) {
+ return FormattingUtils.formatPrice(price);
+ } else {
+ return Res.get("shared.na");
+ }
+ }
+
+ public Double getPriceDeviationAsDouble() {
+ Offer offer = getOffer();
+ return priceUtil.getMarketBasedPrice(offer, offer.getMirroredDirection()).orElse(0d);
+ }
+
+ public String getPriceDeviationAsString() {
+ Offer offer = getOffer();
+ return priceUtil.getMarketBasedPrice(offer, offer.getMirroredDirection())
+ .map(FormattingUtils::formatPercentagePrice)
+ .orElse("");
+ }
+
+ public String getPaymentMethodAsString() {
+ return getOffer().getPaymentMethodNameWithCountryCode();
+ }
+
+ public String getVolumeAsString() {
+ return VolumeUtil.formatVolume(getOffer(), false, 0) + " " + getOffer().getCurrencyCode();
+ }
+
+ public String getAmountAsString() {
+ return DisplayUtils.formatAmount(getOffer(), btcFormatter);
+ }
+
+ public String getDirectionLabel() {
+ Offer offer = getOffer();
+ OfferDirection direction = openOfferManager.isMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
+ return DisplayUtils.getDirectionWithCode(direction, getOffer().getCurrencyCode());
+ }
+
+ public boolean hasMakerFee() {
+ return getOffer().getMakerFee().isPositive();
+ }
+
+ public String getMakerFeeAsString() {
+ Offer offer = getOffer();
+ return offer.isCurrencyForMakerFeeBtc() ?
+ btcFormatter.formatCoinWithCode(offer.getMakerFee()) :
+ bsqFormatter.formatCoinWithCode(offer.getMakerFee());
+ }
+
+ public boolean isNotPublished() {
+ return openOffer.isDeactivated() || (getOffer().isBsqSwapOffer() && openOffer.isBsqSwapOfferHasMissingFunds());
+ }
+
+ public String getTriggerPriceAsString() {
+ Offer offer = getOffer();
+ long triggerPrice = openOffer.getTriggerPrice();
+ if (!offer.isUseMarketBasedPrice() || triggerPrice <= 0) {
+ return Res.get("shared.na");
+ } else {
+ return PriceUtil.formatMarketPrice(triggerPrice, offer.getCurrencyCode());
+ }
+ }
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDateAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getMarketDescription(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPriceAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPriceDeviationAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPaymentMethodAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getVolumeAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAmountAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getDirectionLabel(), filterString)) {
+ return true;
+ }
+ return FilteringUtils.match(getOffer(), filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersDataModel.java
index 752d52d8467..30e3c814a69 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersDataModel.java
@@ -26,12 +26,18 @@
import bisq.core.offer.bisq_v1.TriggerPriceService;
import bisq.core.offer.bsq_swap.OpenBsqSwapOfferService;
import bisq.core.provider.price.PriceFeedService;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.PriceUtil;
+import bisq.core.util.coin.BsqFormatter;
+import bisq.core.util.coin.CoinFormatter;
import bisq.common.handlers.ErrorMessageHandler;
import bisq.common.handlers.ResultHandler;
import com.google.inject.Inject;
+import javax.inject.Named;
+
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
@@ -44,6 +50,9 @@ class OpenOffersDataModel extends ActivatableDataModel {
private final OpenOfferManager openOfferManager;
private final OpenBsqSwapOfferService openBsqSwapOfferService;
private final PriceFeedService priceFeedService;
+ private final PriceUtil priceUtil;
+ private final CoinFormatter btcFormatter;
+ private final BsqFormatter bsqFormatter;
private final ObservableList list = FXCollections.observableArrayList();
private final ListChangeListener tradesListChangeListener;
@@ -52,10 +61,16 @@ class OpenOffersDataModel extends ActivatableDataModel {
@Inject
public OpenOffersDataModel(OpenOfferManager openOfferManager,
OpenBsqSwapOfferService openBsqSwapOfferService,
- PriceFeedService priceFeedService) {
+ PriceFeedService priceFeedService,
+ PriceUtil priceUtil,
+ @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
+ BsqFormatter bsqFormatter) {
this.openOfferManager = openOfferManager;
this.openBsqSwapOfferService = openBsqSwapOfferService;
this.priceFeedService = priceFeedService;
+ this.priceUtil = priceUtil;
+ this.btcFormatter = btcFormatter;
+ this.bsqFormatter = bsqFormatter;
tradesListChangeListener = change -> applyList();
currenciesUpdateFlagPropertyListener = (observable, oldValue, newValue) -> applyList();
@@ -106,7 +121,11 @@ public OfferDirection getDirection(Offer offer) {
private void applyList() {
list.clear();
- list.addAll(openOfferManager.getObservableList().stream().map(OpenOfferListItem::new).collect(Collectors.toList()));
+ list.addAll(
+ openOfferManager.getObservableList().stream()
+ .map(item -> new OpenOfferListItem(item, priceUtil, btcFormatter, bsqFormatter, openOfferManager))
+ .collect(Collectors.toList())
+ );
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getOffer().getDate().compareTo(o1.getOffer().getDate()));
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.fxml b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.fxml
index e3e729317c0..4a0e6201e85 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.fxml
@@ -18,9 +18,8 @@
-->
-
-
+
@@ -34,10 +33,9 @@
-
-
-
-
+
+
+
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java
index f4f6af87ed1..349aa054d88 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java
@@ -25,7 +25,7 @@
import bisq.desktop.components.AutoTooltipSlideToggleButton;
import bisq.desktop.components.AutoTooltipTableColumn;
import bisq.desktop.components.HyperlinkWithIcon;
-import bisq.desktop.components.InputTextField;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.MainView;
import bisq.desktop.main.funds.FundsView;
import bisq.desktop.main.funds.withdrawal.WithdrawalView;
@@ -62,7 +62,6 @@
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
@@ -121,13 +120,7 @@ public String toString() {
marketColumn, directionColumn, dateColumn, offerIdColumn, deactivateItemColumn,
removeItemColumn, editItemColumn, triggerPriceColumn, triggerIconColumn, paymentMethodColumn, duplicateItemColumn;
@FXML
- HBox searchBox;
- @FXML
- AutoTooltipLabel filterLabel;
- @FXML
- InputTextField filterTextField;
- @FXML
- Pane searchBoxSpacer;
+ FilterBox filterBox;
@FXML
Label numItems;
@FXML
@@ -141,8 +134,6 @@ public String toString() {
private final OfferDetailsWindow offerDetailsWindow;
private final BsqSwapOfferDetailsWindow bsqSwapOfferDetailsWindow;
private SortedList sortedList;
- private FilteredList filteredList;
- private ChangeListener filterTextFieldListener;
private PortfolioView.OpenOfferActionHandler openOfferActionHandler;
private ChangeListener widthListener;
@@ -197,10 +188,10 @@ public void initialize() {
offerIdColumn.setComparator(Comparator.comparing(o -> o.getOffer().getId()));
directionColumn.setComparator(Comparator.comparing(o -> o.getOffer().getDirection()));
- marketColumn.setComparator(Comparator.comparing(model::getMarketLabel));
+ marketColumn.setComparator(Comparator.comparing(OpenOfferListItem::getMarketDescription));
amountColumn.setComparator(Comparator.comparing(o -> o.getOffer().getAmount()));
priceColumn.setComparator(Comparator.comparing(o -> o.getOffer().getPrice(), Comparator.nullsFirst(Comparator.naturalOrder())));
- deviationColumn.setComparator(Comparator.comparing(model::getPriceDeviationAsDouble, Comparator.nullsFirst(Comparator.naturalOrder())));
+ deviationColumn.setComparator(Comparator.comparing(OpenOfferListItem::getPriceDeviationAsDouble, Comparator.nullsFirst(Comparator.naturalOrder())));
triggerPriceColumn.setComparator(Comparator.comparing(o -> o.getOpenOffer().getTriggerPrice(),
Comparator.nullsFirst(Comparator.naturalOrder())));
volumeColumn.setComparator(Comparator.comparing(o -> o.getOffer().getVolume(), Comparator.nullsFirst(Comparator.naturalOrder())));
@@ -224,12 +215,6 @@ public void initialize() {
return row;
});
- filterLabel.setText(Res.get("shared.filter"));
- HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
- filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
- searchBox.setSpacing(5);
- HBox.setHgrow(searchBoxSpacer, Priority.ALWAYS);
-
selectToggleButton.setPadding(new Insets(0, 90, -20, 0));
selectToggleButton.setText(Res.get("shared.enabled"));
selectToggleButton.setDisable(true);
@@ -243,11 +228,14 @@ public void initialize() {
@Override
protected void activate() {
- filteredList = new FilteredList<>(model.getList());
+ FilteredList filteredList = new FilteredList<>(model.dataModel.getList());
sortedList = new SortedList<>(filteredList);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
tableView.setItems(sortedList);
+ filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
+ filterBox.activate();
+
updateSelectToggleButtonState();
selectToggleButton.setOnAction(event -> {
@@ -272,16 +260,16 @@ protected void activate() {
};
CSVEntryConverter contentConverter = item -> {
String[] columns = new String[ColumnNames.values().length];
- columns[ColumnNames.OFFER_ID.ordinal()] = model.getOfferId(item);
- columns[ColumnNames.DATE.ordinal()] = model.getDate(item);
- columns[ColumnNames.MARKET.ordinal()] = model.getMarketLabel(item);
- columns[ColumnNames.PRICE.ordinal()] = model.getPrice(item);
- columns[ColumnNames.DEVIATION.ordinal()] = model.getPriceDeviation(item);
- columns[ColumnNames.TRIGGER_PRICE.ordinal()] = model.getTriggerPrice(item);
- columns[ColumnNames.AMOUNT.ordinal()] = model.getAmount(item);
- columns[ColumnNames.VOLUME.ordinal()] = model.getVolume(item);
- columns[ColumnNames.PAYMENT_METHOD.ordinal()] = model.getPaymentMethod(item);
- columns[ColumnNames.DIRECTION.ordinal()] = model.getDirectionLabel(item);
+ columns[ColumnNames.OFFER_ID.ordinal()] = item.getOffer().getShortId();
+ columns[ColumnNames.DATE.ordinal()] = item.getDateAsString();
+ columns[ColumnNames.MARKET.ordinal()] = item.getMarketDescription();
+ columns[ColumnNames.PRICE.ordinal()] = item.getPriceAsString();
+ columns[ColumnNames.DEVIATION.ordinal()] = item.getPriceDeviationAsString();
+ columns[ColumnNames.TRIGGER_PRICE.ordinal()] = item.getTriggerPriceAsString();
+ columns[ColumnNames.AMOUNT.ordinal()] = item.getAmountAsString();
+ columns[ColumnNames.VOLUME.ordinal()] = item.getVolumeAsString();
+ columns[ColumnNames.PAYMENT_METHOD.ordinal()] = item.getPaymentMethodAsString();
+ columns[ColumnNames.DIRECTION.ordinal()] = item.getDirectionLabel();
columns[ColumnNames.STATUS.ordinal()] = String.valueOf(!item.getOpenOffer().isDeactivated());
return columns;
};
@@ -289,14 +277,11 @@ protected void activate() {
GUIUtil.exportCSV("openOffers.csv",
headerConverter,
contentConverter,
- new OpenOfferListItem(),
+ new OpenOfferListItem(null, null, null, null, null),
sortedList,
(Stage) root.getScene().getWindow());
});
- filterTextField.textProperty().addListener(filterTextFieldListener);
- applyFilteredListPredicate(filterTextField.getText());
-
root.widthProperty().addListener(widthListener);
onWidthChange(root.getWidth());
}
@@ -306,7 +291,7 @@ protected void deactivate() {
sortedList.comparatorProperty().unbind();
exportButton.setOnAction(null);
- filterTextField.textProperty().removeListener(filterTextFieldListener);
+ filterBox.deactivate();
root.widthProperty().removeListener(widthListener);
}
@@ -327,44 +312,6 @@ private void updateSelectToggleButtonState() {
}
}
- private void applyFilteredListPredicate(String filterString) {
- filteredList.setPredicate(item -> {
- if (filterString.isEmpty())
- return true;
-
- Offer offer = item.getOpenOffer().getOffer();
- if (offer.getId().contains(filterString)) {
- return true;
- }
- if (model.getDate(item).contains(filterString)) {
- return true;
- }
- if (model.getMarketLabel(item).contains(filterString)) {
- return true;
- }
- if (model.getPrice(item).contains(filterString)) {
- return true;
- }
- if (model.getPriceDeviation(item).contains(filterString)) {
- return true;
- }
- if (model.getPaymentMethod(item).contains(filterString)) {
- return true;
- }
- if (model.getVolume(item).contains(filterString)) {
- return true;
- }
- if (model.getAmount(item).contains(filterString)) {
- return true;
- }
- if (model.getDirectionLabel(item).contains(filterString)) {
- return true;
- }
- return offer.getOfferFeePaymentTxId() != null &&
- offer.getOfferFeePaymentTxId().contains(filterString);
- });
- }
-
private void onWidthChange(double width) {
triggerPriceColumn.setVisible(width > 1200);
}
@@ -393,12 +340,13 @@ private void onActivateOpenOffer(OpenOffer openOffer) {
}
}
- private void onRemoveOpenOffer(OpenOffer openOffer) {
+ private void onRemoveOpenOffer(OpenOfferListItem item) {
+ OpenOffer openOffer = item.getOpenOffer();
if (model.isBootstrappedOrShowPopup()) {
String key = "RemoveOfferWarning";
if (DontShowAgainLookup.showAgain(key)) {
- String message = model.hasMakerFee(openOffer) ?
- Res.get("popup.warning.removeOffer", model.getMakerFeeAsString(openOffer)) :
+ String message = item.hasMakerFee() ?
+ Res.get("popup.warning.removeOffer", item.getMakerFeeAsString()) :
Res.get("popup.warning.removeNoFeeOffer");
new Popup().warning(message)
.actionButtonText(Res.get("shared.removeOffer"))
@@ -468,7 +416,7 @@ public TableCell call(TableColumn {
if (item.getOffer().isBsqSwapOffer()) {
bsqSwapOfferDetailsWindow.show(item.getOffer());
@@ -503,8 +451,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
super.updateItem(item, empty);
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getDate(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getDateAsString()));
} else {
setGraphic(null);
}
@@ -528,8 +476,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getAmount(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getAmountAsString()));
} else {
setGraphic(null);
}
@@ -553,8 +501,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getPrice(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getPriceAsString()));
} else {
setGraphic(null);
}
@@ -578,8 +526,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- AutoTooltipLabel autoTooltipLabel = new AutoTooltipLabel(model.getPriceDeviation(item));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ AutoTooltipLabel autoTooltipLabel = new AutoTooltipLabel(item.getPriceDeviationAsString());
autoTooltipLabel.setOpacity(item.getOffer().isUseMarketBasedPrice() ? 1 : 0.4);
setGraphic(autoTooltipLabel);
} else {
@@ -604,8 +552,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
super.updateItem(item, empty);
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getTriggerPrice(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getTriggerPriceAsString()));
} else {
setGraphic(null);
}
@@ -629,8 +577,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getVolume(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getVolumeAsString()));
} else {
setGraphic(null);
}
@@ -654,8 +602,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getPaymentMethod(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getPaymentMethodAsString()));
} else {
setGraphic(null);
}
@@ -679,8 +627,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getDirectionLabel(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getDirectionLabel()));
} else {
setGraphic(null);
}
@@ -704,8 +652,8 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
getStyleClass().removeAll("offer-disabled");
if (item != null) {
- if (model.isNotPublished(item)) getStyleClass().add("offer-disabled");
- setGraphic(new AutoTooltipLabel(model.getMarketLabel(item)));
+ if (item.isNotPublished()) getStyleClass().add("offer-disabled");
+ setGraphic(new AutoTooltipLabel(item.getMarketDescription()));
} else {
setGraphic(null);
}
@@ -785,7 +733,7 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
button.setTooltip(new Tooltip(Res.get("shared.removeOffer")));
setGraphic(button);
}
- button.setOnAction(event -> onRemoveOpenOffer(item.getOpenOffer()));
+ button.setOnAction(event -> onRemoveOpenOffer(item));
} else {
setGraphic(null);
if (button != null) {
@@ -857,7 +805,7 @@ public void updateItem(final OpenOfferListItem item, boolean empty) {
button.setTooltip(new Tooltip(Res.get("openOffer.triggered")));
} else {
button.getGraphic().getStyleClass().remove("warning");
- button.setTooltip(new Tooltip(Res.get("openOffer.triggerPrice", model.getTriggerPrice(item))));
+ button.setTooltip(new Tooltip(Res.get("openOffer.triggerPrice", item.getTriggerPriceAsString())));
}
setGraphic(button);
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java
index e07fe0e2f2f..ce4893a4055 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java
@@ -19,54 +19,31 @@
import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.model.ViewModel;
-import bisq.desktop.util.DisplayUtils;
import bisq.desktop.util.GUIUtil;
-import bisq.core.locale.CurrencyUtil;
-import bisq.core.locale.Res;
-import bisq.core.monetary.Price;
-import bisq.core.offer.Offer;
import bisq.core.offer.OpenOffer;
-import bisq.core.util.FormattingUtils;
import bisq.core.util.PriceUtil;
-import bisq.core.util.VolumeUtil;
-import bisq.core.util.coin.BsqFormatter;
-import bisq.core.util.coin.CoinFormatter;
import bisq.network.p2p.P2PService;
import bisq.common.handlers.ErrorMessageHandler;
import bisq.common.handlers.ResultHandler;
-import org.bitcoinj.core.Coin;
-
import com.google.inject.Inject;
-import javax.inject.Named;
-
-import javafx.collections.ObservableList;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
class OpenOffersViewModel extends ActivatableWithDataModel implements ViewModel {
private final P2PService p2PService;
private final PriceUtil priceUtil;
- private final CoinFormatter btcFormatter;
- private final BsqFormatter bsqFormatter;
@Inject
public OpenOffersViewModel(OpenOffersDataModel dataModel,
P2PService p2PService,
- PriceUtil priceUtil,
- @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
- BsqFormatter bsqFormatter) {
+ PriceUtil priceUtil) {
super(dataModel);
this.p2PService = p2PService;
this.priceUtil = priceUtil;
- this.btcFormatter = btcFormatter;
- this.bsqFormatter = bsqFormatter;
}
@Override
@@ -90,122 +67,7 @@ void onRemoveOpenOffer(OpenOffer openOffer, ResultHandler resultHandler, ErrorMe
dataModel.onRemoveOpenOffer(openOffer, resultHandler, errorMessageHandler);
}
- public ObservableList getList() {
- return dataModel.getList();
- }
-
- String getOfferId(OpenOfferListItem item) {
- return item.getOffer().getShortId();
- }
-
- String getAmount(OpenOfferListItem item) {
- return (item != null) ? DisplayUtils.formatAmount(item.getOffer(), btcFormatter) : "";
- }
-
- String getPrice(OpenOfferListItem item) {
- if ((item == null))
- return "";
-
- Offer offer = item.getOffer();
- Price price = offer.getPrice();
- if (price != null) {
- return FormattingUtils.formatPrice(price);
- } else {
- return Res.get("shared.na");
- }
- }
-
- String getPriceDeviation(OpenOfferListItem item) {
- Offer offer = item.getOffer();
- return priceUtil.getMarketBasedPrice(offer, offer.getMirroredDirection())
- .map(FormattingUtils::formatPercentagePrice)
- .orElse("");
- }
-
- Double getPriceDeviationAsDouble(OpenOfferListItem item) {
- Offer offer = item.getOffer();
- return priceUtil.getMarketBasedPrice(offer, offer.getMirroredDirection()).orElse(0d);
- }
-
- String getVolume(OpenOfferListItem item) {
- return (item != null)
- ? VolumeUtil.formatVolume(item.getOffer(), false, 0) + " " + item.getOffer().getCurrencyCode()
- : "";
- }
-
- String getDirectionLabel(OpenOfferListItem item) {
- if ((item == null))
- return "";
-
- return DisplayUtils.getDirectionWithCode(dataModel.getDirection(item.getOffer()), item.getOffer().getCurrencyCode());
- }
-
- String getMarketLabel(OpenOfferListItem item) {
- if ((item == null))
- return "";
-
- return CurrencyUtil.getCurrencyPair(item.getOffer().getCurrencyCode());
- }
-
- String getPaymentMethod(OpenOfferListItem item) {
- String result = "";
- if (item != null) {
- Offer offer = item.getOffer();
- checkNotNull(offer);
- checkNotNull(offer.getPaymentMethod());
- result = offer.getPaymentMethodNameWithCountryCode();
- }
- return result;
- }
-
- String getDate(OpenOfferListItem item) {
- return DisplayUtils.formatDateTime(item.getOffer().getDate());
- }
-
- boolean isNotPublished(OpenOfferListItem item) {
- return isDeactivated(item) || isBsqSwapOfferHasMissingFunds(item);
- }
-
- boolean isDeactivated(OpenOfferListItem item) {
- return item != null &&
- item.getOpenOffer() != null &&
- item.getOpenOffer().isDeactivated();
- }
-
- boolean isBsqSwapOfferHasMissingFunds(OpenOfferListItem item) {
- return item != null &&
- item.getOpenOffer() != null &&
- item.getOpenOffer().getOffer().isBsqSwapOffer() &&
- item.getOpenOffer().isBsqSwapOfferHasMissingFunds();
- }
-
boolean isBootstrappedOrShowPopup() {
return GUIUtil.isBootstrappedOrShowPopup(p2PService);
}
-
- public boolean hasMakerFee(OpenOffer openOffer) {
- Coin makerFee = openOffer.getOffer().getMakerFee();
- return makerFee.isPositive();
- }
-
- public String getMakerFeeAsString(OpenOffer openOffer) {
- Offer offer = openOffer.getOffer();
- return offer.isCurrencyForMakerFeeBtc() ?
- btcFormatter.formatCoinWithCode(offer.getMakerFee()) :
- bsqFormatter.formatCoinWithCode(offer.getMakerFee());
- }
-
- String getTriggerPrice(OpenOfferListItem item) {
- if ((item == null)) {
- return "";
- }
-
- Offer offer = item.getOffer();
- long triggerPrice = item.getOpenOffer().getTriggerPrice();
- if (!offer.isUseMarketBasedPrice() || triggerPrice <= 0) {
- return Res.get("shared.na");
- } else {
- return PriceUtil.formatMarketPrice(triggerPrice, offer.getCurrencyCode());
- }
- }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java
index 4a3a8d392e2..ca913b7d579 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java
@@ -57,6 +57,7 @@
import bisq.core.trade.protocol.bisq_v1.SellerProtocol;
import bisq.core.user.Preferences;
import bisq.core.util.FormattingUtils;
+import bisq.core.util.coin.CoinFormatter;
import bisq.network.p2p.P2PService;
@@ -71,6 +72,8 @@
import com.google.inject.Inject;
+import javax.inject.Named;
+
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
@@ -109,6 +112,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
public final WalletPasswordWindow walletPasswordWindow;
private final NotificationCenter notificationCenter;
private final OfferUtil offerUtil;
+ private final CoinFormatter btcFormatter;
final ObservableList list = FXCollections.observableArrayList();
private final ListChangeListener tradesListChangeListener;
@@ -145,7 +149,8 @@ public PendingTradesDataModel(TradeManager tradeManager,
Navigation navigation,
WalletPasswordWindow walletPasswordWindow,
NotificationCenter notificationCenter,
- OfferUtil offerUtil) {
+ OfferUtil offerUtil,
+ @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter) {
this.tradeManager = tradeManager;
this.btcWalletService = btcWalletService;
this.pubKeyRing = pubKeyRing;
@@ -161,6 +166,7 @@ public PendingTradesDataModel(TradeManager tradeManager,
this.walletPasswordWindow = walletPasswordWindow;
this.notificationCenter = notificationCenter;
this.offerUtil = offerUtil;
+ this.btcFormatter = formatter;
tradesListChangeListener = change -> onListChanged();
notificationCenter.setSelectItemByTradeIdConsumer(this::selectItemByTradeId);
@@ -381,7 +387,7 @@ public String getReference() {
private void onListChanged() {
list.clear();
list.addAll(tradeManager.getObservableList().stream()
- .map(PendingTradesListItem::new)
+ .map(trade -> new PendingTradesListItem(trade, btcFormatter))
.collect(Collectors.toList()));
// we sort by date, earliest first
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesListItem.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesListItem.java
index e63383786ae..ff4bc15d7db 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesListItem.java
@@ -17,39 +17,69 @@
package bisq.desktop.main.portfolio.pendingtrades;
-import bisq.core.monetary.Price;
-import bisq.core.monetary.Volume;
+import bisq.desktop.util.filtering.FilterableListItem;
+
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.util.FormattingUtils;
+import bisq.core.util.coin.CoinFormatter;
+
+import org.apache.commons.lang3.StringUtils;
-import org.bitcoinj.core.Coin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import javafx.beans.property.ReadOnlyObjectProperty;
+import static bisq.core.locale.CurrencyUtil.getCurrencyPair;
/**
* We could remove that wrapper if it is not needed for additional UI only fields.
*/
-public class PendingTradesListItem {
-
+public class PendingTradesListItem implements FilterableListItem {
+ public static final Logger log = LoggerFactory.getLogger(PendingTradesListItem.class);
+ private final CoinFormatter btcFormatter;
private final Trade trade;
- public PendingTradesListItem(Trade trade) {
+ public PendingTradesListItem(Trade trade, CoinFormatter btcFormatter) {
this.trade = trade;
+ this.btcFormatter = btcFormatter;
}
public Trade getTrade() {
return trade;
}
- public ReadOnlyObjectProperty tradeAmountProperty() {
- return trade.amountProperty();
+ public String getPriceAsString() {
+ return FormattingUtils.formatPrice(trade.getPrice());
}
- public ReadOnlyObjectProperty tradeVolumeProperty() {
- return trade.volumeProperty();
+ public String getAmountAsString() {
+ return btcFormatter.formatCoin(trade.getAmount());
}
- public Price getPrice() {
- return trade.getPrice();
+ public String getPaymentMethod() {
+ return trade.getOffer().getPaymentMethodNameWithCountryCode();
}
+ public String getMarketDescription() {
+ return getCurrencyPair(trade.getOffer().getCurrencyCode());
+ }
+
+ @Override
+ public boolean match(String filterString) {
+ if (filterString.isEmpty()) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getTrade().getId(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getAmountAsString(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getPaymentMethod(), filterString)) {
+ return true;
+ }
+ if (StringUtils.containsIgnoreCase(getMarketDescription(), filterString)) {
+ return true;
+ }
+ return StringUtils.containsIgnoreCase(getPriceAsString(), filterString);
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.fxml b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.fxml
index b8f27271572..15e97dc48f3 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.fxml
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.fxml
@@ -21,12 +21,13 @@
+
-
+
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java
index 7fad26cda3f..3c136ed9f37 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java
@@ -23,6 +23,7 @@
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.PeerInfoIconTrading;
+import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.MainView;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
@@ -42,9 +43,7 @@
import bisq.core.trade.model.bisq_v1.Contract;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.core.user.Preferences;
-import bisq.core.util.FormattingUtils;
import bisq.core.util.VolumeUtil;
-import bisq.core.util.coin.CoinFormatter;
import bisq.network.p2p.NodeAddress;
@@ -102,6 +101,7 @@
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
@@ -119,16 +119,18 @@ public interface ChatCallback {
private final TradeDetailsWindow tradeDetailsWindow;
private final Navigation navigation;
private final KeyRing keyRing;
- private final CoinFormatter formatter;
private final PrivateNotificationManager privateNotificationManager;
private final boolean useDevPrivilegeKeys;
private final boolean useDevModeHeader;
private final Preferences preferences;
@FXML
+ FilterBox filterBox;
+ @FXML
TableView tableView;
@FXML
TableColumn priceColumn, volumeColumn, amountColumn, avatarColumn,
marketColumn, roleColumn, paymentMethodColumn, tradeIdColumn, dateColumn, chatColumn, moveTradeToFailedColumn;
+ private FilteredList filteredList;
private SortedList sortedList;
private TradeSubView selectedSubView;
private EventHandler keyEventEventHandler;
@@ -161,7 +163,6 @@ public PendingTradesView(PendingTradesViewModel model,
TradeDetailsWindow tradeDetailsWindow,
Navigation navigation,
KeyRing keyRing,
- @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
PrivateNotificationManager privateNotificationManager,
Preferences preferences,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys,
@@ -170,7 +171,6 @@ public PendingTradesView(PendingTradesViewModel model,
this.tradeDetailsWindow = tradeDetailsWindow;
this.navigation = navigation;
this.keyRing = keyRing;
- this.formatter = formatter;
this.privateNotificationManager = privateNotificationManager;
this.preferences = preferences;
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
@@ -211,14 +211,14 @@ public void initialize() {
dateColumn.setComparator(Comparator.comparing(o -> o.getTrade().getDate()));
volumeColumn.setComparator(Comparator.comparing(o -> o.getTrade().getVolume(), Comparator.nullsFirst(Comparator.naturalOrder())));
amountColumn.setComparator(Comparator.comparing(o -> o.getTrade().getAmount(), Comparator.nullsFirst(Comparator.naturalOrder())));
- priceColumn.setComparator(Comparator.comparing(item -> FormattingUtils.formatPrice(item.getPrice())));
+ priceColumn.setComparator(Comparator.comparing(PendingTradesListItem::getPriceAsString));
paymentMethodColumn.setComparator(Comparator.comparing(
item -> item.getTrade().getOffer() != null ?
Res.get(item.getTrade().getOffer().getPaymentMethod().getId()) :
null,
Comparator.nullsFirst(Comparator.naturalOrder())));
- marketColumn.setComparator(Comparator.comparing(model::getMarketLabel));
+ marketColumn.setComparator(Comparator.comparing(PendingTradesListItem::getMarketDescription));
roleColumn.setComparator(Comparator.comparing(model::getMyRole));
avatarColumn.setComparator(Comparator.comparing(
o -> model.getNumPastTrades(o.getTrade()),
@@ -281,10 +281,14 @@ public void initialize() {
@Override
protected void activate() {
ObservableList list = model.dataModel.list;
- sortedList = new SortedList<>(list);
+ filteredList = new FilteredList<>(list);
+ sortedList = new SortedList<>(filteredList);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
tableView.setItems(sortedList);
+ filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
+ filterBox.activate();
+
updateMoveTradeToFailedColumnState();
scene = root.getScene();
@@ -303,10 +307,10 @@ protected void activate() {
selectedSubView.setMinHeight(440);
VBox.setVgrow(selectedSubView, Priority.ALWAYS);
- if (root.getChildren().size() == 1)
+ if (root.getChildren().size() == 2)
root.getChildren().add(selectedSubView);
- else if (root.getChildren().size() == 2)
- root.getChildren().set(1, selectedSubView);
+ else if (root.getChildren().size() == 3)
+ root.getChildren().set(2, selectedSubView);
// create and register a callback so we can be notified when the subview
// wants to open the chat window
@@ -340,6 +344,7 @@ else if (root.getChildren().size() == 2)
@Override
protected void deactivate() {
+ filterBox.deactivate();
sortedList.comparatorProperty().unbind();
selectedItemSubscription.unsubscribe();
selectedTableItemSubscription.unsubscribe();
@@ -683,7 +688,7 @@ public TableCell call(
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
- setGraphic(new AutoTooltipLabel(formatter.formatCoin(item.getTrade().getAmount())));
+ setGraphic(new AutoTooltipLabel(item.getAmountAsString()));
else
setGraphic(null);
}
@@ -704,7 +709,7 @@ public TableCell call(
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
- setGraphic(new AutoTooltipLabel(FormattingUtils.formatPrice(item.getPrice())));
+ setGraphic(new AutoTooltipLabel(item.getPriceAsString()));
else
setGraphic(null);
}
@@ -751,7 +756,7 @@ public TableCell call(
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
- setGraphic(new AutoTooltipLabel(model.getPaymentMethod(item)));
+ setGraphic(new AutoTooltipLabel(item.getPaymentMethod()));
else
setGraphic(null);
}
@@ -771,7 +776,12 @@ public TableCell call(
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
- setGraphic(new AutoTooltipLabel(model.getMarketLabel(item)));
+
+ if (item != null && !empty) {
+ setGraphic(new AutoTooltipLabel(item.getMarketDescription()));
+ } else {
+ setGraphic(null);
+ }
}
};
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
index 06de2be4eba..6237fa14509 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
@@ -245,16 +245,6 @@ ReadOnlyObjectProperty