Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Clean up Altcoin payment accounts #1835

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -19,22 +19,23 @@

import bisq.common.UserThread;

import javafx.scene.control.ComboBox;
import com.jfoenix.controls.JFXComboBox;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;

public class SearchComboBox<T> extends ComboBox<T> {
public class SearchComboBox<T> extends JFXComboBox<T> {
@SuppressWarnings("CanBeFinal")
private FilteredList<T> filteredList;

public SearchComboBox() {
this(FXCollections.<T>observableArrayList());
this(FXCollections.observableArrayList());
}

public SearchComboBox(final ObservableList<T> items) {
private SearchComboBox(final ObservableList<T> items) {
super(new FilteredList<>(items));

filteredList = new FilteredList<>(items);
setEditable(true);

Expand All @@ -43,8 +44,7 @@ public SearchComboBox(final ObservableList<T> items) {
setItems(filteredList);
});
getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
if (!filteredList.stream().filter(item -> getConverter().toString(item).equals(newValue)).
findAny().isPresent()) {
if (filteredList.stream().noneMatch(item -> getConverter().toString(item).equals(newValue))) {
UserThread.execute(() -> {
filteredList.setPredicate(item -> newValue.isEmpty() ||
getConverter().toString(item).toLowerCase().contains(newValue.toLowerCase()));
Expand Down
Expand Up @@ -38,7 +38,6 @@

import org.apache.commons.lang3.StringUtils;

import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
Expand All @@ -52,6 +51,7 @@

import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
import static bisq.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon;
import static bisq.desktop.util.GUIUtil.getComboBoxButtonCell;

public class CryptoCurrencyForm extends PaymentMethodForm {
private final CryptoCurrencyAccount cryptoCurrencyAccount;
Expand All @@ -60,8 +60,6 @@ public class CryptoCurrencyForm extends PaymentMethodForm {

private InputTextField addressInputTextField;

private ComboBox<TradeCurrency> currencyComboBox;

public static int addFormForBuyer(GridPane gridPane,
int gridRow,
PaymentAccountPayload paymentAccountPayload,
Expand Down Expand Up @@ -158,6 +156,12 @@ protected void addTradeCurrencyComboBox() {
currencyComboBox = FormBuilder.<TradeCurrency>addLabelSearchComboBox(gridPane, ++gridRow, Res.get("payment.altcoin"),
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
currencyComboBox.setPromptText(Res.get("payment.select.altcoin"));
currencyComboBox.setButtonCell(getComboBoxButtonCell(Res.get("payment.select.altcoin"), currencyComboBox));

currencyComboBox.getEditor().focusedProperty().addListener(observable -> {
currencyComboBox.setPromptText("");
});

currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getWhiteListedSortedCryptoCurrencies(assetService)));
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 15));
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
Expand All @@ -175,6 +179,10 @@ public TradeCurrency fromString(String s) {
}
});
currencyComboBox.setOnAction(e -> {

addressInputTextField.resetValidation();
addressInputTextField.validate();

paymentAccount.setSingleTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem());
updateFromInputs();
});
Expand Down
Expand Up @@ -309,7 +309,7 @@ public int getGridRow() {
}

public int getRowSpan() {
return gridRow - gridRowFrom + 1;
return gridRow - gridRowFrom + 2;
}

public PaymentAccount getPaymentAccount() {
Expand Down
@@ -0,0 +1,133 @@
package bisq.desktop.main.account.content;

import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.util.ImageUtil;

import bisq.core.locale.Res;
import bisq.core.payment.PaymentAccount;

import bisq.common.UserThread;

import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;

import javafx.beans.value.ChangeListener;

import javafx.collections.ObservableList;

import javafx.util.Callback;

import java.util.concurrent.TimeUnit;

public abstract class PaymentAccountsView<R extends Node, M extends ActivatableWithDataModel> extends ActivatableViewAndModel<R, M> {

protected ListView<PaymentAccount> paymentAccountsListView;
protected ChangeListener<PaymentAccount> paymentAccountChangeListener;
protected Button addAccountButton, exportButton, importButton;

public PaymentAccountsView(M model) {
super(model);
}

@Override
public void initialize() {
buildForm();
paymentAccountChangeListener = (observable, oldValue, newValue) -> {
if (newValue != null)
onSelectAccount(newValue);
};
Label placeholder = new AutoTooltipLabel(Res.get("shared.noAccountsSetupYet"));
placeholder.setWrapText(true);
paymentAccountsListView.setPlaceholder(placeholder);
}

@Override
protected void activate() {
paymentAccountsListView.setItems(getPaymentAccounts());
paymentAccountsListView.getSelectionModel().selectedItemProperty().addListener(paymentAccountChangeListener);
addAccountButton.setOnAction(event -> addNewAccount());
exportButton.setOnAction(event -> exportAccounts());
importButton.setOnAction(event -> importAccounts());
}

@Override
protected void deactivate() {
paymentAccountsListView.getSelectionModel().selectedItemProperty().removeListener(paymentAccountChangeListener);
addAccountButton.setOnAction(null);
exportButton.setOnAction(null);
importButton.setOnAction(null);
}

protected void onDeleteAccount(PaymentAccount paymentAccount) {
new Popup<>().warning(Res.get("shared.askConfirmDeleteAccount"))
.actionButtonText(Res.get("shared.yes"))
.onAction(() -> {
boolean isPaymentAccountUsed = deleteAccountFromModel(paymentAccount);
if (!isPaymentAccountUsed)
removeSelectAccountForm();
else
UserThread.runAfter(() -> new Popup<>().warning(
Res.get("shared.cannotDeleteAccount"))
.show(), 100, TimeUnit.MILLISECONDS);
})
.closeButtonText(Res.get("shared.cancel"))
.show();
}

protected void setPaymentAccountsCellFactory() {
paymentAccountsListView.setCellFactory(new Callback<ListView<PaymentAccount>, ListCell<PaymentAccount>>() {
@Override
public ListCell<PaymentAccount> call(ListView<PaymentAccount> list) {
return new ListCell<PaymentAccount>() {
final Label label = new AutoTooltipLabel();
final ImageView icon = ImageUtil.getImageViewById(ImageUtil.REMOVE_ICON);
final Button removeButton = new AutoTooltipButton("", icon);
final AnchorPane pane = new AnchorPane(label, removeButton);

{
label.setLayoutY(5);
removeButton.setId("icon-button");
AnchorPane.setRightAnchor(removeButton, 0d);
}

@Override
public void updateItem(final PaymentAccount item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
label.setText(item.getAccountName());
removeButton.setOnAction(e -> onDeleteAccount(item));
setGraphic(pane);
} else {
setGraphic(null);
}
}
};
}
});
}

protected abstract void removeSelectAccountForm();

protected abstract boolean deleteAccountFromModel(PaymentAccount paymentAccount);

protected abstract void importAccounts();

protected abstract void exportAccounts();

protected abstract void addNewAccount();

protected abstract ObservableList<PaymentAccount> getPaymentAccounts();

protected abstract void buildForm();

protected abstract void onSelectAccount(PaymentAccount paymentAccount);
}