mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 10:22:18 +01:00
Merge branch 'master' into refactoring-mainviewmodel
This commit is contained in:
commit
1d8a6fe24e
@ -1316,6 +1316,13 @@ textfield */
|
||||
-fx-font-size: 0.846em;
|
||||
}
|
||||
|
||||
.my-message-header {
|
||||
-fx-text-fill: -fx-accent;
|
||||
-fx-fill: -fx-accent;
|
||||
-fx-font-size: 0.846em;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* *
|
||||
* DAO *
|
||||
|
78
src/main/java/bisq/desktop/components/TextFieldWithIcon.java
Normal file
78
src/main/java/bisq/desktop/components/TextFieldWithIcon.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.components;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class TextFieldWithIcon extends AnchorPane {
|
||||
public static final Logger log = LoggerFactory.getLogger(TextFieldWithIcon.class);
|
||||
@Getter
|
||||
private final Label iconLabel;
|
||||
private final TextField textField;
|
||||
private final Label dummyTextField;
|
||||
|
||||
public TextFieldWithIcon() {
|
||||
textField = new TextField();
|
||||
textField.setEditable(false);
|
||||
textField.setMouseTransparent(true);
|
||||
textField.setFocusTraversable(false);
|
||||
setLeftAnchor(textField, 0d);
|
||||
setRightAnchor(textField, 0d);
|
||||
|
||||
dummyTextField = new Label();
|
||||
dummyTextField.setWrapText(true);
|
||||
dummyTextField.setAlignment(Pos.CENTER_LEFT);
|
||||
dummyTextField.setTextAlignment(TextAlignment.LEFT);
|
||||
dummyTextField.setMouseTransparent(true);
|
||||
dummyTextField.setFocusTraversable(false);
|
||||
setLeftAnchor(dummyTextField, 0d);
|
||||
dummyTextField.setVisible(false);
|
||||
|
||||
iconLabel = new Label();
|
||||
iconLabel.setLayoutX(0);
|
||||
iconLabel.setLayoutY(3);
|
||||
|
||||
dummyTextField.widthProperty().addListener((observable, oldValue, newValue) -> {
|
||||
iconLabel.setLayoutX(dummyTextField.widthProperty().get() + 20);
|
||||
});
|
||||
|
||||
getChildren().addAll(textField, dummyTextField, iconLabel);
|
||||
}
|
||||
|
||||
public void setIcon(AwesomeIcon iconLabel) {
|
||||
AwesomeDude.setIcon(this.iconLabel, iconLabel);
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
textField.setText(text);
|
||||
dummyTextField.setText(text);
|
||||
}
|
||||
}
|
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.components.paymentmethods;
|
||||
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.util.BSFormatter;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.validation.EmailValidator;
|
||||
|
||||
import bisq.core.locale.BankUtil;
|
||||
import bisq.core.locale.Country;
|
||||
import bisq.core.locale.CountryUtil;
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.locale.Region;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.payment.AccountAgeWitnessService;
|
||||
import bisq.core.payment.MoneyGramAccount;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.payload.MoneyGramAccountPayload;
|
||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
||||
import bisq.core.util.validation.InputValidator;
|
||||
|
||||
import bisq.common.util.Tuple2;
|
||||
import bisq.common.util.Tuple3;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.FlowPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.VPos;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addLabel;
|
||||
import static bisq.desktop.util.FormBuilder.addLabelTextFieldWithCopyIcon;
|
||||
|
||||
@Slf4j
|
||||
public class MoneyGramForm extends PaymentMethodForm {
|
||||
|
||||
public static int addFormForBuyer(GridPane gridPane, int gridRow,
|
||||
PaymentAccountPayload paymentAccountPayload) {
|
||||
final MoneyGramAccountPayload payload = (MoneyGramAccountPayload) paymentAccountPayload;
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.getWithCol("payment.account.fullName"),
|
||||
payload.getHolderName());
|
||||
FormBuilder.addLabelTextFieldWithCopyIcon(gridPane, ++gridRow,
|
||||
Res.getWithCol("payment.bank.country"),
|
||||
CountryUtil.getNameAndCode(((MoneyGramAccountPayload) paymentAccountPayload).getCountryCode()));
|
||||
if (BankUtil.isStateRequired(payload.getCountryCode()))
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.account.state"),
|
||||
payload.getState());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.email"),
|
||||
payload.getEmail());
|
||||
|
||||
return gridRow;
|
||||
}
|
||||
|
||||
protected final MoneyGramAccountPayload moneyGramAccountPayload;
|
||||
protected InputTextField holderNameInputTextField, emailInputTextField, stateInputTextField;
|
||||
private Label stateLabel;
|
||||
private final EmailValidator emailValidator;
|
||||
|
||||
public MoneyGramForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator,
|
||||
GridPane gridPane, int gridRow, BSFormatter formatter) {
|
||||
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
|
||||
this.moneyGramAccountPayload = (MoneyGramAccountPayload) paymentAccount.paymentAccountPayload;
|
||||
|
||||
emailValidator = new EmailValidator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFormForDisplayAccount() {
|
||||
gridRowFrom = gridRow;
|
||||
final Country country = getMoneyGramPaymentAccount().getCountry();
|
||||
FormBuilder.addLabelTextField(gridPane, gridRow, Res.get("payment.account.name"), paymentAccount.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.paymentMethod"),
|
||||
Res.get(paymentAccount.getPaymentMethod().getId()));
|
||||
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.get("payment.country"), country != null ? country.name : "");
|
||||
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.getWithCol("payment.account.fullName"),
|
||||
moneyGramAccountPayload.getHolderName());
|
||||
if (BankUtil.isStateRequired(moneyGramAccountPayload.getCountryCode()))
|
||||
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.get("payment.account.state"),
|
||||
moneyGramAccountPayload.getState()).second.setMouseTransparent(false);
|
||||
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.get("payment.email"),
|
||||
moneyGramAccountPayload.getEmail());
|
||||
addLimitations();
|
||||
addCurrenciesGrid(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFormForAddAccount() {
|
||||
gridRowFrom = gridRow + 1;
|
||||
|
||||
Tuple3<Label, ComboBox, ComboBox> tuple3 = FormBuilder.addLabelComboBoxComboBox(gridPane, ++gridRow, Res.get("payment.country"));
|
||||
|
||||
//noinspection unchecked,unchecked,unchecked
|
||||
ComboBox<Region> regionComboBox = tuple3.second;
|
||||
regionComboBox.setPromptText(Res.get("payment.select.region"));
|
||||
regionComboBox.setConverter(new StringConverter<Region>() {
|
||||
@Override
|
||||
public String toString(Region region) {
|
||||
return region.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region fromString(String s) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
regionComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllRegions()));
|
||||
|
||||
//noinspection unchecked,unchecked,unchecked
|
||||
ComboBox<Country> countryComboBox = tuple3.third;
|
||||
countryComboBox.setVisibleRowCount(15);
|
||||
countryComboBox.setDisable(true);
|
||||
countryComboBox.setPromptText(Res.get("payment.select.country"));
|
||||
countryComboBox.setConverter(new StringConverter<Country>() {
|
||||
@Override
|
||||
public String toString(Country country) {
|
||||
return country.name + " (" + country.code + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Country fromString(String s) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
countryComboBox.setOnAction(e -> {
|
||||
Country selectedItem = countryComboBox.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null) {
|
||||
getMoneyGramPaymentAccount().setCountry(selectedItem);
|
||||
updateFromInputs();
|
||||
applyIsStateRequired();
|
||||
stateInputTextField.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
regionComboBox.setOnAction(e -> {
|
||||
Region selectedItem = regionComboBox.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null) {
|
||||
countryComboBox.setDisable(false);
|
||||
countryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesForRegion(selectedItem)));
|
||||
}
|
||||
});
|
||||
|
||||
holderNameInputTextField = FormBuilder.addLabelInputTextField(gridPane,
|
||||
++gridRow, Res.getWithCol("payment.account.fullName")).second;
|
||||
holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
moneyGramAccountPayload.setHolderName(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
holderNameInputTextField.setValidator(inputValidator);
|
||||
|
||||
final Tuple2<Label, InputTextField> tuple2 = FormBuilder.addLabelInputTextField(gridPane, ++gridRow, Res.get("payment.account.state"));
|
||||
stateLabel = tuple2.first;
|
||||
stateInputTextField = tuple2.second;
|
||||
stateInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
moneyGramAccountPayload.setState(newValue);
|
||||
updateFromInputs();
|
||||
|
||||
});
|
||||
applyIsStateRequired();
|
||||
|
||||
emailInputTextField = FormBuilder.addLabelInputTextField(gridPane, ++gridRow, Res.get("payment.email")).second;
|
||||
emailInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
moneyGramAccountPayload.setEmail(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
emailInputTextField.setValidator(emailValidator);
|
||||
|
||||
addCurrenciesGrid(true);
|
||||
addLimitations();
|
||||
addAccountNameTextFieldWithAutoFillCheckBox();
|
||||
|
||||
updateFromInputs();
|
||||
}
|
||||
|
||||
private void addCurrenciesGrid(boolean isEditable) {
|
||||
Label label = addLabel(gridPane, ++gridRow, Res.get("payment.supportedCurrencies"), 0);
|
||||
GridPane.setValignment(label, VPos.TOP);
|
||||
FlowPane flowPane = new FlowPane();
|
||||
flowPane.setPadding(new Insets(10, 10, 10, 10));
|
||||
flowPane.setVgap(10);
|
||||
flowPane.setHgap(10);
|
||||
|
||||
if (isEditable)
|
||||
flowPane.setId("flow-pane-checkboxes-bg");
|
||||
else
|
||||
flowPane.setId("flow-pane-checkboxes-non-editable-bg");
|
||||
|
||||
CurrencyUtil.getAllMoneyGramCurrencies().forEach(e -> {
|
||||
CheckBox checkBox = new CheckBox(e.getCode());
|
||||
checkBox.setMouseTransparent(!isEditable);
|
||||
checkBox.setSelected(paymentAccount.getTradeCurrencies().contains(e));
|
||||
checkBox.setMinWidth(60);
|
||||
checkBox.setMaxWidth(checkBox.getMinWidth());
|
||||
checkBox.setTooltip(new Tooltip(e.getName()));
|
||||
checkBox.setOnAction(event -> {
|
||||
if (checkBox.isSelected())
|
||||
paymentAccount.addCurrency(e);
|
||||
else
|
||||
paymentAccount.removeCurrency(e);
|
||||
|
||||
updateAllInputsValid();
|
||||
});
|
||||
flowPane.getChildren().add(checkBox);
|
||||
});
|
||||
|
||||
GridPane.setRowIndex(flowPane, gridRow);
|
||||
GridPane.setColumnIndex(flowPane, 1);
|
||||
gridPane.getChildren().add(flowPane);
|
||||
}
|
||||
|
||||
private void applyIsStateRequired() {
|
||||
final boolean stateRequired = BankUtil.isStateRequired(moneyGramAccountPayload.getCountryCode());
|
||||
stateLabel.setManaged(stateRequired);
|
||||
stateLabel.setVisible(stateRequired);
|
||||
stateInputTextField.setManaged(stateRequired);
|
||||
stateInputTextField.setVisible(stateRequired);
|
||||
}
|
||||
|
||||
private MoneyGramAccount getMoneyGramPaymentAccount() {
|
||||
return (MoneyGramAccount) this.paymentAccount;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void autoFillNameTextField() {
|
||||
if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) {
|
||||
accountNameTextField.setText(Res.get(paymentAccount.getPaymentMethod().getId())
|
||||
.concat(": ")
|
||||
.concat(StringUtils.abbreviate(holderNameInputTextField.getText(), 9)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAllInputsValid() {
|
||||
boolean result = isAccountNameValid()
|
||||
&& getMoneyGramPaymentAccount().getCountry() != null
|
||||
&& inputValidator.validate(moneyGramAccountPayload.getHolderName()).isValid
|
||||
&& emailValidator.validate(moneyGramAccountPayload.getEmail()).isValid
|
||||
&& paymentAccount.getTradeCurrencies().size() > 0;
|
||||
allInputsValid.set(result);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ import bisq.desktop.components.paymentmethods.ClearXchangeForm;
|
||||
import bisq.desktop.components.paymentmethods.FasterPaymentsForm;
|
||||
import bisq.desktop.components.paymentmethods.InteracETransferForm;
|
||||
import bisq.desktop.components.paymentmethods.MoneyBeamForm;
|
||||
import bisq.desktop.components.paymentmethods.MoneyGramForm;
|
||||
import bisq.desktop.components.paymentmethods.NationalBankForm;
|
||||
import bisq.desktop.components.paymentmethods.OKPayForm;
|
||||
import bisq.desktop.components.paymentmethods.PaymentMethodForm;
|
||||
@ -72,6 +73,7 @@ import bisq.core.app.BisqEnvironment;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.payment.AccountAgeWitnessService;
|
||||
import bisq.core.payment.ClearXchangeAccount;
|
||||
import bisq.core.payment.MoneyGramAccount;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.PaymentAccountFactory;
|
||||
import bisq.core.payment.WesternUnionAccount;
|
||||
@ -252,6 +254,13 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
|
||||
.actionButtonText(Res.get("shared.iUnderstand"))
|
||||
.onAction(() -> doSaveNewAccount(paymentAccount))
|
||||
.show();
|
||||
} else if (paymentAccount instanceof MoneyGramAccount) {
|
||||
new Popup<>().information(Res.get("payment.moneyGram.info"))
|
||||
.width(700)
|
||||
.closeButtonText(Res.get("shared.cancel"))
|
||||
.actionButtonText(Res.get("shared.iUnderstand"))
|
||||
.onAction(() -> doSaveNewAccount(paymentAccount))
|
||||
.show();
|
||||
} else {
|
||||
doSaveNewAccount(paymentAccount);
|
||||
}
|
||||
@ -467,6 +476,8 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
|
||||
return new InteracETransferForm(paymentAccount, accountAgeWitnessService, interacETransferValidator, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.US_POSTAL_MONEY_ORDER_ID:
|
||||
return new USPostalMoneyOrderForm(paymentAccount, accountAgeWitnessService, usPostalMoneyOrderValidator, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.MONEY_GRAM_ID:
|
||||
return new MoneyGramForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.WESTERN_UNION_ID:
|
||||
return new WesternUnionForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.CASH_DEPOSIT_ID:
|
||||
|
@ -157,8 +157,8 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
private VBox messagesInputBox;
|
||||
private BusyAnimation sendMsgBusyAnimation;
|
||||
private Label sendMsgInfoLabel;
|
||||
private ChangeListener<Boolean> arrivedPropertyListener;
|
||||
private ChangeListener<Boolean> storedInMailboxPropertyListener;
|
||||
private ChangeListener<Boolean> storedInMailboxPropertyListener, arrivedPropertyListener;
|
||||
private ChangeListener<String> sendMessageErrorPropertyListener;
|
||||
@Nullable
|
||||
private DisputeCommunicationMessage disputeCommunicationMessage;
|
||||
private ListChangeListener<DisputeCommunicationMessage> disputeDirectMessageListListener;
|
||||
@ -488,6 +488,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
if (disputeCommunicationMessage != null) {
|
||||
disputeCommunicationMessage.arrivedProperty().removeListener(arrivedPropertyListener);
|
||||
disputeCommunicationMessage.storedInMailboxProperty().removeListener(storedInMailboxPropertyListener);
|
||||
disputeCommunicationMessage.sendMessageErrorProperty().removeListener(sendMessageErrorPropertyListener);
|
||||
}
|
||||
|
||||
disputeCommunicationMessage = disputeManager.sendDisputeDirectMessage(dispute, inputText, new ArrayList<>(tempAttachments));
|
||||
@ -510,8 +511,6 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
hideSendMsgInfo(timer);
|
||||
}
|
||||
};
|
||||
if (disputeCommunicationMessage != null && disputeCommunicationMessage.arrivedProperty() != null)
|
||||
disputeCommunicationMessage.arrivedProperty().addListener(arrivedPropertyListener);
|
||||
storedInMailboxPropertyListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
sendMsgInfoLabel.setVisible(true);
|
||||
@ -520,8 +519,19 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
hideSendMsgInfo(timer);
|
||||
}
|
||||
};
|
||||
if (disputeCommunicationMessage != null)
|
||||
sendMessageErrorPropertyListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
sendMsgInfoLabel.setVisible(true);
|
||||
sendMsgInfoLabel.setManaged(true);
|
||||
sendMsgInfoLabel.setText(Res.get("support.sendMessageError", newValue));
|
||||
hideSendMsgInfo(timer);
|
||||
}
|
||||
};
|
||||
if (disputeCommunicationMessage != null) {
|
||||
disputeCommunicationMessage.arrivedProperty().addListener(arrivedPropertyListener);
|
||||
disputeCommunicationMessage.storedInMailboxProperty().addListener(storedInMailboxPropertyListener);
|
||||
disputeCommunicationMessage.sendMessageErrorProperty().addListener(sendMessageErrorPropertyListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideSendMsgInfo(Timer timer) {
|
||||
@ -734,7 +744,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
@Override
|
||||
public ListCell<DisputeCommunicationMessage> call(ListView<DisputeCommunicationMessage> list) {
|
||||
return new ListCell<DisputeCommunicationMessage>() {
|
||||
public ChangeListener<Boolean> sendMsgBusyAnimationListener;
|
||||
ChangeListener<Boolean> sendMsgBusyAnimationListener;
|
||||
final Pane bg = new Pane();
|
||||
final ImageView arrow = new ImageView();
|
||||
final Label headerLabel = new AutoTooltipLabel();
|
||||
@ -743,6 +753,8 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
final HBox attachmentsBox = new HBox();
|
||||
final AnchorPane messageAnchorPane = new AnchorPane();
|
||||
final Label statusIcon = new Label();
|
||||
final Label statusInfoLabel = new Label();
|
||||
final HBox statusHBox = new HBox();
|
||||
final double arrowWidth = 15d;
|
||||
final double attachmentsBoxHeight = 20d;
|
||||
final double border = 10d;
|
||||
@ -756,25 +768,26 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
headerLabel.setTextAlignment(TextAlignment.CENTER);
|
||||
attachmentsBox.setSpacing(5);
|
||||
statusIcon.getStyleClass().add("small-text");
|
||||
statusInfoLabel.getStyleClass().add("small-text");
|
||||
statusInfoLabel.setPadding(new Insets(3, 0, 0, 0));
|
||||
copyIcon.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
messageAnchorPane.getChildren().addAll(bg, arrow, headerLabel, messageLabel, copyIcon, attachmentsBox, statusIcon);
|
||||
messageLabel.setOnMouseClicked(event -> {
|
||||
if (2 > event.getClickCount()) {
|
||||
return;
|
||||
}
|
||||
GUIUtil.showSelectableTextModal(headerLabel.getText(), messageLabel.getText());
|
||||
});
|
||||
statusHBox.setSpacing(5);
|
||||
statusHBox.getChildren().addAll(statusIcon, statusInfoLabel);
|
||||
messageAnchorPane.getChildren().addAll(bg, arrow, headerLabel, messageLabel, copyIcon, attachmentsBox, statusHBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final DisputeCommunicationMessage item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null && !empty) {
|
||||
public void updateItem(final DisputeCommunicationMessage message, boolean empty) {
|
||||
super.updateItem(message, empty);
|
||||
if (message != null && !empty) {
|
||||
copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(messageLabel.getText()));
|
||||
messageLabel.setOnMouseClicked(event -> {
|
||||
if (2 > event.getClickCount()) {
|
||||
return;
|
||||
}
|
||||
GUIUtil.showSelectableTextModal(headerLabel.getText(), messageLabel.getText());
|
||||
});
|
||||
|
||||
/* messageAnchorPane.prefWidthProperty().bind(EasyBind.map(messageListView.widthProperty(),
|
||||
w -> (double) w - padding - GUIUtil.getScrollbarWidth(messageListView)));*/
|
||||
if (!messageAnchorPane.prefWidthProperty().isBound())
|
||||
messageAnchorPane.prefWidthProperty()
|
||||
.bind(messageListView.widthProperty().subtract(padding + GUIUtil.getScrollbarWidth(messageListView)));
|
||||
@ -787,25 +800,27 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
AnchorPane.setTopAnchor(copyIcon, 25d);
|
||||
AnchorPane.setBottomAnchor(attachmentsBox, bottomBorder + 10);
|
||||
|
||||
boolean senderIsTrader = item.isSenderIsTrader();
|
||||
boolean senderIsTrader = message.isSenderIsTrader();
|
||||
boolean isMyMsg = isTrader ? senderIsTrader : !senderIsTrader;
|
||||
|
||||
arrow.setVisible(!item.isSystemMessage());
|
||||
arrow.setManaged(!item.isSystemMessage());
|
||||
statusIcon.setVisible(false);
|
||||
arrow.setVisible(!message.isSystemMessage());
|
||||
arrow.setManaged(!message.isSystemMessage());
|
||||
statusHBox.setVisible(false);
|
||||
|
||||
headerLabel.getStyleClass().removeAll("message-header", "success-text",
|
||||
headerLabel.getStyleClass().removeAll("message-header", "my-message-header", "success-text",
|
||||
"highlight-static");
|
||||
messageLabel.getStyleClass().removeAll("my-message", "message");
|
||||
copyIcon.getStyleClass().removeAll("my-message", "message");
|
||||
|
||||
if (item.isSystemMessage()) {
|
||||
if (message.isSystemMessage()) {
|
||||
headerLabel.getStyleClass().addAll("message-header", "success-text");
|
||||
bg.setId("message-bubble-green");
|
||||
messageLabel.getStyleClass().add("my-message");
|
||||
copyIcon.getStyleClass().add("my-message");
|
||||
message.addWeakMessageStateListener(() -> updateMsgState(message));
|
||||
updateMsgState(message);
|
||||
} else if (isMyMsg) {
|
||||
headerLabel.getStyleClass().add("highlight-static");
|
||||
headerLabel.getStyleClass().add("my-message-header");
|
||||
bg.setId("message-bubble-blue");
|
||||
messageLabel.getStyleClass().add("my-message");
|
||||
copyIcon.getStyleClass().add("my-message");
|
||||
@ -818,22 +833,13 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
sendMsgBusyAnimation.isRunningProperty().removeListener(sendMsgBusyAnimationListener);
|
||||
|
||||
sendMsgBusyAnimationListener = (observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
if (item.arrivedProperty().get())
|
||||
showArrivedIcon();
|
||||
else if (item.storedInMailboxProperty().get())
|
||||
showMailboxIcon();
|
||||
}
|
||||
if (!newValue)
|
||||
updateMsgState(message);
|
||||
};
|
||||
sendMsgBusyAnimation.isRunningProperty().addListener(sendMsgBusyAnimationListener);
|
||||
|
||||
if (item.arrivedProperty().get())
|
||||
showArrivedIcon();
|
||||
else if (item.storedInMailboxProperty().get())
|
||||
showMailboxIcon();
|
||||
//TODO show that icon on error
|
||||
/*else if (sendMsgProgressIndicator.getProgress() == 0)
|
||||
showNotArrivedIcon();*/
|
||||
sendMsgBusyAnimation.isRunningProperty().addListener(sendMsgBusyAnimationListener);
|
||||
message.addWeakMessageStateListener(() -> updateMsgState(message));
|
||||
updateMsgState(message);
|
||||
} else {
|
||||
headerLabel.getStyleClass().add("message-header");
|
||||
bg.setId("message-bubble-grey");
|
||||
@ -845,7 +851,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
arrow.setId("bubble_arrow_grey_left");
|
||||
}
|
||||
|
||||
if (item.isSystemMessage()) {
|
||||
if (message.isSystemMessage()) {
|
||||
AnchorPane.setLeftAnchor(headerLabel, padding);
|
||||
AnchorPane.setRightAnchor(headerLabel, padding);
|
||||
AnchorPane.setLeftAnchor(bg, border);
|
||||
@ -855,6 +861,8 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
AnchorPane.setRightAnchor(copyIcon, padding);
|
||||
AnchorPane.setLeftAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setRightAnchor(attachmentsBox, padding);
|
||||
AnchorPane.clearConstraints(statusHBox);
|
||||
AnchorPane.setLeftAnchor(statusHBox, padding);
|
||||
} else if (senderIsTrader) {
|
||||
AnchorPane.setLeftAnchor(headerLabel, padding + arrowWidth);
|
||||
AnchorPane.setLeftAnchor(bg, border + arrowWidth);
|
||||
@ -865,7 +873,8 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
AnchorPane.setRightAnchor(copyIcon, padding);
|
||||
AnchorPane.setLeftAnchor(attachmentsBox, padding + arrowWidth);
|
||||
AnchorPane.setRightAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setRightAnchor(statusIcon, padding);
|
||||
AnchorPane.clearConstraints(statusHBox);
|
||||
AnchorPane.setRightAnchor(statusHBox, padding);
|
||||
} else {
|
||||
AnchorPane.setRightAnchor(headerLabel, padding + arrowWidth);
|
||||
AnchorPane.setLeftAnchor(bg, border);
|
||||
@ -876,14 +885,14 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
AnchorPane.setRightAnchor(copyIcon, padding + arrowWidth);
|
||||
AnchorPane.setLeftAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setRightAnchor(attachmentsBox, padding + arrowWidth);
|
||||
AnchorPane.setLeftAnchor(statusIcon, padding);
|
||||
AnchorPane.clearConstraints(statusHBox);
|
||||
AnchorPane.setLeftAnchor(statusHBox, padding);
|
||||
}
|
||||
|
||||
AnchorPane.setBottomAnchor(statusIcon, 7d);
|
||||
headerLabel.setText(formatter.formatDateTime(new Date(item.getDate())));
|
||||
messageLabel.setText(item.getMessage());
|
||||
AnchorPane.setBottomAnchor(statusHBox, 7d);
|
||||
headerLabel.setText(formatter.formatDateTime(new Date(message.getDate())));
|
||||
messageLabel.setText(message.getMessage());
|
||||
attachmentsBox.getChildren().clear();
|
||||
if (item.getAttachments() != null && item.getAttachments().size() > 0) {
|
||||
if (message.getAttachments() != null && message.getAttachments().size() > 0) {
|
||||
AnchorPane.setBottomAnchor(messageLabel, bottomBorder + attachmentsBoxHeight + 10);
|
||||
attachmentsBox.getChildren().add(new AutoTooltipLabel(Res.get("support.attachments") + " ") {{
|
||||
setPadding(new Insets(0, 0, 3, 0));
|
||||
@ -892,7 +901,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
else
|
||||
getStyleClass().add("message");
|
||||
}});
|
||||
item.getAttachments().stream().forEach(attachment -> {
|
||||
message.getAttachments().forEach(attachment -> {
|
||||
final Label icon = new Label();
|
||||
setPadding(new Insets(0, 0, 3, 0));
|
||||
if (isMyMsg)
|
||||
@ -927,33 +936,56 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
AnchorPane.clearConstraints(arrow);
|
||||
AnchorPane.clearConstraints(messageLabel);
|
||||
AnchorPane.clearConstraints(copyIcon);
|
||||
AnchorPane.clearConstraints(statusIcon);
|
||||
AnchorPane.clearConstraints(statusHBox);
|
||||
AnchorPane.clearConstraints(attachmentsBox);
|
||||
|
||||
copyIcon.setOnMouseClicked(null);
|
||||
messageLabel.setOnMouseClicked(null);
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
|
||||
/* private void showNotArrivedIcon() {
|
||||
statusIcon.setVisible(true);
|
||||
AwesomeDude.setIcon(statusIcon, AwesomeIcon.WARNING_SIGN, "14");
|
||||
Tooltip.install(statusIcon, new Tooltip("Message did not arrive. Please try to send again."));
|
||||
statusIcon.setTextFill(Paint.valueOf("#dd0000"));
|
||||
}*/
|
||||
|
||||
private void showMailboxIcon() {
|
||||
statusIcon.setVisible(true);
|
||||
AwesomeDude.setIcon(statusIcon, AwesomeIcon.ENVELOPE_ALT, "14");
|
||||
statusIcon.setTooltip(new Tooltip(Res.get("support.savedInMailbox")));
|
||||
private void updateMsgState(DisputeCommunicationMessage message) {
|
||||
boolean visible;
|
||||
AwesomeIcon icon = null;
|
||||
String text = null;
|
||||
statusIcon.setTextFill(Paint.valueOf("#0f87c3"));
|
||||
}
|
||||
statusInfoLabel.setTextFill(Paint.valueOf("#0f87c3"));
|
||||
statusHBox.setOpacity(1);
|
||||
log.debug("updateMsgState msg-{}, ack={}, arrived={}", message.getMessage(),
|
||||
message.acknowledgedProperty().get(), message.arrivedProperty().get());
|
||||
if (message.acknowledgedProperty().get()) {
|
||||
visible = true;
|
||||
icon = AwesomeIcon.OK_SIGN;
|
||||
text = Res.get("support.acknowledged");
|
||||
|
||||
private void showArrivedIcon() {
|
||||
statusIcon.setVisible(true);
|
||||
AwesomeDude.setIcon(statusIcon, AwesomeIcon.OK, "14");
|
||||
statusIcon.setTooltip(new Tooltip(Res.get("support.arrived")));
|
||||
statusIcon.setTextFill(Paint.valueOf("#0f87c3"));
|
||||
} else if (message.ackErrorProperty().get() != null) {
|
||||
visible = true;
|
||||
icon = AwesomeIcon.EXCLAMATION_SIGN;
|
||||
text = Res.get("support.error", message.ackErrorProperty().get());
|
||||
statusIcon.setTextFill(Paint.valueOf("#dd0000"));
|
||||
statusInfoLabel.setTextFill(Paint.valueOf("#dd0000"));
|
||||
} else if (message.arrivedProperty().get()) {
|
||||
visible = true;
|
||||
icon = AwesomeIcon.OK;
|
||||
text = Res.get("support.arrived");
|
||||
statusHBox.setOpacity(0.5);
|
||||
} else if (message.storedInMailboxProperty().get()) {
|
||||
visible = true;
|
||||
icon = AwesomeIcon.ENVELOPE;
|
||||
text = Res.get("support.savedInMailbox");
|
||||
statusHBox.setOpacity(0.5);
|
||||
} else {
|
||||
visible = false;
|
||||
log.debug("updateMsgState called but no msg state available. message={}", message);
|
||||
}
|
||||
|
||||
statusHBox.setVisible(visible);
|
||||
if (visible) {
|
||||
AwesomeDude.setIcon(statusIcon, icon, "14");
|
||||
statusIcon.setTooltip(new Tooltip(text));
|
||||
statusInfoLabel.setText(text);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ public abstract class EditableOfferViewModel<M extends EditableOfferDataModel> e
|
||||
switch (BisqEnvironment.getBaseCurrencyNetwork().getCurrencyCode()) {
|
||||
case "BTC":
|
||||
amount.set("0.0001");
|
||||
price.set("11029");
|
||||
price.set("6700");
|
||||
break;
|
||||
case "LTC":
|
||||
amount.set("50");
|
||||
|
@ -213,8 +213,8 @@ class TakeOfferDataModel extends OfferDataModel {
|
||||
calculateTotalToPay();
|
||||
log.info("Completed requestTxFee: txFeeFromFeeService={}", txFeeFromFeeService);
|
||||
} else {
|
||||
log.warn("We received the tx fee respnse after we have shown the funding screen and ignore that " +
|
||||
"to avoid that the total funds to pay changes due cahnged tx fees.");
|
||||
log.debug("We received the tx fee response after we have shown the funding screen and ignore that " +
|
||||
"to avoid that the total funds to pay changes due changed tx fees.");
|
||||
}
|
||||
}, null);
|
||||
|
||||
|
@ -23,7 +23,6 @@ import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.main.overlays.Overlay;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.Transitions;
|
||||
|
||||
import bisq.core.arbitration.Dispute;
|
||||
import bisq.core.arbitration.DisputeManager;
|
||||
@ -566,7 +565,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
if (!finalPeersDispute.isClosed())
|
||||
UserThread.runAfter(() ->
|
||||
new Popup<>().attention(Res.get("disputeSummaryWindow.close.closePeer")).show(),
|
||||
Transitions.DEFAULT_DURATION, TimeUnit.MILLISECONDS);
|
||||
200, TimeUnit.MILLISECONDS);
|
||||
|
||||
hide();
|
||||
|
||||
|
@ -139,21 +139,24 @@ public class SendPrivateNotificationWindow extends Overlay<SendPrivateNotificati
|
||||
new SendMailboxMessageListener() {
|
||||
@Override
|
||||
public void onArrived() {
|
||||
log.info("PrivateNotificationMessage arrived at peer.");
|
||||
log.info("{} arrived at peer {}.",
|
||||
message.getClass().getSimpleName(), nodeAddress);
|
||||
new Popup<>().feedback(Res.get("shared.messageArrived"))
|
||||
.onClose(SendPrivateNotificationWindow.this::hide).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStoredInMailbox() {
|
||||
log.info("PrivateNotificationMessage was stored in mailbox.");
|
||||
log.info("{} stored in mailbox for peer {}.",
|
||||
message.getClass().getSimpleName(), nodeAddress);
|
||||
new Popup<>().feedback(Res.get("shared.messageStoredInMailbox"))
|
||||
.onClose(SendPrivateNotificationWindow.this::hide).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(String errorMessage) {
|
||||
log.error("sendEncryptedMailboxMessage failed. message=" + message);
|
||||
log.error("{} failed: Peer {}, errorMessage={}",
|
||||
message.getClass().getSimpleName(), nodeAddress, errorMessage);
|
||||
new Popup<>().feedback(Res.get("shared.messageSendingFailed", errorMessage))
|
||||
.onClose(SendPrivateNotificationWindow.this::hide).show();
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.validation.BtcAddressValidator;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.network.MessageState;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.payment.AccountAgeWitnessService;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
@ -52,12 +53,15 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel.SellerState.UNDEFINED;
|
||||
|
||||
public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataModel> implements ViewModel {
|
||||
private Subscription tradeStateSubscription;
|
||||
|
||||
@Getter
|
||||
@Nullable
|
||||
private Trade trade;
|
||||
|
||||
@ -90,6 +94,11 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||
|
||||
private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>();
|
||||
@Getter
|
||||
private final ObjectProperty<MessageState> messageStateProperty = new SimpleObjectProperty<>(MessageState.UNDEFINED);
|
||||
private Subscription tradeStateSubscription;
|
||||
private Subscription messageStateSubscription;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
@ -115,8 +124,18 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
protected void deactivate() {
|
||||
if (tradeStateSubscription != null) {
|
||||
tradeStateSubscription.unsubscribe();
|
||||
tradeStateSubscription = null;
|
||||
}
|
||||
|
||||
if (messageStateSubscription != null) {
|
||||
messageStateSubscription.unsubscribe();
|
||||
messageStateSubscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't set own listener as we need to control the order of the calls
|
||||
@ -126,20 +145,36 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||
sellerState.set(SellerState.UNDEFINED);
|
||||
buyerState.set(BuyerState.UNDEFINED);
|
||||
}
|
||||
|
||||
if (messageStateSubscription != null) {
|
||||
messageStateSubscription.unsubscribe();
|
||||
messageStateProperty.set(MessageState.UNDEFINED);
|
||||
}
|
||||
|
||||
if (selectedItem != null) {
|
||||
this.trade = selectedItem.getTrade();
|
||||
tradeStateSubscription = EasyBind.subscribe(trade.stateProperty(), this::onTradeStateChanged);
|
||||
|
||||
messageStateSubscription = EasyBind.subscribe(trade.getProcessModel().getPaymentStartedMessageStateProperty(), this::onMessageStateChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
if (tradeStateSubscription != null) {
|
||||
tradeStateSubscription.unsubscribe();
|
||||
tradeStateSubscription = null;
|
||||
public void setMessageStateProperty(MessageState messageState) {
|
||||
if (messageStateProperty.get() == MessageState.ACKNOWLEDGED) {
|
||||
log.warn("We have already an ACKNOWLEDGED message received. " +
|
||||
"We would not expect any other message after that. Received messageState={}", messageState);
|
||||
return;
|
||||
}
|
||||
|
||||
if (trade != null)
|
||||
trade.getProcessModel().setPaymentStartedMessageState(messageState);
|
||||
}
|
||||
|
||||
private void onMessageStateChanged(MessageState messageState) {
|
||||
messageStateProperty.set(messageState);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -78,6 +78,8 @@ public abstract class TradeStepView extends AnchorPane {
|
||||
private Subscription txIdSubscription;
|
||||
private Clock.Listener clockListener;
|
||||
private final ChangeListener<String> errorMessageListener;
|
||||
protected Label infoLabel;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, Initialisation
|
||||
@ -144,6 +146,9 @@ public abstract class TradeStepView extends AnchorPane {
|
||||
});
|
||||
|
||||
model.clock.addListener(clockListener);
|
||||
|
||||
if (infoLabel != null)
|
||||
infoLabel.setText(getInfoText());
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
@ -211,7 +216,7 @@ public abstract class TradeStepView extends AnchorPane {
|
||||
|
||||
protected void addInfoBlock() {
|
||||
FormBuilder.addTitledGroupBg(gridPane, ++gridRow, 1, getInfoBlockTitle(), Layout.GROUP_DISTANCE);
|
||||
FormBuilder.addMultilineLabel(gridPane, gridRow, getInfoText(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
infoLabel = FormBuilder.addMultilineLabel(gridPane, gridRow, "", Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
}
|
||||
|
||||
protected String getInfoText() {
|
||||
|
@ -29,6 +29,7 @@ import bisq.desktop.components.paymentmethods.CryptoCurrencyForm;
|
||||
import bisq.desktop.components.paymentmethods.FasterPaymentsForm;
|
||||
import bisq.desktop.components.paymentmethods.InteracETransferForm;
|
||||
import bisq.desktop.components.paymentmethods.MoneyBeamForm;
|
||||
import bisq.desktop.components.paymentmethods.MoneyGramForm;
|
||||
import bisq.desktop.components.paymentmethods.NationalBankForm;
|
||||
import bisq.desktop.components.paymentmethods.OKPayForm;
|
||||
import bisq.desktop.components.paymentmethods.PerfectMoneyForm;
|
||||
@ -51,8 +52,10 @@ import bisq.desktop.util.Layout;
|
||||
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.network.MessageState;
|
||||
import bisq.core.payment.payload.CashDepositAccountPayload;
|
||||
import bisq.core.payment.payload.CryptoCurrencyAccountPayload;
|
||||
import bisq.core.payment.payload.MoneyGramAccountPayload;
|
||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.payment.payload.USPostalMoneyOrderAccountPayload;
|
||||
@ -111,7 +114,7 @@ public class BuyerStep2View extends TradeStepView {
|
||||
busyAnimation.play();
|
||||
confirmButton.setDisable(true);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
|
||||
model.setMessageStateProperty(MessageState.SENT);
|
||||
timeoutTimer = UserThread.runAfter(() -> {
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
@ -121,16 +124,19 @@ public class BuyerStep2View extends TradeStepView {
|
||||
case BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageArrived"));
|
||||
model.setMessageStateProperty(MessageState.ARRIVED);
|
||||
break;
|
||||
case BUYER_STORED_IN_MAILBOX_FIAT_PAYMENT_INITIATED_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageStoredInMailbox"));
|
||||
model.setMessageStateProperty(MessageState.STORED_IN_MAILBOX);
|
||||
break;
|
||||
case BUYER_SEND_FAILED_FIAT_PAYMENT_INITIATED_MSG:
|
||||
// We get a popup and the trade closed, so we dont need to show anything here
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText("");
|
||||
model.setMessageStateProperty(MessageState.FAILED);
|
||||
break;
|
||||
default:
|
||||
log.warn("Unexpected case: State={}, tradeId={} " + state.name(), trade.getId());
|
||||
@ -245,6 +251,9 @@ public class BuyerStep2View extends TradeStepView {
|
||||
case PaymentMethod.CASH_DEPOSIT_ID:
|
||||
gridRow = CashDepositForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
|
||||
break;
|
||||
case PaymentMethod.MONEY_GRAM_ID:
|
||||
gridRow = MoneyGramForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
|
||||
break;
|
||||
case PaymentMethod.WESTERN_UNION_ID:
|
||||
gridRow = WesternUnionForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
|
||||
break;
|
||||
@ -338,6 +347,24 @@ public class BuyerStep2View extends TradeStepView {
|
||||
} else {
|
||||
showConfirmPaymentStartedPopup();
|
||||
}
|
||||
} else if (model.dataModel.getSellersPaymentAccountPayload() instanceof MoneyGramAccountPayload) {
|
||||
//noinspection UnusedAssignment
|
||||
//noinspection ConstantConditions
|
||||
String key = "moneyGramMTCNSent";
|
||||
if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) {
|
||||
String email = ((MoneyGramAccountPayload) model.dataModel.getSellersPaymentAccountPayload()).getEmail();
|
||||
Popup popup = new Popup<>();
|
||||
popup.headLine(Res.get("portfolio.pending.step2_buyer.moneyGramMTCNInfo.headline"))
|
||||
.feedback(Res.get("portfolio.pending.step2_buyer.moneyGramMTCNInfo.msg", email))
|
||||
.onAction(this::showConfirmPaymentStartedPopup)
|
||||
.actionButtonText(Res.get("shared.yes"))
|
||||
.closeButtonText(Res.get("shared.no"))
|
||||
.onClose(popup::hide)
|
||||
.dontShowAgainId(key)
|
||||
.show();
|
||||
} else {
|
||||
showConfirmPaymentStartedPopup();
|
||||
}
|
||||
} else {
|
||||
showConfirmPaymentStartedPopup();
|
||||
}
|
||||
@ -432,6 +459,15 @@ public class BuyerStep2View extends TradeStepView {
|
||||
paymentDetailsForTradePopup + ".\n" +
|
||||
copyPaste + "\n\n" +
|
||||
extra;
|
||||
} else if (paymentAccountPayload instanceof MoneyGramAccountPayload) {
|
||||
final String email = ((MoneyGramAccountPayload) paymentAccountPayload).getEmail();
|
||||
final String extra = Res.get("portfolio.pending.step2_buyer.moneyGram.extra", email);
|
||||
message += Res.get("portfolio.pending.step2_buyer.moneyGram",
|
||||
amount) +
|
||||
accountDetails +
|
||||
paymentDetailsForTradePopup + ".\n" +
|
||||
copyPaste + "\n\n" +
|
||||
extra;
|
||||
} else if (paymentAccountPayload instanceof USPostalMoneyOrderAccountPayload) {
|
||||
//noinspection UnusedAssignment
|
||||
message += Res.get("portfolio.pending.step2_buyer.postal", amount) +
|
||||
|
@ -17,12 +17,26 @@
|
||||
|
||||
package bisq.desktop.main.portfolio.pendingtrades.steps.buyer;
|
||||
|
||||
import bisq.desktop.components.TextFieldWithIcon;
|
||||
import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||
import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.Layout;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.network.MessageState;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.paint.Paint;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
public class BuyerStep3View extends TradeStepView {
|
||||
private final ChangeListener<MessageState> messageStateChangeListener;
|
||||
private TextFieldWithIcon textFieldWithIconWithIcon;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, Initialisation
|
||||
@ -30,12 +44,40 @@ public class BuyerStep3View extends TradeStepView {
|
||||
|
||||
public BuyerStep3View(PendingTradesViewModel model) {
|
||||
super(model);
|
||||
|
||||
messageStateChangeListener = (observable, oldValue, newValue) -> {
|
||||
updateMessageStateInfo();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
model.getMessageStateProperty().addListener(messageStateChangeListener);
|
||||
|
||||
updateMessageStateInfo();
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
model.getMessageStateProperty().removeListener(messageStateChangeListener);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Info
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void addInfoBlock() {
|
||||
FormBuilder.addTitledGroupBg(gridPane, ++gridRow, 2, getInfoBlockTitle(), Layout.GROUP_DISTANCE);
|
||||
infoLabel = FormBuilder.addMultilineLabel(gridPane, gridRow, "", Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
textFieldWithIconWithIcon = FormBuilder.addLabelTextFieldWithIcon(gridPane, ++gridRow,
|
||||
Res.get("portfolio.pending.step3_buyer.wait.msgStateInfo.label"), 0).second;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInfoBlockTitle() {
|
||||
return Res.get("portfolio.pending.step3_buyer.wait.headline");
|
||||
@ -46,6 +88,39 @@ public class BuyerStep3View extends TradeStepView {
|
||||
return Res.get("portfolio.pending.step3_buyer.wait.info", model.dataModel.getCurrencyCode());
|
||||
}
|
||||
|
||||
private void updateMessageStateInfo() {
|
||||
MessageState messageState = model.getMessageStateProperty().get();
|
||||
textFieldWithIconWithIcon.setText(Res.get("message.state." + messageState.name()));
|
||||
Label iconLabel = textFieldWithIconWithIcon.getIconLabel();
|
||||
switch (messageState) {
|
||||
case UNDEFINED:
|
||||
textFieldWithIconWithIcon.setIcon(AwesomeIcon.QUESTION);
|
||||
iconLabel.setTextFill(Paint.valueOf("#e9a20a"));
|
||||
break;
|
||||
case SENT:
|
||||
textFieldWithIconWithIcon.setIcon(AwesomeIcon.ARROW_RIGHT);
|
||||
iconLabel.setTextFill(Paint.valueOf("#afe193"));
|
||||
break;
|
||||
case ARRIVED:
|
||||
textFieldWithIconWithIcon.setIcon(AwesomeIcon.OK);
|
||||
iconLabel.setTextFill(Paint.valueOf("#0793ad"));
|
||||
break;
|
||||
case STORED_IN_MAILBOX:
|
||||
textFieldWithIconWithIcon.setIcon(AwesomeIcon.ENVELOPE_ALT);
|
||||
iconLabel.setTextFill(Paint.valueOf("#91B6E9"));
|
||||
break;
|
||||
case ACKNOWLEDGED:
|
||||
textFieldWithIconWithIcon.setIcon(AwesomeIcon.OK_SIGN);
|
||||
iconLabel.setTextFill(Paint.valueOf("#009900"));
|
||||
break;
|
||||
case FAILED:
|
||||
textFieldWithIconWithIcon.setIcon(AwesomeIcon.EXCLAMATION_SIGN);
|
||||
iconLabel.setTextFill(Paint.valueOf("#dd0000"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Warning
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -30,6 +30,7 @@ import bisq.core.locale.Res;
|
||||
import bisq.core.payment.payload.BankAccountPayload;
|
||||
import bisq.core.payment.payload.CashDepositAccountPayload;
|
||||
import bisq.core.payment.payload.CryptoCurrencyAccountPayload;
|
||||
import bisq.core.payment.payload.MoneyGramAccountPayload;
|
||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
||||
import bisq.core.payment.payload.SepaAccountPayload;
|
||||
import bisq.core.payment.payload.SepaInstantAccountPayload;
|
||||
@ -315,6 +316,8 @@ public class SellerStep3View extends TradeStepView {
|
||||
message = message + Res.get("portfolio.pending.step3_seller.cash", part);
|
||||
else if (paymentAccountPayload instanceof WesternUnionAccountPayload)
|
||||
message = message + Res.get("portfolio.pending.step3_seller.westernUnion", part);
|
||||
else if (paymentAccountPayload instanceof MoneyGramAccountPayload)
|
||||
message = message + Res.get("portfolio.pending.step3_seller.moneyGram", part);
|
||||
|
||||
Optional<String> optionalHolderName = getOptionalHolderName();
|
||||
if (optionalHolderName.isPresent()) {
|
||||
|
@ -33,6 +33,7 @@ import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.components.PasswordTextField;
|
||||
import bisq.desktop.components.SearchComboBox;
|
||||
import bisq.desktop.components.TextFieldWithCopyIcon;
|
||||
import bisq.desktop.components.TextFieldWithIcon;
|
||||
import bisq.desktop.components.TitledGroupBg;
|
||||
import bisq.desktop.components.TxIdTextField;
|
||||
|
||||
@ -44,6 +45,8 @@ import bisq.common.util.Tuple4;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import de.jensd.fx.glyphs.GlyphIcons;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
@ -74,16 +77,7 @@ import javafx.geometry.VPos;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
|
||||
import de.jensd.fx.glyphs.GlyphIcons;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory;
|
||||
|
||||
public class FormBuilder {
|
||||
private static final Logger log = LoggerFactory.getLogger(FormBuilder.class);
|
||||
public static final String MATERIAL_DESIGN_ICONS = "'Material Design Icons'";
|
||||
public static final String FONTAWESOME_ICONS = "FontAwesome";
|
||||
|
||||
@ -211,6 +205,27 @@ public class FormBuilder {
|
||||
return new Tuple2<>(label, textField);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Label + TextFieldWithIcon
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public static Tuple2<Label, TextFieldWithIcon> addLabelTextFieldWithIcon(GridPane gridPane, int rowIndex, String title, double top) {
|
||||
Label label = addLabel(gridPane, rowIndex, title, top);
|
||||
|
||||
TextFieldWithIcon textFieldWithIcon = new TextFieldWithIcon();
|
||||
textFieldWithIcon.setMouseTransparent(true);
|
||||
textFieldWithIcon.setFocusTraversable(false);
|
||||
GridPane.setRowIndex(textFieldWithIcon, rowIndex);
|
||||
GridPane.setColumnIndex(textFieldWithIcon, 1);
|
||||
GridPane.setMargin(textFieldWithIcon, new Insets(top, 0, 0, 0));
|
||||
gridPane.getChildren().add(textFieldWithIcon);
|
||||
|
||||
return new Tuple2<>(label, textFieldWithIcon);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HyperlinkWithIcon
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -873,6 +888,7 @@ public class FormBuilder {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Label + InfoTextField
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static Tuple2<Label, InfoTextField> addLabelInfoTextfield(GridPane gridPane, int rowIndex, String labelText,
|
||||
String fieldText) {
|
||||
return addLabelInfoTextfield(gridPane, rowIndex, labelText, fieldText, 0);
|
||||
|
@ -59,7 +59,7 @@ public class AwesomeFontDemo extends Application {
|
||||
root.getChildren().add(button);
|
||||
}
|
||||
|
||||
primaryStage.setScene(new Scene(root, 900, 850));
|
||||
primaryStage.setScene(new Scene(root, 1200, 950));
|
||||
primaryStage.show();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user