mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 01:41:11 +01:00
Improve flow in create/take offer process.
When creating or taking an offer the user gets the choice to fund the trade from an external wallet for potentially better privacy (avoid coin merge if inputs from ext. wallet are kept separated). From feedback it seems that most users are not using that option and then they need to do that extra click on the "Fund from internal Bisq wallet" button. We offer a way to avoid that extra step if the user chooses to use the internal wallet. We show at the first time a popup with background info why funding from an external wallet could improve privacy and if the user prefers to not use that to give them an option to skip that step in future. In the settings we could add a toggle to re-enable it again. The review screen can be skipped if user chooses this feature, leading to data entry > confirm rather than data entry > fund > review > confirm.
This commit is contained in:
parent
9813ae7574
commit
e9ec3d72e1
@ -151,6 +151,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
||||
// Added at 1.9.11
|
||||
private boolean isFullBMAccountingNode = false;
|
||||
|
||||
private boolean useBisqWalletFunding = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
@ -225,7 +226,8 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
||||
.setUserDefinedTradeLimit(userDefinedTradeLimit)
|
||||
.setUserHasRaisedTradeLimit(userHasRaisedTradeLimit)
|
||||
.setProcessBurningManAccountingData(processBurningManAccountingData)
|
||||
.setIsFullBMAccountingNode(isFullBMAccountingNode);
|
||||
.setIsFullBMAccountingNode(isFullBMAccountingNode)
|
||||
.setUseBisqWalletFunding(useBisqWalletFunding);
|
||||
|
||||
Optional.ofNullable(backupDirectory).ifPresent(builder::setBackupDirectory);
|
||||
Optional.ofNullable(preferredTradeCurrency).ifPresent(e -> builder.setPreferredTradeCurrency((protobuf.TradeCurrency) e.toProtoMessage()));
|
||||
@ -334,7 +336,8 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
||||
proto.getUserHasRaisedTradeLimit() ? proto.getUserDefinedTradeLimit() : Preferences.INITIAL_TRADE_LIMIT,
|
||||
proto.getUserHasRaisedTradeLimit(),
|
||||
proto.getProcessBurningManAccountingData(),
|
||||
proto.getIsFullBMAccountingNode()
|
||||
proto.getIsFullBMAccountingNode(),
|
||||
proto.getUseBisqWalletFunding()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,10 @@ shared.nextStep=Next step
|
||||
shared.fundFromSavingsWalletButton=Transfer funds from Bisq wallet
|
||||
shared.fundFromExternalWalletButton=Open your external wallet for funding
|
||||
shared.openDefaultWalletFailed=Failed to open a Bitcoin wallet application. Are you sure you have one installed?
|
||||
shared.question.useBisqWalletForFunding=Would you like to always use your Bisq wallet for funding?\n\n\
|
||||
The make/take offer process will take less steps by choosing this. \
|
||||
However, funding from an external wallet could potentially be better for privacy.\n\n\
|
||||
(This can be also be controlled in Settings: "Fund offer/trades from Bisq wallet").
|
||||
shared.belowInPercent=Below % from market price
|
||||
shared.aboveInPercent=Above % from market price
|
||||
shared.enterPercentageValue=Enter % value
|
||||
@ -1405,6 +1409,8 @@ setting.preferences.useBitcoinUris.tooltip=Bisq's QR codes can either store bitc
|
||||
with some extra parameters (amount & label) or plain bitcoin addresses\n\
|
||||
with no additional data. Disable this option if your external wallet's\n\
|
||||
scanner cannot handle the bitcoin URI scheme format.
|
||||
setting.preferences.useBisqWalletForFunding=Fund offer/trades from Bisq wallet
|
||||
setting.preferences.useBisqWalletForFunding.tooltip=The make/take offer process will be streamlined to take fewer steps if this option is enabled.
|
||||
setting.preferences.currenciesInList=Currencies in market price feed list
|
||||
setting.preferences.prefCurrency=Preferred currency
|
||||
setting.preferences.displayFiat=Display national currencies
|
||||
|
@ -430,7 +430,12 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
||||
advancedOptionsBox.setManaged(false);
|
||||
|
||||
model.onShowPayFundsScreen(() -> {
|
||||
if (!DevEnv.isDevMode()) {
|
||||
totalToPayTextField.setFundsStructure(model.getFundsStructure());
|
||||
totalToPayTextField.setContentForInfoPopOver(createInfoPopover());
|
||||
|
||||
if (preferences.isUseBisqWalletFunding()) {
|
||||
model.fundFromSavingsWallet();
|
||||
} else {
|
||||
String key = "createOfferFundWalletInfo";
|
||||
String tradeAmountText = model.isSellOffer() ?
|
||||
Res.get("createOffer.createOfferFundWalletInfo.tradeAmount", model.getTradeAmount()) : "";
|
||||
@ -447,9 +452,6 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
||||
.dontShowAgainId(key)
|
||||
.show();
|
||||
}
|
||||
|
||||
totalToPayTextField.setFundsStructure(model.getFundsStructure());
|
||||
totalToPayTextField.setContentForInfoPopOver(createInfoPopover());
|
||||
});
|
||||
|
||||
paymentAccountsComboBox.setDisable(true);
|
||||
@ -467,7 +469,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
||||
|
||||
balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get());
|
||||
|
||||
if (!DevEnv.isDevMode()) {
|
||||
if (!preferences.isUseBisqWalletFunding()) {
|
||||
String key = "securityDepositInfo";
|
||||
new Popup().backgroundInfo(Res.get("popup.info.securityDepositInfo"))
|
||||
.actionButtonText(Res.get("shared.faq"))
|
||||
@ -822,6 +824,9 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
||||
.autoClose();
|
||||
|
||||
walletFundedNotification.show();
|
||||
if (preferences.isUseBisqWalletFunding()) { // potentially bypass review step to the confirmation popup
|
||||
UserThread.execute(this::onPlaceOffer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1254,7 +1259,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
||||
fundFromSavingsWalletButton = new AutoTooltipButton(Res.get("shared.fundFromSavingsWalletButton"));
|
||||
fundFromSavingsWalletButton.setDefaultButton(true);
|
||||
fundFromSavingsWalletButton.getStyleClass().add("action-button");
|
||||
fundFromSavingsWalletButton.setOnAction(e -> model.fundFromSavingsWallet());
|
||||
fundFromSavingsWalletButton.setOnAction(e -> GUIUtil.maybeAskAboutStreamliningOrderFunding(
|
||||
model::savePreferenceAndFundFromSavingsWallet, model::fundFromSavingsWallet));
|
||||
Label label = new AutoTooltipLabel(Res.get("shared.OR"));
|
||||
label.setPadding(new Insets(5, 0, 0, 0));
|
||||
Button fundFromExternalWalletButton = new AutoTooltipButton(Res.get("shared.fundFromExternalWalletButton"));
|
||||
|
@ -690,6 +690,11 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
updateSpinnerInfo();
|
||||
}
|
||||
|
||||
void savePreferenceAndFundFromSavingsWallet() {
|
||||
preferences.setUseBisqWalletFunding(true);
|
||||
fundFromSavingsWallet();
|
||||
}
|
||||
|
||||
void fundFromSavingsWallet() {
|
||||
dataModel.fundFromSavingsWallet();
|
||||
if (dataModel.getIsBtcWalletFunded().get()) {
|
||||
|
@ -59,6 +59,7 @@ import bisq.core.payment.FasterPaymentsAccount;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.user.DontShowAgainLookup;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
@ -126,6 +127,7 @@ import static javafx.beans.binding.Bindings.createStringBinding;
|
||||
@FxmlView
|
||||
public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOfferViewModel> implements ClosableView, InitializableViewWithTakeOfferData, SelectableView {
|
||||
private final Navigation navigation;
|
||||
private final Preferences preferences;
|
||||
private final CoinFormatter formatter;
|
||||
private final BsqFormatter bsqFormatter;
|
||||
private final OfferDetailsWindow offerDetailsWindow;
|
||||
@ -184,6 +186,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
@Inject
|
||||
private TakeOfferView(TakeOfferViewModel model,
|
||||
Navigation navigation,
|
||||
Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
|
||||
BsqFormatter bsqFormatter,
|
||||
OfferDetailsWindow offerDetailsWindow,
|
||||
@ -191,6 +194,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
super(model);
|
||||
|
||||
this.navigation = navigation;
|
||||
this.preferences = preferences;
|
||||
this.formatter = formatter;
|
||||
this.bsqFormatter = bsqFormatter;
|
||||
this.offerDetailsWindow = offerDetailsWindow;
|
||||
@ -224,6 +228,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
.autoClose();
|
||||
|
||||
walletFundedNotification.show();
|
||||
if (preferences.isUseBisqWalletFunding()) { // potentially bypass review step to the confirmation popup
|
||||
UserThread.execute(this::onTakeOffer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -504,7 +511,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
|
||||
balanceTextField.setTargetAmount(model.dataModel.getTotalToPayAsCoin().get());
|
||||
|
||||
if (!DevEnv.isDevMode()) {
|
||||
if (preferences.isUseBisqWalletFunding()) {
|
||||
model.fundFromSavingsWallet();
|
||||
} else {
|
||||
String key = "securityDepositInfo";
|
||||
new Popup().backgroundInfo(Res.get("popup.info.securityDepositInfo"))
|
||||
.actionButtonText(Res.get("shared.faq"))
|
||||
@ -995,7 +1004,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
fundFromSavingsWalletButton = new AutoTooltipButton(Res.get("shared.fundFromSavingsWalletButton"));
|
||||
fundFromSavingsWalletButton.setDefaultButton(true);
|
||||
fundFromSavingsWalletButton.getStyleClass().add("action-button");
|
||||
fundFromSavingsWalletButton.setOnAction(e -> model.fundFromSavingsWallet());
|
||||
fundFromSavingsWalletButton.setOnAction(e -> GUIUtil.maybeAskAboutStreamliningOrderFunding(
|
||||
model::savePreferenceAndFundFromSavingsWallet, model::fundFromSavingsWallet));
|
||||
Label label = new AutoTooltipLabel(Res.get("shared.OR"));
|
||||
label.setPadding(new Insets(5, 0, 0, 0));
|
||||
Button fundFromExternalWalletButton = new AutoTooltipButton(Res.get("shared.fundFromExternalWalletButton"));
|
||||
|
@ -41,6 +41,7 @@ import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
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.BsqFormatter;
|
||||
@ -86,6 +87,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
private final P2PService p2PService;
|
||||
private final AccountAgeWitnessService accountAgeWitnessService;
|
||||
private final Navigation navigation;
|
||||
private final Preferences preferences;
|
||||
private final CoinFormatter btcFormatter;
|
||||
private final BsqFormatter bsqFormatter;
|
||||
|
||||
@ -145,6 +147,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
P2PService p2PService,
|
||||
AccountAgeWitnessService accountAgeWitnessService,
|
||||
Navigation navigation,
|
||||
Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
|
||||
BsqFormatter bsqFormatter) {
|
||||
super(dataModel);
|
||||
@ -154,6 +157,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
this.p2PService = p2PService;
|
||||
this.accountAgeWitnessService = accountAgeWitnessService;
|
||||
this.navigation = navigation;
|
||||
this.preferences = preferences;
|
||||
this.btcFormatter = btcFormatter;
|
||||
this.bsqFormatter = bsqFormatter;
|
||||
createListeners();
|
||||
@ -266,6 +270,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
updateSpinnerInfo();
|
||||
}
|
||||
|
||||
void savePreferenceAndFundFromSavingsWallet() {
|
||||
preferences.setUseBisqWalletFunding(true);
|
||||
fundFromSavingsWallet();
|
||||
}
|
||||
|
||||
boolean fundFromSavingsWallet() {
|
||||
dataModel.fundFromSavingsWallet();
|
||||
if (dataModel.getIsBtcWalletFunded().get()) {
|
||||
|
@ -134,7 +134,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
avoidStandbyMode, useCustomFee, autoConfirmXmrToggle, hideNonAccountPaymentMethodsToggle, denyApiTakerToggle,
|
||||
notifyOnPreReleaseToggle, isDaoFullNodeToggleButton,
|
||||
fullModeDaoMonitorToggleButton, useBitcoinUrisToggle, tradeLimitToggle, processBurningManAccountingDataToggleButton,
|
||||
isFullBMAccountingDataNodeToggleButton;
|
||||
isFullBMAccountingDataNodeToggleButton, useBisqWalletForFundingToggle;
|
||||
private int gridRow = 0;
|
||||
private int displayCurrenciesGridRowIndex = 0;
|
||||
private InputTextField transactionFeeInputTextField, ignoreTradersListInputTextField, ignoreDustThresholdInputTextField,
|
||||
@ -286,7 +286,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void initializeGeneralOptions() {
|
||||
int titledGroupBgRowSpan = displayStandbyModeFeature ? 11 : 10;
|
||||
int titledGroupBgRowSpan = displayStandbyModeFeature ? 12 : 11;
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, titledGroupBgRowSpan, Res.get("setting.preferences.general"));
|
||||
GridPane.setColumnSpan(titledGroupBg, 1);
|
||||
|
||||
@ -440,12 +440,23 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
Res.get("setting.preferences.avoidStandbyMode"));
|
||||
}
|
||||
|
||||
useBitcoinUrisToggle = addSlideToggleButton(root, ++gridRow, Res.get("setting.preferences.useBitcoinUris"));
|
||||
Tooltip tooltip = new Tooltip(Res.get("setting.preferences.useBitcoinUris.tooltip"));
|
||||
tooltip.setShowDuration(Duration.millis(8000));
|
||||
tooltip.setShowDelay(Duration.millis(300));
|
||||
tooltip.setHideDelay(Duration.millis(0));
|
||||
Tooltip.install(useBitcoinUrisToggle, tooltip);
|
||||
{
|
||||
useBitcoinUrisToggle = addSlideToggleButton(root, ++gridRow, Res.get("setting.preferences.useBitcoinUris"));
|
||||
Tooltip tooltip = new Tooltip(Res.get("setting.preferences.useBitcoinUris.tooltip"));
|
||||
tooltip.setShowDuration(Duration.millis(8000));
|
||||
tooltip.setShowDelay(Duration.millis(300));
|
||||
tooltip.setHideDelay(Duration.millis(0));
|
||||
Tooltip.install(useBitcoinUrisToggle, tooltip);
|
||||
}
|
||||
|
||||
{
|
||||
useBisqWalletForFundingToggle = addSlideToggleButton(root, ++gridRow, Res.get("setting.preferences.useBisqWalletForFunding"));
|
||||
Tooltip tooltip = new Tooltip(Res.get("setting.preferences.useBisqWalletForFunding.tooltip"));
|
||||
tooltip.setShowDuration(Duration.millis(8000));
|
||||
tooltip.setShowDelay(Duration.millis(300));
|
||||
tooltip.setHideDelay(Duration.millis(0));
|
||||
Tooltip.install(useBisqWalletForFundingToggle, tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeSeparator() {
|
||||
@ -990,6 +1001,10 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
useBitcoinUrisToggle.setOnAction(e ->
|
||||
preferences.setUseBitcoinUrisInQrCodes(useBitcoinUrisToggle.isSelected()));
|
||||
|
||||
useBisqWalletForFundingToggle.setSelected(preferences.isUseBisqWalletFunding());
|
||||
useBisqWalletForFundingToggle.setOnAction(e ->
|
||||
preferences.setUseBisqWalletFunding(useBisqWalletForFundingToggle.isSelected()));
|
||||
|
||||
btcExplorerTextField.setText(preferences.getBlockChainExplorer().name);
|
||||
bsqExplorerTextField.setText(preferences.getBsqBlockChainExplorer().name);
|
||||
|
||||
@ -1362,6 +1377,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
editCustomBtcExplorer.setOnAction(null);
|
||||
editCustomBsqExplorer.setOnAction(null);
|
||||
useBitcoinUrisToggle.setOnAction(null);
|
||||
useBisqWalletForFundingToggle.setOnAction(null);
|
||||
deviationInputTextField.textProperty().removeListener(deviationListener);
|
||||
deviationInputTextField.focusedProperty().removeListener(deviationFocusedListener);
|
||||
transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);
|
||||
|
@ -803,6 +803,23 @@ public class GUIUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void maybeAskAboutStreamliningOrderFunding(Runnable actionHandlerYes, Runnable actionHandlerNo) {
|
||||
String key = "ask_always_use_bisq_wallet";
|
||||
if (!preferences.isUseBisqWalletFunding() && DontShowAgainLookup.showAgain(key)) {
|
||||
// user clicks on "Fund from Bisq wallet",
|
||||
// ask user if they want to in the future always fund from Bisq wallet
|
||||
new Popup().instruction(Res.get("shared.question.useBisqWalletForFunding"))
|
||||
.actionButtonText(Res.get("shared.yes"))
|
||||
.onAction(actionHandlerYes)
|
||||
.closeButtonText(Res.get("shared.no"))
|
||||
.onClose(actionHandlerNo)
|
||||
.dontShowAgainId(key)
|
||||
.show();
|
||||
} else {
|
||||
actionHandlerNo.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isReadyForTxBroadcastOrShowPopup(P2PService p2PService, WalletsSetup walletsSetup) {
|
||||
if (!GUIUtil.isBootstrappedOrShowPopup(p2PService)) {
|
||||
return false;
|
||||
|
@ -1973,6 +1973,7 @@ message PreferencesPayload {
|
||||
bool user_has_raised_trade_limit = 68;
|
||||
bool process_burning_man_accounting_data = 69;
|
||||
bool is_full_b_m_accounting_node = 70;
|
||||
bool use_bisq_wallet_funding = 71;
|
||||
}
|
||||
|
||||
message AutoConfirmSettings {
|
||||
|
Loading…
Reference in New Issue
Block a user