mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 23:06:39 +01:00
Add support for user name for Revolut accounts
If a user has an existing account with phone number or email as account ID we show a popup at startup where we require that he sets the user name. This popup has no close button so he is forced to enter a value. If there are multiple account multiple popups will be shown. To not break signed accounts we keep accountId as internal id used for signing. Old accounts get a popup to add the new required field userName but accountId is left unchanged. Newly created accounts fill accountId with the value of userName. In the UI we only use userName. Input validation does only check for length (5-100 chars). Not sure what are the requirements at Revolut. Can be changes easily if anyone gets the specs.
This commit is contained in:
parent
51e66d5763
commit
6c60e1739d
11 changed files with 220 additions and 104 deletions
|
@ -96,6 +96,7 @@ public class BisqHeadlessApp implements HeadlessApp {
|
|||
bisqSetup.setVoteResultExceptionHandler(voteResultException -> log.warn("voteResultException={}", voteResultException.toString()));
|
||||
bisqSetup.setRejectedTxErrorMessageHandler(errorMessage -> log.warn("setRejectedTxErrorMessageHandler. errorMessage={}", errorMessage));
|
||||
bisqSetup.setShowPopupIfInvalidBtcConfigHandler(() -> log.error("onShowPopupIfInvalidBtcConfigHandler"));
|
||||
bisqSetup.setRevolutAccountsUpdateHandler(revolutAccountList -> log.info("setRevolutAccountsUpdateHandler: revolutAccountList={}", revolutAccountList));
|
||||
|
||||
//TODO move to bisqSetup
|
||||
corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> log.warn("getCorruptedDatabaseFiles. files={}", files));
|
||||
|
|
|
@ -44,6 +44,7 @@ import bisq.core.notifications.alerts.market.MarketAlerts;
|
|||
import bisq.core.notifications.alerts.price.PriceAlert;
|
||||
import bisq.core.offer.OpenOfferManager;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.RevolutAccount;
|
||||
import bisq.core.payment.TradeLimits;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
|
@ -221,6 +222,9 @@ public class BisqSetup {
|
|||
@Setter
|
||||
@Nullable
|
||||
private Runnable showPopupIfInvalidBtcConfigHandler;
|
||||
@Setter
|
||||
@Nullable
|
||||
private Consumer<List<RevolutAccount>> revolutAccountsUpdateHandler;
|
||||
|
||||
@Getter
|
||||
final BooleanProperty newVersionAvailableProperty = new SimpleBooleanProperty(false);
|
||||
|
@ -824,6 +828,8 @@ public class BisqSetup {
|
|||
priceAlert.onAllServicesInitialized();
|
||||
marketAlerts.onAllServicesInitialized();
|
||||
|
||||
user.onAllServicesInitialized(revolutAccountsUpdateHandler);
|
||||
|
||||
allBasicServicesInitialized = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,15 @@ public final class RevolutAccount extends PaymentAccount {
|
|||
return new RevolutAccountPayload(paymentMethod.getId(), id);
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId) {
|
||||
((RevolutAccountPayload) paymentAccountPayload).setAccountId(accountId);
|
||||
public void setUserName(String userName) {
|
||||
((RevolutAccountPayload) paymentAccountPayload).setUserName(userName);
|
||||
}
|
||||
|
||||
public String getAccountId() {
|
||||
return ((RevolutAccountPayload) paymentAccountPayload).getAccountId();
|
||||
public String getUserName() {
|
||||
return ((RevolutAccountPayload) paymentAccountPayload).getUserName();
|
||||
}
|
||||
|
||||
public boolean userNameNotSet() {
|
||||
return ((RevolutAccountPayload) paymentAccountPayload).userNameNotSet();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,26 +19,36 @@ package bisq.core.payment.payload;
|
|||
|
||||
import bisq.core.locale.Res;
|
||||
|
||||
import bisq.common.proto.ProtoUtil;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
public final class RevolutAccountPayload extends PaymentAccountPayload {
|
||||
private String accountId = "";
|
||||
// Not used anymore from outside. Only used as internal Id to not break existing account witness objects
|
||||
private String accountId = null;
|
||||
|
||||
// Was added in 1.3.8
|
||||
// To not break signed accounts we keep accountId as internal id used for signing.
|
||||
// Old accounts get a popup to add the new required field userName but accountId is
|
||||
// left unchanged. Newly created accounts fill accountId with the value of userName.
|
||||
// In the UI we only use userName.
|
||||
@Nullable
|
||||
private String userName = null;
|
||||
|
||||
public RevolutAccountPayload(String paymentMethod, String id) {
|
||||
super(paymentMethod, id);
|
||||
|
@ -52,6 +62,7 @@ public final class RevolutAccountPayload extends PaymentAccountPayload {
|
|||
private RevolutAccountPayload(String paymentMethod,
|
||||
String id,
|
||||
String accountId,
|
||||
@Nullable String userName,
|
||||
long maxTradePeriod,
|
||||
Map<String, String> excludeFromJsonDataMap) {
|
||||
super(paymentMethod,
|
||||
|
@ -60,20 +71,23 @@ public final class RevolutAccountPayload extends PaymentAccountPayload {
|
|||
excludeFromJsonDataMap);
|
||||
|
||||
this.accountId = accountId;
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message toProtoMessage() {
|
||||
return getPaymentAccountPayloadBuilder()
|
||||
.setRevolutAccountPayload(protobuf.RevolutAccountPayload.newBuilder()
|
||||
.setAccountId(accountId))
|
||||
.build();
|
||||
protobuf.RevolutAccountPayload.Builder revolutBuilder = protobuf.RevolutAccountPayload.newBuilder().setAccountId(accountId);
|
||||
Optional.ofNullable(userName).ifPresent(revolutBuilder::setUserName);
|
||||
return getPaymentAccountPayloadBuilder().setRevolutAccountPayload(revolutBuilder).build();
|
||||
}
|
||||
|
||||
|
||||
public static RevolutAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
|
||||
protobuf.RevolutAccountPayload revolutAccountPayload = proto.getRevolutAccountPayload();
|
||||
return new RevolutAccountPayload(proto.getPaymentMethodId(),
|
||||
proto.getId(),
|
||||
proto.getRevolutAccountPayload().getAccountId(),
|
||||
revolutAccountPayload.getAccountId(),
|
||||
ProtoUtil.stringOrNullFromProto(revolutAccountPayload.getUserName()),
|
||||
proto.getMaxTradePeriod(),
|
||||
new HashMap<>(proto.getExcludeFromJsonDataMap()));
|
||||
}
|
||||
|
@ -85,7 +99,7 @@ public final class RevolutAccountPayload extends PaymentAccountPayload {
|
|||
|
||||
@Override
|
||||
public String getPaymentDetails() {
|
||||
return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.account") + " " + accountId;
|
||||
return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.account.userName") + " " + userName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,6 +109,26 @@ public final class RevolutAccountPayload extends PaymentAccountPayload {
|
|||
|
||||
@Override
|
||||
public byte[] getAgeWitnessInputData() {
|
||||
return super.getAgeWitnessInputData(accountId.getBytes(StandardCharsets.UTF_8));
|
||||
// getAgeWitnessInputData is called at new account creation when accountId is null, we use empty string as
|
||||
// it has been the case before
|
||||
String input = this.accountId == null ? "" : this.accountId;
|
||||
return super.getAgeWitnessInputData(input.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public void setUserName(@Nullable String userName) {
|
||||
this.userName = userName;
|
||||
// We only set accountId to userName for new accounts. Existing accounts have accountId set with email
|
||||
// or phone nr. and we keep that to not break account signing.
|
||||
if (accountId == null) {
|
||||
accountId = userName;
|
||||
}
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName != null ? userName : accountId;
|
||||
}
|
||||
|
||||
public boolean userNameNotSet() {
|
||||
return userName == null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import bisq.core.locale.TradeCurrency;
|
|||
import bisq.core.notifications.alerts.market.MarketAlertFilter;
|
||||
import bisq.core.notifications.alerts.price.PriceAlertFilter;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.RevolutAccount;
|
||||
import bisq.core.support.dispute.arbitration.arbitrator.Arbitrator;
|
||||
import bisq.core.support.dispute.mediation.mediator.Mediator;
|
||||
import bisq.core.support.dispute.refund.refundagent.RefundAgent;
|
||||
|
@ -50,6 +51,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -126,6 +128,16 @@ public class User implements PersistedDataHost {
|
|||
// API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onAllServicesInitialized(@Nullable Consumer<List<RevolutAccount>> resultHandler) {
|
||||
if (resultHandler != null) {
|
||||
resultHandler.accept(paymentAccountsAsObservable.stream()
|
||||
.filter(paymentAccount -> paymentAccount instanceof RevolutAccount)
|
||||
.map(paymentAccount -> (RevolutAccount) paymentAccount)
|
||||
.filter(RevolutAccount::userNameNotSet)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Arbitrator getAcceptedArbitratorByAddress(NodeAddress nodeAddress) {
|
||||
final List<Arbitrator> acceptedArbitrators = userPayload.getAcceptedArbitrators();
|
||||
|
|
|
@ -2987,6 +2987,7 @@ seed.restore.error=An error occurred when restoring the wallets with seed words.
|
|||
payment.account=Account
|
||||
payment.account.no=Account no.
|
||||
payment.account.name=Account name
|
||||
payment.account.userName=User name
|
||||
payment.account.owner=Account owner full name
|
||||
payment.account.fullName=Full name (first, middle, last)
|
||||
payment.account.state=State/Province/Region
|
||||
|
@ -3021,8 +3022,6 @@ payment.cashApp.cashTag=$Cashtag
|
|||
payment.moneyBeam.accountId=Email or phone no.
|
||||
payment.venmo.venmoUserName=Venmo username
|
||||
payment.popmoney.accountId=Email or phone no.
|
||||
payment.revolut.email=Email
|
||||
payment.revolut.phoneNr=Registered phone no.
|
||||
payment.promptPay.promptPayId=Citizen ID/Tax ID or phone no.
|
||||
payment.supportedCurrencies=Supported currencies
|
||||
payment.limitations=Limitations
|
||||
|
@ -3126,8 +3125,12 @@ payment.limits.info.withSigning=To limit chargeback risk, Bisq sets per-trade li
|
|||
payment.cashDeposit.info=Please confirm your bank allows you to send cash deposits into other peoples' accounts. \
|
||||
For example, Bank of America and Wells Fargo no longer allow such deposits.
|
||||
|
||||
payment.revolut.info=Please be sure that the phone number you used for your Revolut account is registered at Revolut \
|
||||
otherwise the BTC buyer cannot send you the funds.
|
||||
payment.revolut.info=Revolut requires the 'User name' as account ID not the phone number or email as it was the case in the past.
|
||||
payment.account.revolut.addUserNameInfo={0}\n\
|
||||
Your existing Revolut account ({1}) does not has set the ''User name''.\n\
|
||||
Please enter your Revolut ''User name'' to update your account data.\n\
|
||||
This will not affect your account age signing status.
|
||||
payment.revolut.addUserNameInfo.headLine=Update Revolut account
|
||||
|
||||
payment.usPostalMoneyOrder.info=Trading using US Postal Money Orders (USPMO) on Bisq requires that you understand the following:\n\
|
||||
\n\
|
||||
|
|
|
@ -23,8 +23,6 @@ import bisq.desktop.util.Layout;
|
|||
import bisq.desktop.util.validation.RevolutValidator;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.locale.Country;
|
||||
import bisq.core.locale.CountryUtil;
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
|
@ -34,46 +32,28 @@ import bisq.core.payment.payload.RevolutAccountPayload;
|
|||
import bisq.core.util.coin.CoinFormatter;
|
||||
import bisq.core.util.validation.InputValidator;
|
||||
|
||||
import com.jfoenix.controls.JFXComboBox;
|
||||
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.FlowPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextFieldWithCopyIcon;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelFlowPane;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelWithVBox;
|
||||
|
||||
public class RevolutForm extends PaymentMethodForm {
|
||||
private final RevolutAccount account;
|
||||
private RevolutValidator validator;
|
||||
private InputTextField accountIdInputTextField;
|
||||
private Country selectedCountry;
|
||||
private InputTextField userNameInputTextField;
|
||||
|
||||
public static int addFormForBuyer(GridPane gridPane, int gridRow,
|
||||
PaymentAccountPayload paymentAccountPayload) {
|
||||
String accountId = ((RevolutAccountPayload) paymentAccountPayload).getAccountId();
|
||||
addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, getTitle(accountId), accountId);
|
||||
String userName = ((RevolutAccountPayload) paymentAccountPayload).getUserName();
|
||||
addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.account.userName"), userName);
|
||||
|
||||
return gridRow;
|
||||
}
|
||||
|
||||
private static String getTitle(String accountId) {
|
||||
// From 0.9.4 on we only allow phone nr. as with emails we got too many disputes as users used an email which was
|
||||
// not registered at Revolut. It seems that phone numbers need to be registered at least we have no reports from
|
||||
// arbitrators with such cases. Thought email is still supported for backward compatibility.
|
||||
// We might still get emails from users who have registered when email was supported
|
||||
return accountId.contains("@") ? Res.get("payment.revolut.email") : Res.get("payment.revolut.phoneNr");
|
||||
}
|
||||
|
||||
public RevolutForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService,
|
||||
RevolutValidator revolutValidator, InputValidator inputValidator, GridPane gridPane,
|
||||
int gridRow, CoinFormatter formatter) {
|
||||
|
@ -86,63 +66,16 @@ public class RevolutForm extends PaymentMethodForm {
|
|||
public void addFormForAddAccount() {
|
||||
gridRowFrom = gridRow + 1;
|
||||
|
||||
// country selection is added only to prevent anymore email id input and
|
||||
// solely to validate the given phone number
|
||||
ComboBox<Country> countryComboBox = addCountrySelection();
|
||||
setCountryComboBoxAction(countryComboBox);
|
||||
countryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllRevolutCountries()));
|
||||
|
||||
accountIdInputTextField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.revolut.phoneNr"));
|
||||
accountIdInputTextField.setValidator(validator);
|
||||
accountIdInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
account.setAccountId(newValue.trim());
|
||||
userNameInputTextField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.account.userName"));
|
||||
userNameInputTextField.setValidator(validator);
|
||||
userNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
account.setUserName(newValue.trim());
|
||||
updateFromInputs();
|
||||
});
|
||||
|
||||
addCurrenciesGrid(true);
|
||||
addLimitations(false);
|
||||
addAccountNameTextFieldWithAutoFillToggleButton();
|
||||
|
||||
//set default country as selected
|
||||
selectedCountry = CountryUtil.getDefaultCountry();
|
||||
if (CountryUtil.getAllRevolutCountries().contains(selectedCountry)) {
|
||||
countryComboBox.getSelectionModel().select(selectedCountry);
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox<Country> addCountrySelection() {
|
||||
HBox hBox = new HBox();
|
||||
|
||||
hBox.setSpacing(5);
|
||||
ComboBox<Country> countryComboBox = new JFXComboBox<>();
|
||||
hBox.getChildren().add(countryComboBox);
|
||||
|
||||
addTopLabelWithVBox(gridPane, ++gridRow, Res.get("payment.bank.country"), hBox, 0);
|
||||
|
||||
countryComboBox.setPromptText(Res.get("payment.select.bank.country"));
|
||||
countryComboBox.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Country country) {
|
||||
return country.name + " (" + country.code + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Country fromString(String s) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return countryComboBox;
|
||||
}
|
||||
|
||||
void setCountryComboBoxAction(ComboBox<Country> countryComboBox) {
|
||||
countryComboBox.setOnAction(e -> {
|
||||
selectedCountry = countryComboBox.getSelectionModel().getSelectedItem();
|
||||
updateFromInputs();
|
||||
accountIdInputTextField.resetValidation();
|
||||
accountIdInputTextField.validate();
|
||||
accountIdInputTextField.requestFocus();
|
||||
countryComboBox.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
private void addCurrenciesGrid(boolean isEditable) {
|
||||
|
@ -161,18 +94,18 @@ public class RevolutForm extends PaymentMethodForm {
|
|||
|
||||
@Override
|
||||
protected void autoFillNameTextField() {
|
||||
setAccountNameWithString(accountIdInputTextField.getText());
|
||||
setAccountNameWithString(userNameInputTextField.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFormForDisplayAccount() {
|
||||
gridRowFrom = gridRow;
|
||||
addTopLabelTextField(gridPane, gridRow, Res.get("payment.account.name"),
|
||||
addTopLabelTextField(gridPane, gridRow, Res.get("payment.account.userName"),
|
||||
account.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"),
|
||||
Res.get(account.getPaymentMethod().getId()));
|
||||
String accountId = account.getAccountId();
|
||||
TextField field = addCompactTopLabelTextField(gridPane, ++gridRow, getTitle(accountId), accountId).second;
|
||||
String userName = account.getUserName();
|
||||
TextField field = addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.account.userName"), userName).second;
|
||||
field.setMouseTransparent(false);
|
||||
addLimitations(true);
|
||||
addCurrenciesGrid(false);
|
||||
|
@ -181,7 +114,7 @@ public class RevolutForm extends PaymentMethodForm {
|
|||
@Override
|
||||
public void updateAllInputsValid() {
|
||||
allInputsValid.set(isAccountNameValid()
|
||||
&& validator.validate(account.getAccountId(), selectedCountry.code).isValid
|
||||
&& validator.validate(account.getUserName()).isValid
|
||||
&& account.getTradeCurrencies().size() > 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import bisq.desktop.main.overlays.windows.DisplayAlertMessageWindow;
|
|||
import bisq.desktop.main.overlays.windows.NewTradeProtocolLaunchWindow;
|
||||
import bisq.desktop.main.overlays.windows.TacWindow;
|
||||
import bisq.desktop.main.overlays.windows.TorNetworkSettingsWindow;
|
||||
import bisq.desktop.main.overlays.windows.UpdateRevolutAccountWindow;
|
||||
import bisq.desktop.main.overlays.windows.WalletPasswordWindow;
|
||||
import bisq.desktop.main.overlays.windows.downloadupdate.DisplayUpdateDownloadWindow;
|
||||
import bisq.desktop.main.presentation.AccountPresentation;
|
||||
|
@ -49,6 +50,7 @@ import bisq.core.locale.CurrencyUtil;
|
|||
import bisq.core.locale.Res;
|
||||
import bisq.core.payment.AliPayAccount;
|
||||
import bisq.core.payment.CryptoCurrencyAccount;
|
||||
import bisq.core.payment.RevolutAccount;
|
||||
import bisq.core.presentation.BalancePresentation;
|
||||
import bisq.core.presentation.SupportTicketsPresentation;
|
||||
import bisq.core.presentation.TradePresentation;
|
||||
|
@ -87,12 +89,15 @@ import javafx.beans.property.StringProperty;
|
|||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -300,10 +305,11 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
|
|||
.useReportBugButton()
|
||||
.show()));
|
||||
bisqSetup.setDisplayTorNetworkSettingsHandler(show -> {
|
||||
if (show)
|
||||
if (show) {
|
||||
torNetworkSettingsWindow.show();
|
||||
else
|
||||
} else if (torNetworkSettingsWindow.isDisplayed()) {
|
||||
torNetworkSettingsWindow.hide();
|
||||
}
|
||||
});
|
||||
bisqSetup.setSpvFileCorruptedHandler(msg -> new Popup().warning(msg)
|
||||
.actionButtonText(Res.get("settings.net.reSyncSPVChainButton"))
|
||||
|
@ -374,6 +380,12 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
|
|||
|
||||
bisqSetup.setShowPopupIfInvalidBtcConfigHandler(this::showPopupIfInvalidBtcConfig);
|
||||
|
||||
bisqSetup.setRevolutAccountsUpdateHandler(revolutAccountList -> {
|
||||
// We copy the array as we will mutate it later
|
||||
showRevolutAccountUpdateWindow(new ArrayList<>(revolutAccountList));
|
||||
});
|
||||
|
||||
|
||||
corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> new Popup()
|
||||
.warning(Res.get("popup.warning.incompatibleDB", files.toString(), config.appDataDir))
|
||||
.useShutDownButton()
|
||||
|
@ -403,6 +415,17 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
|
|||
bisqSetup.setFilterWarningHandler(warning -> new Popup().warning(warning).show());
|
||||
}
|
||||
|
||||
private void showRevolutAccountUpdateWindow(List<RevolutAccount> revolutAccountList) {
|
||||
if (!revolutAccountList.isEmpty()) {
|
||||
RevolutAccount revolutAccount = revolutAccountList.get(0);
|
||||
revolutAccountList.remove(0);
|
||||
new UpdateRevolutAccountWindow(revolutAccount, user).onClose(() -> {
|
||||
// We delay a bit in case we have multiple account for better UX
|
||||
UserThread.runAfter(() -> showRevolutAccountUpdateWindow(revolutAccountList), 300, TimeUnit.MILLISECONDS);
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupP2PNumPeersWatcher() {
|
||||
p2PService.getNumConnectedPeers().addListener((observable, oldValue, newValue) -> {
|
||||
int numPeers = (int) newValue;
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.main.overlays.windows;
|
||||
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.main.overlays.Overlay;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.validation.RevolutValidator;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.payment.RevolutAccount;
|
||||
import bisq.core.user.User;
|
||||
|
||||
import javafx.scene.Scene;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addInputTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addLabel;
|
||||
|
||||
public class UpdateRevolutAccountWindow extends Overlay<UpdateRevolutAccountWindow> {
|
||||
private final RevolutValidator revolutValidator;
|
||||
private final RevolutAccount revolutAccount;
|
||||
private final User user;
|
||||
private InputTextField userNameInputTextField;
|
||||
|
||||
public UpdateRevolutAccountWindow(RevolutAccount revolutAccount, User user) {
|
||||
super();
|
||||
this.revolutAccount = revolutAccount;
|
||||
this.user = user;
|
||||
type = Type.Attention;
|
||||
hideCloseButton = true;
|
||||
revolutValidator = new RevolutValidator();
|
||||
actionButtonText = Res.get("shared.save");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupKeyHandler(Scene scene) {
|
||||
// We do not support enter or escape here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (headLine == null)
|
||||
headLine = Res.get("payment.revolut.addUserNameInfo.headLine");
|
||||
|
||||
width = 868;
|
||||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
addButtons();
|
||||
applyStyles();
|
||||
display();
|
||||
}
|
||||
|
||||
private void addContent() {
|
||||
addLabel(gridPane, ++rowIndex, Res.get("payment.account.revolut.addUserNameInfo", Res.get("payment.revolut.info"), revolutAccount.getAccountName()));
|
||||
userNameInputTextField = addInputTextField(gridPane, ++rowIndex, Res.get("payment.account.userName"), Layout.COMPACT_FIRST_ROW_DISTANCE);
|
||||
userNameInputTextField.setValidator(revolutValidator);
|
||||
userNameInputTextField.textProperty().addListener((observable, oldValue, newValue) ->
|
||||
actionButton.setDisable(!revolutValidator.validate(newValue).isValid));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addButtons() {
|
||||
super.addButtons();
|
||||
|
||||
// We do not allow close in case the userName is not correctly added so we
|
||||
// overwrote the default handler
|
||||
actionButton.setOnAction(event -> {
|
||||
String userName = userNameInputTextField.getText();
|
||||
if (revolutValidator.validate(userName).isValid) {
|
||||
revolutAccount.setUserName(userName);
|
||||
user.persist();
|
||||
closeHandlerOptional.ifPresent(Runnable::run);
|
||||
hide();
|
||||
}
|
||||
});
|
||||
actionButton.setDisable(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,10 +17,13 @@
|
|||
|
||||
package bisq.desktop.util.validation;
|
||||
|
||||
public final class RevolutValidator extends PhoneNumberValidator {
|
||||
public final class RevolutValidator extends LengthValidator {
|
||||
public RevolutValidator() {
|
||||
// Not sure what are requirements for Revolut user names
|
||||
super(5, 100);
|
||||
}
|
||||
|
||||
public ValidationResult validate(String input, String code) {
|
||||
super.setIsoCountryCode(code);
|
||||
public ValidationResult validate(String input) {
|
||||
return super.validate(input);
|
||||
}
|
||||
|
||||
|
|
|
@ -1085,6 +1085,7 @@ message PopmoneyAccountPayload {
|
|||
|
||||
message RevolutAccountPayload {
|
||||
string account_id = 1;
|
||||
string user_name = 2;
|
||||
}
|
||||
|
||||
message PerfectMoneyAccountPayload {
|
||||
|
|
Loading…
Add table
Reference in a new issue