From f59d6fe591593e34d9c0d02bb1436cf2c672aa8d Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:28:30 +0100 Subject: [PATCH 01/25] Add "Buy BSQ" button next to trade fee selector Conflicts: desktop/src/main/java/bisq/desktop/main/offer/OfferView.java --- .../resources/i18n/displayStrings.properties | 4 +++ .../bisq/desktop/main/offer/OfferView.java | 30 +++++++++------- .../main/offer/bisq_v1/MutableOfferView.java | 14 ++++++-- .../main/offer/bisq_v1/OfferViewUtil.java | 36 +++++++++++++++++++ .../bisq_v1/takeoffer/TakeOfferView.java | 4 ++- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 04f2a585ac7..7ec8e6aae00 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -481,6 +481,10 @@ createOffer.triggerPrice.tooltip=As protection against drastic price movements y createOffer.triggerPrice.invalid.tooLow=Value must be higher than {0} createOffer.triggerPrice.invalid.tooHigh=Value must be lower than {0} +createOffer.buyBsq.popupMessage=Trading fees are paid to fund the Bisq DAO when making or taking an offer. Fees can be paid in BSQ or BTC.\n\n\ + Bisq encourages traders to use BSQ by offering a discount of approximately 50%, since BSQ fees help fund Bisq's development. \ + This discount varies as the BSQ/BTC rate fluctuates. To maintain the 50% discount target, trading fees are updated every cycle as necessary. + # new entries createOffer.placeOfferButton=Review: Place offer to {0} bitcoin createOffer.createOfferFundWalletInfo.headline=Fund your offer diff --git a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java index 8e828c42047..5374cfd1344 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java @@ -176,7 +176,9 @@ protected void activate() { root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener); root.getTabs().addListener(tabListChangeListener); navigation.addListener(navigationListener); - navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class); + if (offerBookView == null) { + navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class); + } } @Override @@ -202,17 +204,21 @@ private void loadView(Class viewClass) { View view; boolean isBuy = direction == OfferDirection.BUY; - if (viewClass == OfferBookView.class && offerBookView == null) { - view = viewLoader.load(viewClass); - // Offerbook must not be cached by ViewLoader as we use 2 instances for sell and buy screens. - offerBookTab = new Tab(isBuy ? Res.get("shared.buyBitcoin").toUpperCase() : Res.get("shared.sellBitcoin").toUpperCase()); - offerBookTab.setClosable(false); - offerBookTab.setContent(view.getRoot()); - tabPane.getTabs().add(offerBookTab); - offerBookView = (OfferBookView) view; - offerBookView.onTabSelected(true); - offerBookView.setOfferActionHandler(offerActionHandler); - offerBookView.setDirection(direction); + if (viewClass == OfferBookView.class) { + if (offerBookTab != null && offerBookView != null) { + tabPane.getSelectionModel().select(offerBookTab); + } else { + view = viewLoader.load(viewClass); + // Offerbook must not be cached by ViewLoader as we use 2 instances for sell and buy screens. + offerBookTab = new Tab(isBuy ? Res.get("shared.buyBitcoin").toUpperCase() : Res.get("shared.sellBitcoin").toUpperCase()); + offerBookTab.setClosable(false); + offerBookTab.setContent(view.getRoot()); + tabPane.getTabs().add(offerBookTab); + offerBookView = (OfferBookView) view; + offerBookView.onTabSelected(true); + offerBookView.setOfferActionHandler(offerActionHandler); + offerBookView.setDirection(direction); + } } else if (viewClass == CreateOfferView.class && createOfferView == null) { view = viewLoader.load(viewClass); // CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index 07a86f35e44..d493dfa2503 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -137,7 +137,7 @@ public abstract class MutableOfferView> exten private TitledGroupBg payFundsTitledGroupBg, setDepositTitledGroupBg, paymentTitledGroupBg; protected TitledGroupBg amountTitledGroupBg; private BusyAnimation waitingForFundsSpinner; - private AutoTooltipButton nextButton, cancelButton1, cancelButton2, placeOfferButton; + private AutoTooltipButton nextButton, cancelButton1, cancelButton2, placeOfferButton, buyBsqButton; private Button priceTypeToggleButton; private InputTextField fixedPriceTextField, marketBasedPriceTextField, triggerPriceInputTextField; protected InputTextField amountTextField, minAmountTextField, volumeTextField, buyerSecurityDepositInputTextField; @@ -270,6 +270,8 @@ protected void doActivate() { tradeFeeInBtcToggle.setManaged(false); tradeFeeInBsqToggle.setVisible(false); tradeFeeInBsqToggle.setManaged(false); + buyBsqButton.setVisible(false); + buyBsqButton.setManaged(false); } Label popOverLabel = OfferViewUtil.createPopOverLabel(Res.get("createOffer.triggerPrice.tooltip")); @@ -397,6 +399,9 @@ private void onShowPayFundsScreen() { cancelButton1.setVisible(false); cancelButton1.setManaged(false); cancelButton1.setOnAction(null); + buyBsqButton.setVisible(false); + buyBsqButton.setManaged(false); + buyBsqButton.setOnAction(null); tradeFeeInBtcToggle.setMouseTransparent(true); tradeFeeInBsqToggle.setMouseTransparent(true); @@ -894,6 +899,7 @@ private void createListeners() { if (DevEnv.isDaoActivated()) { tradeFeeInBtcToggle.setVisible(newValue); tradeFeeInBsqToggle.setVisible(newValue); + buyBsqButton.setVisible(newValue); } }; @@ -1110,7 +1116,11 @@ private void addOptionsGroup() { GridPane.setMargin(advancedOptionsBox, new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); gridPane.getChildren().add(advancedOptionsBox); - advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), getTradeFeeFieldsBox()); + Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox(navigation, preferences); + buyBsqButton = buyBsqButtonBox.first; + buyBsqButton.setVisible(false); + + advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), getTradeFeeFieldsBox(), buyBsqButtonBox.second); Tuple2 tuple = add2ButtonsAfterGroup(gridPane, ++gridRow, Res.get("shared.nextStep"), Res.get("shared.cancel")); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index f5aff0937d7..5d0d6b55e6e 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -17,9 +17,23 @@ package bisq.desktop.main.offer.bisq_v1; +import bisq.desktop.Navigation; +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.main.MainView; +import bisq.desktop.main.offer.offerbook.OfferBookView; +import bisq.desktop.main.overlays.popups.Popup; + +import bisq.core.locale.Res; +import bisq.core.user.Preferences; + +import bisq.common.util.Tuple2; + import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import javafx.geometry.HPos; import javafx.geometry.Insets; +import javafx.geometry.Pos; // Shared utils for Views public class OfferViewUtil { @@ -31,4 +45,26 @@ public static Label createPopOverLabel(String text) { label.setPadding(new Insets(10)); return label; } + + public static Tuple2 createBuyBsqButtonBox(Navigation navigation, Preferences preferences) { + String buyBsqText = Res.get("shared.buyCurrency", "BSQ"); + var buyBsqButton = new AutoTooltipButton(buyBsqText); + buyBsqButton.getStyleClass().add("action-button"); + buyBsqButton.setStyle("-fx-pref-height: 20; -fx-padding: 3 8 3 8; -fx-font-size: 0.769em; -fx-border-radius: 5;"); + buyBsqButton.setOnAction(e -> new Popup().headLine(buyBsqText) + .information(Res.get("createOffer.buyBsq.popupMessage")) + .actionButtonText(buyBsqText) + .buttonAlignment(HPos.CENTER) + .onAction(() -> { + preferences.setSellScreenCurrencyCode("BSQ"); + navigation.navigateTo(MainView.class, SellOfferView.class, OfferBookView.class); + }).show()); + + final VBox buyBsqButtonVBox = new VBox(buyBsqButton); + buyBsqButtonVBox.setAlignment(Pos.BOTTOM_LEFT); + buyBsqButtonVBox.setPadding(new Insets(0, 0, 0, -20)); + VBox.setMargin(buyBsqButton, new Insets(0, 0, 4, 0)); + + return new Tuple2<>(buyBsqButton, buyBsqButtonVBox); + } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index 3eb24820233..bab6cb80168 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -884,7 +884,9 @@ private void addOptionsGroup() { GridPane.setMargin(advancedOptionsBox, new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); gridPane.getChildren().add(advancedOptionsBox); - advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox()); + Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox(navigation, model.dataModel.preferences); + + advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox(), buyBsqButtonBox.second); } private void addButtons() { From 107cc3a8dd33171a7c8feab12a5d3d6359178e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Louck=C3=BD?= Date: Fri, 1 Jan 2021 21:15:29 +0100 Subject: [PATCH 02/25] Tiny refactoring --- desktop/src/main/java/bisq/desktop/main/offer/OfferView.java | 2 +- .../java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java index 5374cfd1344..cb61fe568b8 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java @@ -253,7 +253,7 @@ private void loadView(Class viewClass) { // in different graphs takeOfferView = (TakeOfferView) view; takeOfferView.initWithData(offer); - takeOfferPane = ((TakeOfferView) view).getRoot(); + takeOfferPane = takeOfferView.getRoot(); takeOfferTab = new Tab(getTakeOfferTabName()); takeOfferTab.setClosable(true); // close handler from close on take offer action diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index d493dfa2503..fd51553ce60 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -338,7 +338,7 @@ public void initWithData(OfferDirection direction, TradeCurrency tradeCurrency, showInsufficientBsqFundsForBtcFeePaymentPopup(); } - // called form parent as the view does not get notified when the tab is closed + // called from parent as the view does not get notified when the tab is closed public void onClose() { // we use model.placeOfferCompleted to not react on close which was triggered by a successful placeOffer if (model.getDataModel().getBalance().get().isPositive() && !model.placeOfferCompleted.get()) { From 4c770442744b781f03a693f9eed00636d1a2fab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Louck=C3=BD?= Date: Sun, 16 May 2021 19:58:31 +0200 Subject: [PATCH 03/25] Move button style to bisq.css Add link to bisq.wiki --- core/src/main/resources/i18n/displayStrings.properties | 3 ++- desktop/src/main/java/bisq/desktop/bisq.css | 7 +++++++ .../bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 7ec8e6aae00..673f7ad5cb1 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -483,7 +483,8 @@ createOffer.triggerPrice.invalid.tooHigh=Value must be lower than {0} createOffer.buyBsq.popupMessage=Trading fees are paid to fund the Bisq DAO when making or taking an offer. Fees can be paid in BSQ or BTC.\n\n\ Bisq encourages traders to use BSQ by offering a discount of approximately 50%, since BSQ fees help fund Bisq's development. \ - This discount varies as the BSQ/BTC rate fluctuates. To maintain the 50% discount target, trading fees are updated every cycle as necessary. + This discount varies as the BSQ/BTC rate fluctuates. To maintain the 50% discount target, trading fees are updated every cycle as necessary.\n\n\ + For more details see [HYPERLINK:https://bisq.wiki/Trading_fees] # new entries createOffer.placeOfferButton=Review: Place offer to {0} bitcoin diff --git a/desktop/src/main/java/bisq/desktop/bisq.css b/desktop/src/main/java/bisq/desktop/bisq.css index d8aac0472d6..8037df530b4 100644 --- a/desktop/src/main/java/bisq/desktop/bisq.css +++ b/desktop/src/main/java/bisq/desktop/bisq.css @@ -175,6 +175,13 @@ -fx-padding: 0 10 0 10; } +.tiny-button, .action-button.tiny-button { + -fx-font-size: 0.769em; + -fx-pref-height: 20; + -fx-padding: 3 8 3 8; + -fx-border-radius: 5; +} + .text-button { -fx-background-color: transparent; -fx-underline: true; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 5d0d6b55e6e..09d4247c67d 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -50,7 +50,7 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n String buyBsqText = Res.get("shared.buyCurrency", "BSQ"); var buyBsqButton = new AutoTooltipButton(buyBsqText); buyBsqButton.getStyleClass().add("action-button"); - buyBsqButton.setStyle("-fx-pref-height: 20; -fx-padding: 3 8 3 8; -fx-font-size: 0.769em; -fx-border-radius: 5;"); + buyBsqButton.getStyleClass().add("tiny-button"); buyBsqButton.setOnAction(e -> new Popup().headLine(buyBsqText) .information(Res.get("createOffer.buyBsq.popupMessage")) .actionButtonText(buyBsqText) From 57b9c6f13820fbf4b65083b21edbd918d9b60c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Louck=C3=BD?= Date: Mon, 17 May 2021 23:57:28 +0200 Subject: [PATCH 04/25] Display button only when insufficient BSQ funds --- .../bisq/desktop/main/offer/bisq_v1/MutableOfferView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index fd51553ce60..dd3511df297 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -899,7 +899,9 @@ private void createListeners() { if (DevEnv.isDaoActivated()) { tradeFeeInBtcToggle.setVisible(newValue); tradeFeeInBsqToggle.setVisible(newValue); - buyBsqButton.setVisible(newValue); + if (!(newValue && model.dataModel.isBsqForFeeAvailable())) { + buyBsqButton.setVisible(newValue); + } } }; From 717d7c205b3341d39e4fc978612dd2f0ccf8e86d Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:35:50 +0100 Subject: [PATCH 05/25] Close current SELL offer tab TODO: fix bug with currency combobox Conflicts: desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java --- .../main/offer/bisq_v1/MutableOfferView.java | 16 +++++++++++++++- .../main/offer/bisq_v1/OfferViewUtil.java | 14 ++++++++++++-- .../offer/bisq_v1/takeoffer/TakeOfferView.java | 3 ++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index dd3511df297..e57614d2e9b 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -168,6 +168,7 @@ public abstract class MutableOfferView> exten private ChangeListener tradeCurrencyCodeListener, errorMessageListener, marketPriceMarginListener, volumeListener, buyerSecurityDepositInBTCListener; private ChangeListener marketPriceAvailableListener; + private Navigation.Listener navigationWithCloseListener; private EventHandler currencyComboBoxSelectionHandler, paymentAccountsComboBoxSelectionHandler; private OfferView.CloseHandler closeHandler; @@ -916,6 +917,14 @@ private void createListeners() { buyerSecurityDepositInputTextField.setDisable(false); } }); + + navigationWithCloseListener = (path, data) -> { + log.warn("*** target path={}, data={}, dir={}", path, data, model.getDataModel().getDirection()); + if ("closeOfferView".equals(data)) { + log.warn("*** WILL CLOSE"); + close(); + } + }; } private void setIsCurrencyForMakerFeeBtc(boolean isCurrencyForMakerFeeBtc) { @@ -972,6 +981,8 @@ private void addListeners() { // UI actions paymentAccountsComboBox.setOnAction(paymentAccountsComboBoxSelectionHandler); currencyComboBox.setOnAction(currencyComboBoxSelectionHandler); + + navigation.addListener(navigationWithCloseListener); } private void removeListeners() { @@ -1007,6 +1018,8 @@ private void removeListeners() { // UI actions paymentAccountsComboBox.setOnAction(null); currencyComboBox.setOnAction(null); + + navigation.removeListener(navigationWithCloseListener); } @@ -1118,7 +1131,8 @@ private void addOptionsGroup() { GridPane.setMargin(advancedOptionsBox, new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); gridPane.getChildren().add(advancedOptionsBox); - Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox(navigation, preferences); + Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( + navigation, preferences, model.dataModel::getDirection); buyBsqButton = buyBsqButtonBox.first; buyBsqButton.setVisible(false); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 09d4247c67d..3a3acec2925 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -24,6 +24,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.core.locale.Res; +import bisq.core.offer.OfferPayload; import bisq.core.user.Preferences; import bisq.common.util.Tuple2; @@ -46,7 +47,13 @@ public static Label createPopOverLabel(String text) { return label; } - public static Tuple2 createBuyBsqButtonBox(Navigation navigation, Preferences preferences) { + public interface DirectionClosure { + OfferPayload.Direction getDirection(); + } + + public static Tuple2 createBuyBsqButtonBox(Navigation navigation, + Preferences preferences, + DirectionClosure directionClosure) { String buyBsqText = Res.get("shared.buyCurrency", "BSQ"); var buyBsqButton = new AutoTooltipButton(buyBsqText); buyBsqButton.getStyleClass().add("action-button"); @@ -57,7 +64,10 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n .buttonAlignment(HPos.CENTER) .onAction(() -> { preferences.setSellScreenCurrencyCode("BSQ"); - navigation.navigateTo(MainView.class, SellOfferView.class, OfferBookView.class); + navigation.navigateToWithData( + // FIXME: replace "closeOfferView" with a more unique object? + directionClosure.getDirection() == OfferPayload.Direction.SELL ? "closeOfferView" : null, + MainView.class, SellOfferView.class, OfferBookView.class); }).show()); final VBox buyBsqButtonVBox = new VBox(buyBsqButton); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index bab6cb80168..9dbaca83590 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -884,7 +884,8 @@ private void addOptionsGroup() { GridPane.setMargin(advancedOptionsBox, new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); gridPane.getChildren().add(advancedOptionsBox); - Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox(navigation, model.dataModel.preferences); + Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( + navigation, model.dataModel.preferences, model.dataModel::getDirection); advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox(), buyBsqButtonBox.second); } From 6692ce574c7df626cf693fa342b8ec2267d50b5f Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Mon, 4 Oct 2021 11:19:40 +0200 Subject: [PATCH 06/25] Improve wording Co-authored-by: m52go <735155+m52go@users.noreply.github.com> --- core/src/main/resources/i18n/displayStrings.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 673f7ad5cb1..610a939149f 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -481,10 +481,10 @@ createOffer.triggerPrice.tooltip=As protection against drastic price movements y createOffer.triggerPrice.invalid.tooLow=Value must be higher than {0} createOffer.triggerPrice.invalid.tooHigh=Value must be lower than {0} -createOffer.buyBsq.popupMessage=Trading fees are paid to fund the Bisq DAO when making or taking an offer. Fees can be paid in BSQ or BTC.\n\n\ - Bisq encourages traders to use BSQ by offering a discount of approximately 50%, since BSQ fees help fund Bisq's development. \ +createOffer.buyBsq.popupMessage=Trading fees are paid to fund the Bisq DAO. Fees can be paid in BSQ or BTC.\n\n\ + BSQ fees directly help fund Bisq's development, so Bisq encourages traders to use BSQ by offering a 50% discount on trading fees. \ This discount varies as the BSQ/BTC rate fluctuates. To maintain the 50% discount target, trading fees are updated every cycle as necessary.\n\n\ - For more details see [HYPERLINK:https://bisq.wiki/Trading_fees] + For more about fees, see [HYPERLINK:https://bisq.wiki/Trading_fees]. For more about the Bisq DAO, see [HYPERLINK:https://bisq.wiki/Introduction_to_the_DAO#The_Bisq_DAO]. # new entries createOffer.placeOfferButton=Review: Place offer to {0} bitcoin From 35e76e30b2ea8c0ec2ebbf646a35fc9abd9bf912 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 30 Sep 2021 12:26:42 +0200 Subject: [PATCH 07/25] Add Button to confirm payment in BSQ wallet --- .../resources/i18n/displayStrings.properties | 1 + .../steps/seller/SellerStep3View.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 610a939149f..e050df1b73d 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -865,6 +865,7 @@ portfolio.pending.step3_seller.xmrTxHash=Transaction ID portfolio.pending.step3_seller.xmrTxKey=Transaction key portfolio.pending.step3_seller.buyersAccount=Buyers account data portfolio.pending.step3_seller.confirmReceipt=Confirm payment receipt +portfolio.pending.step3_seller.showBsqWallet=Show payment in BSQ wallet portfolio.pending.step3_seller.buyerStartedPayment=The BTC buyer has started the {0} payment.\n{1} portfolio.pending.step3_seller.buyerStartedPayment.altcoin=Check for blockchain confirmations at your altcoin wallet or block explorer and confirm the payment when you have sufficient blockchain confirmations. portfolio.pending.step3_seller.buyerStartedPayment.fiat=Check at your trading account (e.g. bank account) and confirm when you have received the payment. diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java index cb6715a5738..2d9c46e5b55 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java @@ -17,10 +17,15 @@ package bisq.desktop.main.portfolio.pendingtrades.steps.seller; +import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.InfoTextField; import bisq.desktop.components.TextFieldWithCopyIcon; import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.DaoView; +import bisq.desktop.main.dao.wallet.BsqWalletView; +import bisq.desktop.main.dao.wallet.tx.BsqTxView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel; import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView; @@ -82,6 +87,7 @@ public class SellerStep3View extends TradeStepView { private Button confirmButton; + private AutoTooltipButton showBsqWallet; private Label statusLabel; private BusyAnimation busyAnimation; private Subscription tradeStatePropertySubscription; @@ -296,11 +302,21 @@ protected void addContent() { Tuple4 tuple = addButtonBusyAnimationLabelAfterGroup(gridPane, ++gridRow, Res.get("portfolio.pending.step3_seller.confirmReceipt")); + HBox hBox = tuple.fourth; GridPane.setColumnSpan(tuple.fourth, 2); confirmButton = tuple.first; confirmButton.setOnAction(e -> onPaymentReceived()); busyAnimation = tuple.second; statusLabel = tuple.third; + + if (trade.getOffer().getCurrencyCode().equals("BSQ")) { + showBsqWallet = new AutoTooltipButton(Res.get("portfolio.pending.step3_seller.showBsqWallet")); + hBox.getChildren().add(1, showBsqWallet); + showBsqWallet.setOnAction(e -> { + model.getNavigation().navigateTo(MainView.class, DaoView.class, BsqWalletView.class, + BsqTxView.class); + }); + } } From 9cf373a9bb1fcee7b4c09932ced0d7fdf43c82e2 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Wed, 6 Oct 2021 10:36:06 +0200 Subject: [PATCH 08/25] Not show buy bsq hint for buy bsq offers --- .../desktop/main/offer/bisq_v1/MutableOfferDataModel.java | 4 ++++ .../bisq/desktop/main/offer/bisq_v1/MutableOfferView.java | 2 +- .../desktop/main/offer/bisq_v1/MutableOfferViewModel.java | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java index 3321e647076..da401709ee2 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java @@ -781,6 +781,10 @@ boolean isBsqForFeeAvailable() { return offerUtil.isBsqForMakerFeeAvailable(amount.get()); } + boolean isBuyBsqOffer() { + return !isBuyOffer() && getTradeCurrency().getCode().equals("BSQ"); + } + boolean canPlaceOffer() { return GUIUtil.isBootstrappedOrShowPopup(p2PService) && GUIUtil.canCreateOrTakeOfferOrShowPopup(user, navigation, tradeCurrency); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index e57614d2e9b..e42ff2ccd0a 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -900,7 +900,7 @@ private void createListeners() { if (DevEnv.isDaoActivated()) { tradeFeeInBtcToggle.setVisible(newValue); tradeFeeInBsqToggle.setVisible(newValue); - if (!(newValue && model.dataModel.isBsqForFeeAvailable())) { + if (model.isShowBuyBsqHint()) { buyBsqButton.setVisible(newValue); } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java index 344966a0165..5121e2242ca 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java @@ -1355,4 +1355,8 @@ private void updateMarketPriceToManual() { } } } + + public boolean isShowBuyBsqHint() { + return !dataModel.isBsqForFeeAvailable() && !dataModel.isBuyBsqOffer(); + } } From e1b405f20bb30e0435117733955702b0df8e4ff8 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:36:46 +0100 Subject: [PATCH 09/25] Apply minor refactorings Conflicts: desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java --- .../main/offer/bisq_v1/MutableOfferView.java | 78 +++++-------------- .../offer/bisq_v1/MutableOfferViewModel.java | 4 +- .../bisq_v1/takeoffer/TakeOfferView.java | 49 ++---------- .../main/java/bisq/desktop/util/GUIUtil.java | 56 +++++++++++++ 4 files changed, 85 insertions(+), 102 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index e42ff2ccd0a..01e963fd277 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -83,7 +83,6 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -123,6 +122,7 @@ import static bisq.core.payment.payload.PaymentMethod.HAL_CASH_ID; import static bisq.desktop.util.FormBuilder.*; +import static bisq.desktop.util.GUIUtil.addPayInfoEntry; import static javafx.beans.binding.Bindings.createStringBinding; public abstract class MutableOfferView> extends ActivatableViewAndModel { @@ -375,6 +375,16 @@ private void onPlaceOffer() { } private void showInsufficientBsqFundsForBtcFeePaymentPopup() { + String message = getMissingBsqForFeePaymentMessage(); + + if (message != null) + new Popup().warning(message) + .actionButtonTextWithGoTo("navigation.dao.wallet.receive") + .onAction(() -> navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, BsqReceiveView.class)) + .show(); + } + + private String getMissingBsqForFeePaymentMessage() { Coin makerFee = model.getDataModel().getMakerFee(false); String message = null; if (makerFee != null) { @@ -384,11 +394,7 @@ private void showInsufficientBsqFundsForBtcFeePaymentPopup() { } else if (model.getDataModel().getUsableBsqBalance().isZero()) message = Res.get("popup.warning.noBsqFundsForBtcFeePayment"); - if (message != null) - new Popup().warning(message) - .actionButtonTextWithGoTo("navigation.dao.wallet.receive") - .onAction(() -> navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, BsqReceiveView.class)) - .show(); + return message; } private void onShowPayFundsScreen() { @@ -520,17 +526,7 @@ private void maybeShowFasterPaymentsWarning(PaymentAccount paymentAccount) { private void maybeShowAccountWarning(PaymentAccount paymentAccount, boolean isBuyer) { String msgKey = paymentAccount.getPreTradeMessage(isBuyer); - if (msgKey == null || paymentAccountWarningDisplayed.getOrDefault(msgKey, false)) { - return; - } - paymentAccountWarningDisplayed.put(msgKey, true); - UserThread.runAfter(() -> { - new Popup().information(Res.get(msgKey)) - .width(900) - .closeButtonText(Res.get("shared.iConfirm")) - .dontShowAgainId(msgKey) - .show(); - }, 500, TimeUnit.MILLISECONDS); + GUIUtil.showPaymentAccountWarning(msgKey, paymentAccountWarningDisplayed); } protected void onPaymentAccountsComboBoxSelected() { @@ -1028,15 +1024,7 @@ private void removeListeners() { /////////////////////////////////////////////////////////////////////////////////////////// private void addScrollPane() { - scrollPane = new ScrollPane(); - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setFitToWidth(true); - scrollPane.setFitToHeight(true); - AnchorPane.setLeftAnchor(scrollPane, 0d); - AnchorPane.setTopAnchor(scrollPane, 0d); - AnchorPane.setRightAnchor(scrollPane, 0d); - AnchorPane.setBottomAnchor(scrollPane, 0d); + scrollPane = GUIUtil.createScrollPane(); root.getChildren().add(scrollPane); } @@ -1046,13 +1034,7 @@ private void addGridPane() { gridPane.setPadding(new Insets(30, 25, -1, 25)); gridPane.setHgap(5); gridPane.setVgap(5); - ColumnConstraints columnConstraints1 = new ColumnConstraints(); - columnConstraints1.setHalignment(HPos.RIGHT); - columnConstraints1.setHgrow(Priority.NEVER); - columnConstraints1.setMinWidth(200); - ColumnConstraints columnConstraints2 = new ColumnConstraints(); - columnConstraints2.setHgrow(Priority.ALWAYS); - gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); + GUIUtil.setDefaultTwoColumnConstraintsForGridPane(gridPane); scrollPane.setContent(gridPane); } @@ -1178,15 +1160,7 @@ private void showFeeOption() { boolean isPreferredFeeCurrencyBtc = model.getDataModel().isPreferredFeeCurrencyBtc(); boolean isBsqForFeeAvailable = model.getDataModel().isBsqForFeeAvailable(); if (!isPreferredFeeCurrencyBtc && !isBsqForFeeAvailable) { - Coin makerFee = model.getDataModel().getMakerFee(false); - String missingBsq = null; - if (makerFee != null) { - missingBsq = Res.get("popup.warning.insufficientBsqFundsForBtcFeePayment", - bsqFormatter.formatCoinWithCode(makerFee.subtract(model.getDataModel().getUsableBsqBalance()))); - - } else if (model.getDataModel().getUsableBsqBalance().isZero()) { - missingBsq = Res.get("popup.warning.noBsqFundsForBtcFeePayment"); - } + String missingBsq = getMissingBsqForFeePaymentMessage(); if (missingBsq != null) { new Popup().warning(missingBsq) @@ -1568,8 +1542,9 @@ private GridPane createInfoPopover() { infoGridPane.setPadding(new Insets(10, 10, 10, 10)); int i = 0; - if (model.isSellOffer()) - addPayInfoEntry(infoGridPane, i++, Res.getWithCol("shared.tradeAmount"), model.tradeAmount.get()); + if (model.isSellOffer()) { + addPayInfoEntry(infoGridPane, i++, Res.getWithCol("shared.tradeAmount"), model.getTradeAmount()); + } addPayInfoEntry(infoGridPane, i++, Res.getWithCol("shared.yourSecurityDeposit"), model.getSecurityDepositInfo()); addPayInfoEntry(infoGridPane, i++, Res.getWithCol("createOffer.fundsBox.offerFee"), model.getTradeFee()); @@ -1579,19 +1554,8 @@ private GridPane createInfoPopover() { separator.getStyleClass().add("offer-separator"); GridPane.setConstraints(separator, 1, i++); infoGridPane.getChildren().add(separator); - addPayInfoEntry(infoGridPane, i, Res.getWithCol("shared.total"), model.getTotalToPayInfo()); + addPayInfoEntry(infoGridPane, i, Res.getWithCol("shared.total"), + model.getTotalToPayInfo()); return infoGridPane; } - - private void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) { - Label label = new AutoTooltipLabel(labelText); - TextField textField = new TextField(value); - textField.setMinWidth(500); - textField.setEditable(false); - textField.setFocusTraversable(false); - textField.setId("payment-info"); - GridPane.setConstraints(label, 0, row, 1, 1, HPos.RIGHT, VPos.CENTER); - GridPane.setConstraints(textField, 1, row); - infoGridPane.getChildren().addAll(label, textField); - } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java index 5121e2242ca..c07dde3d61a 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java @@ -678,11 +678,10 @@ void onShowPayFundsScreen(Runnable actionHandler) { updateSpinnerInfo(); } - boolean fundFromSavingsWallet() { + void fundFromSavingsWallet() { dataModel.fundFromSavingsWallet(); if (dataModel.getIsBtcWalletFunded().get()) { updateButtonDisableState(); - return true; } else { new Popup().warning(Res.get("shared.notEnoughFunds", btcFormatter.formatCoinWithCode(dataModel.totalToPayAsCoinProperty().get()), @@ -690,7 +689,6 @@ boolean fundFromSavingsWallet() { .actionButtonTextWithGoTo("navigation.funds.depositFunds") .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) .show(); - return false; } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index 9dbaca83590..b405e892842 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -90,7 +90,6 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -119,6 +118,7 @@ import org.jetbrains.annotations.NotNull; import static bisq.desktop.util.FormBuilder.*; +import static bisq.desktop.util.GUIUtil.addPayInfoEntry; import static javafx.beans.binding.Bindings.createStringBinding; @FxmlView @@ -672,7 +672,7 @@ private void addSubscriptions() { offerDetailsWindow.hide(); UserThread.runAfter(() -> new Popup().warning(newValue + "\n\n" + - Res.get("takeOffer.alreadyPaidInFunds")) + Res.get("takeOffer.alreadyPaidInFunds")) .actionButtonTextWithGoTo("navigation.funds.availableForWithdrawal") .onAction(() -> { errorPopupDisplayed.set(true); @@ -787,15 +787,7 @@ private void removeListeners() { /////////////////////////////////////////////////////////////////////////////////////////// private void addScrollPane() { - scrollPane = new ScrollPane(); - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setFitToWidth(true); - scrollPane.setFitToHeight(true); - AnchorPane.setLeftAnchor(scrollPane, 0d); - AnchorPane.setTopAnchor(scrollPane, 0d); - AnchorPane.setRightAnchor(scrollPane, 0d); - AnchorPane.setBottomAnchor(scrollPane, 0d); + scrollPane = GUIUtil.createScrollPane(); root.getChildren().add(scrollPane); } @@ -805,13 +797,7 @@ private void addGridPane() { gridPane.setPadding(new Insets(15, 15, -1, 15)); gridPane.setHgap(5); gridPane.setVgap(5); - ColumnConstraints columnConstraints1 = new ColumnConstraints(); - columnConstraints1.setHalignment(HPos.RIGHT); - columnConstraints1.setHgrow(Priority.NEVER); - columnConstraints1.setMinWidth(200); - ColumnConstraints columnConstraints2 = new ColumnConstraints(); - columnConstraints2.setHgrow(Priority.ALWAYS); - gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); + GUIUtil.setDefaultTwoColumnConstraintsForGridPane(gridPane); scrollPane.setContent(gridPane); } @@ -1282,17 +1268,7 @@ private void maybeShowFasterPaymentsWarning(PaymentAccount paymentAccount) { private void maybeShowAccountWarning(PaymentAccount paymentAccount, boolean isBuyer) { String msgKey = paymentAccount.getPreTradeMessage(!isBuyer); - if (msgKey == null || paymentAccountWarningDisplayed.getOrDefault(msgKey, false)) { - return; - } - paymentAccountWarningDisplayed.put(msgKey, true); - UserThread.runAfter(() -> { - new Popup().information(Res.get(msgKey)) - .width(900) - .closeButtonText(Res.get("shared.iConfirm")) - .dontShowAgainId(msgKey) - .show(); - }, 500, TimeUnit.MILLISECONDS); + GUIUtil.showPaymentAccountWarning(msgKey, paymentAccountWarningDisplayed); } private void maybeShowCashByMailWarning(PaymentAccount paymentAccount, Offer offer) { @@ -1332,8 +1308,9 @@ private GridPane createInfoPopover() { infoGridPane.setPadding(new Insets(10, 10, 10, 10)); int i = 0; - if (model.isSeller()) + if (model.isSeller()) { addPayInfoEntry(infoGridPane, i++, Res.get("takeOffer.fundsBox.tradeAmount"), model.getTradeAmount()); + } addPayInfoEntry(infoGridPane, i++, Res.getWithCol("shared.yourSecurityDeposit"), model.getSecurityDepositInfo()); addPayInfoEntry(infoGridPane, i++, Res.get("takeOffer.fundsBox.offerFee"), model.getTradeFee()); @@ -1348,17 +1325,5 @@ private GridPane createInfoPopover() { return infoGridPane; } - - private void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) { - Label label = new AutoTooltipLabel(labelText); - TextField textField = new TextField(value); - textField.setMinWidth(500); - textField.setEditable(false); - textField.setFocusTraversable(false); - textField.setId("payment-info"); - GridPane.setConstraints(label, 0, row, 1, 1, HPos.RIGHT, VPos.CENTER); - GridPane.setConstraints(textField, 1, row); - infoGridPane.getChildren().addAll(label, textField); - } } diff --git a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java index 3698a13ab6b..cbf02418797 100644 --- a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java @@ -108,14 +108,20 @@ import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.control.ScrollBar; +import javafx.scene.control.ScrollPane; import javafx.scene.control.TableView; import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.geometry.HPos; import javafx.geometry.Orientation; +import javafx.geometry.VPos; import javafx.collections.FXCollections; @@ -1218,4 +1224,54 @@ public static String getProofResultAsString(@Nullable AssetTxProofResult result) return result.name(); } } + + public static ScrollPane createScrollPane() { + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setFitToWidth(true); + scrollPane.setFitToHeight(true); + AnchorPane.setLeftAnchor(scrollPane, 0d); + AnchorPane.setTopAnchor(scrollPane, 0d); + AnchorPane.setRightAnchor(scrollPane, 0d); + AnchorPane.setBottomAnchor(scrollPane, 0d); + return scrollPane; + } + + public static void setDefaultTwoColumnConstraintsForGridPane(GridPane gridPane) { + ColumnConstraints columnConstraints1 = new ColumnConstraints(); + columnConstraints1.setHalignment(HPos.RIGHT); + columnConstraints1.setHgrow(Priority.NEVER); + columnConstraints1.setMinWidth(200); + ColumnConstraints columnConstraints2 = new ColumnConstraints(); + columnConstraints2.setHgrow(Priority.ALWAYS); + gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); + } + + public static void showPaymentAccountWarning(String msgKey, + HashMap paymentAccountWarningDisplayed) { + if (msgKey == null || paymentAccountWarningDisplayed.getOrDefault(msgKey, false)) { + return; + } + paymentAccountWarningDisplayed.put(msgKey, true); + UserThread.runAfter(() -> { + new Popup().information(Res.get(msgKey)) + .width(900) + .closeButtonText(Res.get("shared.iConfirm")) + .dontShowAgainId(msgKey) + .show(); + }, 500, TimeUnit.MILLISECONDS); + } + + public static void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) { + Label label = new AutoTooltipLabel(labelText); + TextField textField = new TextField(value); + textField.setMinWidth(500); + textField.setEditable(false); + textField.setFocusTraversable(false); + textField.setId("payment-info"); + GridPane.setConstraints(label, 0, row, 1, 1, HPos.RIGHT, VPos.CENTER); + GridPane.setConstraints(textField, 1, row); + infoGridPane.getChildren().addAll(label, textField); + } } From d2baabc180c5254c4698eda6d7fdd4cb10c435b9 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Wed, 6 Oct 2021 11:15:15 +0200 Subject: [PATCH 10/25] Move utility methods from GUIUtil to OfferViewUtil --- .../main/offer/bisq_v1/MutableOfferView.java | 4 +-- .../main/offer/bisq_v1/OfferViewUtil.java | 35 +++++++++++++++++++ .../bisq_v1/takeoffer/TakeOfferView.java | 4 +-- .../main/java/bisq/desktop/util/GUIUtil.java | 28 --------------- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index 01e963fd277..27586e1e84b 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -121,8 +121,8 @@ import org.jetbrains.annotations.NotNull; import static bisq.core.payment.payload.PaymentMethod.HAL_CASH_ID; +import static bisq.desktop.main.offer.OfferViewUtil.addPayInfoEntry; import static bisq.desktop.util.FormBuilder.*; -import static bisq.desktop.util.GUIUtil.addPayInfoEntry; import static javafx.beans.binding.Bindings.createStringBinding; public abstract class MutableOfferView> extends ActivatableViewAndModel { @@ -526,7 +526,7 @@ private void maybeShowFasterPaymentsWarning(PaymentAccount paymentAccount) { private void maybeShowAccountWarning(PaymentAccount paymentAccount, boolean isBuyer) { String msgKey = paymentAccount.getPreTradeMessage(isBuyer); - GUIUtil.showPaymentAccountWarning(msgKey, paymentAccountWarningDisplayed); + OfferViewUtil.showPaymentAccountWarning(msgKey, paymentAccountWarningDisplayed); } protected void onPaymentAccountsComboBoxSelected() { diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 3a3acec2925..42e4987485d 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -19,6 +19,7 @@ import bisq.desktop.Navigation; import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.main.MainView; import bisq.desktop.main.offer.offerbook.OfferBookView; import bisq.desktop.main.overlays.popups.Popup; @@ -27,14 +28,21 @@ import bisq.core.offer.OfferPayload; import bisq.core.user.Preferences; +import bisq.common.UserThread; import bisq.common.util.Tuple2; import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.geometry.VPos; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; // Shared utils for Views public class OfferViewUtil { @@ -47,6 +55,33 @@ public static Label createPopOverLabel(String text) { return label; } + public static void showPaymentAccountWarning(String msgKey, + HashMap paymentAccountWarningDisplayed) { + if (msgKey == null || paymentAccountWarningDisplayed.getOrDefault(msgKey, false)) { + return; + } + paymentAccountWarningDisplayed.put(msgKey, true); + UserThread.runAfter(() -> { + new Popup().information(Res.get(msgKey)) + .width(900) + .closeButtonText(Res.get("shared.iConfirm")) + .dontShowAgainId(msgKey) + .show(); + }, 500, TimeUnit.MILLISECONDS); + } + + public static void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) { + Label label = new AutoTooltipLabel(labelText); + TextField textField = new TextField(value); + textField.setMinWidth(500); + textField.setEditable(false); + textField.setFocusTraversable(false); + textField.setId("payment-info"); + GridPane.setConstraints(label, 0, row, 1, 1, HPos.RIGHT, VPos.CENTER); + GridPane.setConstraints(textField, 1, row); + infoGridPane.getChildren().addAll(label, textField); + } + public interface DirectionClosure { OfferPayload.Direction getDirection(); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index b405e892842..bfdc949985d 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -117,8 +117,8 @@ import org.jetbrains.annotations.NotNull; +import static bisq.desktop.main.offer.OfferViewUtil.addPayInfoEntry; import static bisq.desktop.util.FormBuilder.*; -import static bisq.desktop.util.GUIUtil.addPayInfoEntry; import static javafx.beans.binding.Bindings.createStringBinding; @FxmlView @@ -1268,7 +1268,7 @@ private void maybeShowFasterPaymentsWarning(PaymentAccount paymentAccount) { private void maybeShowAccountWarning(PaymentAccount paymentAccount, boolean isBuyer) { String msgKey = paymentAccount.getPreTradeMessage(!isBuyer); - GUIUtil.showPaymentAccountWarning(msgKey, paymentAccountWarningDisplayed); + OfferViewUtil.showPaymentAccountWarning(msgKey, paymentAccountWarningDisplayed); } private void maybeShowCashByMailWarning(PaymentAccount paymentAccount, Offer offer) { diff --git a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java index cbf02418797..efbb53ba4f3 100644 --- a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java @@ -111,7 +111,6 @@ import javafx.scene.control.ScrollPane; import javafx.scene.control.TableView; import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.ColumnConstraints; @@ -121,7 +120,6 @@ import javafx.geometry.HPos; import javafx.geometry.Orientation; -import javafx.geometry.VPos; import javafx.collections.FXCollections; @@ -1248,30 +1246,4 @@ public static void setDefaultTwoColumnConstraintsForGridPane(GridPane gridPane) gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); } - public static void showPaymentAccountWarning(String msgKey, - HashMap paymentAccountWarningDisplayed) { - if (msgKey == null || paymentAccountWarningDisplayed.getOrDefault(msgKey, false)) { - return; - } - paymentAccountWarningDisplayed.put(msgKey, true); - UserThread.runAfter(() -> { - new Popup().information(Res.get(msgKey)) - .width(900) - .closeButtonText(Res.get("shared.iConfirm")) - .dontShowAgainId(msgKey) - .show(); - }, 500, TimeUnit.MILLISECONDS); - } - - public static void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) { - Label label = new AutoTooltipLabel(labelText); - TextField textField = new TextField(value); - textField.setMinWidth(500); - textField.setEditable(false); - textField.setFocusTraversable(false); - textField.setId("payment-info"); - GridPane.setConstraints(label, 0, row, 1, 1, HPos.RIGHT, VPos.CENTER); - GridPane.setConstraints(textField, 1, row); - infoGridPane.getChildren().addAll(label, textField); - } } From ee30cd9739cdcf5f5579e1bdb873f3bf1818d3eb Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Wed, 6 Oct 2021 11:23:33 +0200 Subject: [PATCH 11/25] Refactor auto-closing of sell BTC offer view --- .../desktop/main/offer/bisq_v1/MutableOfferView.java | 12 +++++------- .../desktop/main/offer/bisq_v1/OfferViewUtil.java | 9 ++++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index 27586e1e84b..a54f7bdad1a 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -168,7 +168,7 @@ public abstract class MutableOfferView> exten private ChangeListener tradeCurrencyCodeListener, errorMessageListener, marketPriceMarginListener, volumeListener, buyerSecurityDepositInBTCListener; private ChangeListener marketPriceAvailableListener; - private Navigation.Listener navigationWithCloseListener; + private Navigation.Listener closeViewListener; private EventHandler currencyComboBoxSelectionHandler, paymentAccountsComboBoxSelectionHandler; private OfferView.CloseHandler closeHandler; @@ -914,10 +914,8 @@ private void createListeners() { } }); - navigationWithCloseListener = (path, data) -> { - log.warn("*** target path={}, data={}, dir={}", path, data, model.getDataModel().getDirection()); - if ("closeOfferView".equals(data)) { - log.warn("*** WILL CLOSE"); + closeViewListener = (path, data) -> { + if (OfferViewUtil.isCloseView((String) data)) { close(); } }; @@ -978,7 +976,7 @@ private void addListeners() { paymentAccountsComboBox.setOnAction(paymentAccountsComboBoxSelectionHandler); currencyComboBox.setOnAction(currencyComboBoxSelectionHandler); - navigation.addListener(navigationWithCloseListener); + navigation.addListener(closeViewListener); } private void removeListeners() { @@ -1015,7 +1013,7 @@ private void removeListeners() { paymentAccountsComboBox.setOnAction(null); currencyComboBox.setOnAction(null); - navigation.removeListener(navigationWithCloseListener); + navigation.removeListener(closeViewListener); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 42e4987485d..b9aca7a73b9 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -46,6 +46,9 @@ // Shared utils for Views public class OfferViewUtil { + + public static final String CLOSE_VIEW = "closeView"; + public static Label createPopOverLabel(String text) { final Label label = new Label(text); label.setPrefWidth(300); @@ -101,7 +104,7 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n preferences.setSellScreenCurrencyCode("BSQ"); navigation.navigateToWithData( // FIXME: replace "closeOfferView" with a more unique object? - directionClosure.getDirection() == OfferPayload.Direction.SELL ? "closeOfferView" : null, + directionClosure.getDirection() == OfferPayload.Direction.SELL ? CLOSE_VIEW : null, MainView.class, SellOfferView.class, OfferBookView.class); }).show()); @@ -112,4 +115,8 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n return new Tuple2<>(buyBsqButton, buyBsqButtonVBox); } + + public static boolean isCloseView(String data) { + return CLOSE_VIEW.equals(data); + } } From 9e2be927870ee9df19ba3e30012f868f1b762a22 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Wed, 6 Oct 2021 11:34:30 +0200 Subject: [PATCH 12/25] Not auto-close create offer view --- .../main/offer/bisq_v1/MutableOfferView.java | 13 +------------ .../main/offer/bisq_v1/OfferViewUtil.java | 18 ++---------------- .../offer/bisq_v1/takeoffer/TakeOfferView.java | 2 +- 3 files changed, 4 insertions(+), 29 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index a54f7bdad1a..b37ef3f28e2 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -168,7 +168,6 @@ public abstract class MutableOfferView> exten private ChangeListener tradeCurrencyCodeListener, errorMessageListener, marketPriceMarginListener, volumeListener, buyerSecurityDepositInBTCListener; private ChangeListener marketPriceAvailableListener; - private Navigation.Listener closeViewListener; private EventHandler currencyComboBoxSelectionHandler, paymentAccountsComboBoxSelectionHandler; private OfferView.CloseHandler closeHandler; @@ -913,12 +912,6 @@ private void createListeners() { buyerSecurityDepositInputTextField.setDisable(false); } }); - - closeViewListener = (path, data) -> { - if (OfferViewUtil.isCloseView((String) data)) { - close(); - } - }; } private void setIsCurrencyForMakerFeeBtc(boolean isCurrencyForMakerFeeBtc) { @@ -975,8 +968,6 @@ private void addListeners() { // UI actions paymentAccountsComboBox.setOnAction(paymentAccountsComboBoxSelectionHandler); currencyComboBox.setOnAction(currencyComboBoxSelectionHandler); - - navigation.addListener(closeViewListener); } private void removeListeners() { @@ -1012,8 +1003,6 @@ private void removeListeners() { // UI actions paymentAccountsComboBox.setOnAction(null); currencyComboBox.setOnAction(null); - - navigation.removeListener(closeViewListener); } @@ -1112,7 +1101,7 @@ private void addOptionsGroup() { gridPane.getChildren().add(advancedOptionsBox); Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( - navigation, preferences, model.dataModel::getDirection); + navigation, preferences); buyBsqButton = buyBsqButtonBox.first; buyBsqButton.setVisible(false); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index b9aca7a73b9..28a0faba5fd 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -25,7 +25,6 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.core.locale.Res; -import bisq.core.offer.OfferPayload; import bisq.core.user.Preferences; import bisq.common.UserThread; @@ -47,8 +46,6 @@ // Shared utils for Views public class OfferViewUtil { - public static final String CLOSE_VIEW = "closeView"; - public static Label createPopOverLabel(String text) { final Label label = new Label(text); label.setPrefWidth(300); @@ -85,13 +82,8 @@ public static void addPayInfoEntry(GridPane infoGridPane, int row, String labelT infoGridPane.getChildren().addAll(label, textField); } - public interface DirectionClosure { - OfferPayload.Direction getDirection(); - } - public static Tuple2 createBuyBsqButtonBox(Navigation navigation, - Preferences preferences, - DirectionClosure directionClosure) { + Preferences preferences) { String buyBsqText = Res.get("shared.buyCurrency", "BSQ"); var buyBsqButton = new AutoTooltipButton(buyBsqText); buyBsqButton.getStyleClass().add("action-button"); @@ -102,9 +94,7 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n .buttonAlignment(HPos.CENTER) .onAction(() -> { preferences.setSellScreenCurrencyCode("BSQ"); - navigation.navigateToWithData( - // FIXME: replace "closeOfferView" with a more unique object? - directionClosure.getDirection() == OfferPayload.Direction.SELL ? CLOSE_VIEW : null, + navigation.navigateTo( MainView.class, SellOfferView.class, OfferBookView.class); }).show()); @@ -115,8 +105,4 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n return new Tuple2<>(buyBsqButton, buyBsqButtonVBox); } - - public static boolean isCloseView(String data) { - return CLOSE_VIEW.equals(data); - } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index bfdc949985d..2c9f6a2e90f 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -871,7 +871,7 @@ private void addOptionsGroup() { gridPane.getChildren().add(advancedOptionsBox); Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( - navigation, model.dataModel.preferences, model.dataModel::getDirection); + navigation, model.dataModel.preferences); advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox(), buyBsqButtonBox.second); } From 552720889496f8f6aae7b0d51932158c7ff503bb Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Wed, 6 Oct 2021 12:16:12 +0200 Subject: [PATCH 13/25] Add more context to buy BSQ button --- .../desktop/components/HyperlinkWithIcon.java | 12 +++++++-- .../main/offer/bisq_v1/MutableOfferView.java | 21 +++++++-------- .../main/offer/bisq_v1/OfferViewUtil.java | 27 ++++++++++++++----- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java b/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java index b3738ee74d0..3eebe0aab8a 100644 --- a/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java +++ b/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java @@ -41,11 +41,15 @@ public HyperlinkWithIcon(String text) { this(text, AwesomeIcon.INFO_SIGN); } - public HyperlinkWithIcon(String text, AwesomeIcon awesomeIcon) { + public HyperlinkWithIcon(String text, String fontSize) { + this(text, AwesomeIcon.INFO_SIGN, fontSize); + } + + public HyperlinkWithIcon(String text, AwesomeIcon awesomeIcon, String fontSize) { super(text); Label icon = new Label(); - AwesomeDude.setIcon(icon, awesomeIcon); + AwesomeDude.setIcon(icon, awesomeIcon, fontSize); icon.setMinWidth(20); icon.setOpacity(0.7); icon.getStyleClass().addAll("hyperlink", "no-underline"); @@ -55,6 +59,10 @@ public HyperlinkWithIcon(String text, AwesomeIcon awesomeIcon) { setIcon(icon); } + public HyperlinkWithIcon(String text, AwesomeIcon awesomeIcon) { + this(text, awesomeIcon, "1.231em"); + } + public HyperlinkWithIcon(String text, GlyphIcons icon) { this(text, icon, null); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index b37ef3f28e2..8310f49cbba 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -137,7 +137,7 @@ public abstract class MutableOfferView> exten private TitledGroupBg payFundsTitledGroupBg, setDepositTitledGroupBg, paymentTitledGroupBg; protected TitledGroupBg amountTitledGroupBg; private BusyAnimation waitingForFundsSpinner; - private AutoTooltipButton nextButton, cancelButton1, cancelButton2, placeOfferButton, buyBsqButton; + private AutoTooltipButton nextButton, cancelButton1, cancelButton2, placeOfferButton; private Button priceTypeToggleButton; private InputTextField fixedPriceTextField, marketBasedPriceTextField, triggerPriceInputTextField; protected InputTextField amountTextField, minAmountTextField, volumeTextField, buyerSecurityDepositInputTextField; @@ -153,7 +153,7 @@ public abstract class MutableOfferView> exten private ComboBox paymentAccountsComboBox; private ComboBox currencyComboBox; private ImageView qrCodeImageView; - private VBox currencySelection, fixedPriceBox, percentagePriceBox, currencyTextFieldBox, triggerPriceVBox; + private VBox currencySelection, fixedPriceBox, percentagePriceBox, currencyTextFieldBox, triggerPriceVBox, buyBsqBox; private HBox fundingHBox, firstRowHBox, secondRowHBox, placeOfferBox, amountValueCurrencyBox, priceAsPercentageValueCurrencyBox, volumeValueCurrencyBox, priceValueCurrencyBox, minAmountValueCurrencyBox, advancedOptionsBox, triggerPriceHBox; @@ -270,8 +270,8 @@ protected void doActivate() { tradeFeeInBtcToggle.setManaged(false); tradeFeeInBsqToggle.setVisible(false); tradeFeeInBsqToggle.setManaged(false); - buyBsqButton.setVisible(false); - buyBsqButton.setManaged(false); + buyBsqBox.setVisible(false); + buyBsqBox.setManaged(false); } Label popOverLabel = OfferViewUtil.createPopOverLabel(Res.get("createOffer.triggerPrice.tooltip")); @@ -405,9 +405,8 @@ private void onShowPayFundsScreen() { cancelButton1.setVisible(false); cancelButton1.setManaged(false); cancelButton1.setOnAction(null); - buyBsqButton.setVisible(false); - buyBsqButton.setManaged(false); - buyBsqButton.setOnAction(null); + buyBsqBox.setVisible(false); + buyBsqBox.setManaged(false); tradeFeeInBtcToggle.setMouseTransparent(true); tradeFeeInBsqToggle.setMouseTransparent(true); @@ -896,7 +895,7 @@ private void createListeners() { tradeFeeInBtcToggle.setVisible(newValue); tradeFeeInBsqToggle.setVisible(newValue); if (model.isShowBuyBsqHint()) { - buyBsqButton.setVisible(newValue); + buyBsqBox.setVisible(newValue); } } }; @@ -1102,10 +1101,10 @@ private void addOptionsGroup() { Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( navigation, preferences); - buyBsqButton = buyBsqButtonBox.first; - buyBsqButton.setVisible(false); + buyBsqBox = buyBsqButtonBox.second; + buyBsqBox.setVisible(false); - advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), getTradeFeeFieldsBox(), buyBsqButtonBox.second); + advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), getTradeFeeFieldsBox(), buyBsqBox); Tuple2 tuple = add2ButtonsAfterGroup(gridPane, ++gridRow, Res.get("shared.nextStep"), Res.get("shared.cancel")); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 28a0faba5fd..816ad8cac81 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -20,6 +20,7 @@ import bisq.desktop.Navigation; import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.main.MainView; import bisq.desktop.main.offer.offerbook.OfferBookView; import bisq.desktop.main.overlays.popups.Popup; @@ -33,6 +34,7 @@ import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.geometry.HPos; @@ -88,21 +90,32 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n var buyBsqButton = new AutoTooltipButton(buyBsqText); buyBsqButton.getStyleClass().add("action-button"); buyBsqButton.getStyleClass().add("tiny-button"); - buyBsqButton.setOnAction(e -> new Popup().headLine(buyBsqText) + buyBsqButton.setOnAction(e -> openBuyBsqOfferBook(navigation, preferences) + ); + + var info = new AutoTooltipLabel("BSQ is colored BTC that helps fund Bisq developers."); + var learnMore = new HyperlinkWithIcon("Learn More"); + learnMore.setOnAction(e -> new Popup().headLine(buyBsqText) .information(Res.get("createOffer.buyBsq.popupMessage")) .actionButtonText(buyBsqText) .buttonAlignment(HPos.CENTER) - .onAction(() -> { - preferences.setSellScreenCurrencyCode("BSQ"); - navigation.navigateTo( - MainView.class, SellOfferView.class, OfferBookView.class); - }).show()); + .onAction(() -> openBuyBsqOfferBook(navigation, preferences)).show()); + + final HBox buyBsqBox = new HBox(buyBsqButton, info, learnMore); + buyBsqBox.setAlignment(Pos.BOTTOM_LEFT); + buyBsqBox.setSpacing(10); - final VBox buyBsqButtonVBox = new VBox(buyBsqButton); + final VBox buyBsqButtonVBox = new VBox(buyBsqBox); buyBsqButtonVBox.setAlignment(Pos.BOTTOM_LEFT); buyBsqButtonVBox.setPadding(new Insets(0, 0, 0, -20)); VBox.setMargin(buyBsqButton, new Insets(0, 0, 4, 0)); return new Tuple2<>(buyBsqButton, buyBsqButtonVBox); } + + private static void openBuyBsqOfferBook(Navigation navigation, Preferences preferences) { + preferences.setSellScreenCurrencyCode("BSQ"); + navigation.navigateTo( + MainView.class, SellOfferView.class, OfferBookView.class); + } } From d6cd83ae88b01ac5770aabfe1a9a4f9b137bf9c4 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Mon, 11 Oct 2021 10:59:49 +0200 Subject: [PATCH 14/25] Improve informational popup --- core/src/main/resources/i18n/displayStrings.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index e050df1b73d..1424726c24d 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -484,7 +484,7 @@ createOffer.triggerPrice.invalid.tooHigh=Value must be lower than {0} createOffer.buyBsq.popupMessage=Trading fees are paid to fund the Bisq DAO. Fees can be paid in BSQ or BTC.\n\n\ BSQ fees directly help fund Bisq's development, so Bisq encourages traders to use BSQ by offering a 50% discount on trading fees. \ This discount varies as the BSQ/BTC rate fluctuates. To maintain the 50% discount target, trading fees are updated every cycle as necessary.\n\n\ - For more about fees, see [HYPERLINK:https://bisq.wiki/Trading_fees]. For more about the Bisq DAO, see [HYPERLINK:https://bisq.wiki/Introduction_to_the_DAO#The_Bisq_DAO]. + For more about fees, see [HYPERLINK:https://bisq.wiki/Trading_fees]. For more about trading BSQ, see [HYPERLINK:https://bisq.wiki/Trading_BSQ]. For more about the Bisq DAO, see [HYPERLINK:https://bisq.wiki/Introduction_to_the_DAO#The_Bisq_DAO]. # new entries createOffer.placeOfferButton=Review: Place offer to {0} bitcoin From 4063b72b7dc824c99322435c211c824f135ae922 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:40:16 +0100 Subject: [PATCH 15/25] Add tooltip for disabled create offer button Conflicts: desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java --- .../resources/i18n/displayStrings.properties | 1 + desktop/src/main/java/bisq/desktop/bisq.css | 3 +- .../main/offer/offerbook/OfferBookView.java | 34 ++++++++++++++----- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 1424726c24d..fca54c8adb4 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -388,6 +388,7 @@ offerbook.createOfferToBuy.withFiat=Create new offer to buy {0} with {1} offerbook.createOfferToSell.forFiat=Create new offer to sell {0} for {1} offerbook.createOfferToBuy.withCrypto=Create new offer to sell {0} (buy {1}) offerbook.createOfferToSell.forCrypto=Create new offer to buy {0} (sell {1}) +offerbook.createOfferDisabled.tooltip=You can only create one offer at a time offerbook.takeOfferButton.tooltip=Take offer for {0} offerbook.yesCreateOffer=Yes, create offer diff --git a/desktop/src/main/java/bisq/desktop/bisq.css b/desktop/src/main/java/bisq/desktop/bisq.css index 8037df530b4..51862da5561 100644 --- a/desktop/src/main/java/bisq/desktop/bisq.css +++ b/desktop/src/main/java/bisq/desktop/bisq.css @@ -175,7 +175,8 @@ -fx-padding: 0 10 0 10; } -.tiny-button, .action-button.tiny-button { +.tiny-button, +.action-button.tiny-button { -fx-font-size: 0.769em; -fx-pref-height: 20; -fx-padding: 3 8 3 8; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java index 5c60d5f9b7d..4998f645524 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java @@ -91,6 +91,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.text.TextAlignment; @@ -146,6 +147,7 @@ public class OfferBookView extends ActivatableViewAndModel priceFeedUpdateCounterListener; private Subscription currencySelectionSubscriber; private static final int SHOW_ALL = 0; + private Label disabledCreateOfferButtonTooltip; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -200,13 +202,23 @@ public void initialize() { matchingOffersToggle.setText(Res.get("offerbook.matchingOffers")); HBox.setMargin(matchingOffersToggle, new Insets(7, 0, -9, -15)); - createOfferButton = new AutoTooltipButton(); createOfferButton.setMinHeight(40); createOfferButton.setGraphicTextGap(10); + disabledCreateOfferButtonTooltip = new Label(""); + disabledCreateOfferButtonTooltip.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE); + disabledCreateOfferButtonTooltip.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE); + disabledCreateOfferButtonTooltip.prefWidthProperty().bind(createOfferButton.widthProperty()); + disabledCreateOfferButtonTooltip.prefHeightProperty().bind(createOfferButton.heightProperty()); + disabledCreateOfferButtonTooltip.setTooltip(new Tooltip(Res.get("offerbook.createOfferDisabled.tooltip"))); + disabledCreateOfferButtonTooltip.setManaged(false); + disabledCreateOfferButtonTooltip.setVisible(false); + + var createOfferButtonStack = new StackPane(createOfferButton, disabledCreateOfferButtonTooltip); + offerToolsBox.getChildren().addAll(currencyBoxTuple.first, paymentBoxTuple.first, - matchingOffersToggle, getSpacer(), createOfferButton); + matchingOffersToggle, getSpacer(), createOfferButtonStack); GridPane.setHgrow(offerToolsBox, Priority.ALWAYS); GridPane.setRowIndex(offerToolsBox, gridRow); @@ -538,6 +550,16 @@ private PaymentMethod specialShowAllItem() { public void enableCreateOfferButton() { createOfferButton.setDisable(false); + disabledCreateOfferButtonTooltip.setManaged(false); + disabledCreateOfferButtonTooltip.setVisible(false); + } + + private void disableCreateOfferButton() { + createOfferButton.setDisable(true); + disabledCreateOfferButtonTooltip.setManaged(true); + disabledCreateOfferButtonTooltip.setVisible(true); + + offerActionHandler.onCreateOffer(model.getSelectedTradeCurrency(), model.selectedPaymentMethod); } public void setDirection(OfferDirection direction) { @@ -594,15 +616,12 @@ public void onTabSelected(boolean isSelected) { private void onCreateOffer() { if (model.canCreateOrTakeOffer()) { - PaymentMethod selectedPaymentMethod = model.selectedPaymentMethod; - TradeCurrency selectedTradeCurrency = model.getSelectedTradeCurrency(); if (!model.hasPaymentAccountForCurrency()) { new Popup().headLine(Res.get("offerbook.warning.noTradingAccountForCurrency.headline")) .instruction(Res.get("offerbook.warning.noTradingAccountForCurrency.msg")) .actionButtonText(Res.get("offerbook.yesCreateOffer")) .onAction(() -> { - createOfferButton.setDisable(true); - offerActionHandler.onCreateOffer(selectedTradeCurrency, selectedPaymentMethod); + disableCreateOfferButton(); }) .secondaryActionButtonText(Res.get("offerbook.setupNewAccount")) .onSecondaryAction(() -> { @@ -614,8 +633,7 @@ private void onCreateOffer() { return; } - createOfferButton.setDisable(true); - offerActionHandler.onCreateOffer(selectedTradeCurrency, selectedPaymentMethod); + disableCreateOfferButton(); } } From 60a0d875fc5f4e1e1d506eaf9ad27d080d5eb0ef Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Tue, 12 Oct 2021 11:50:10 +0200 Subject: [PATCH 16/25] Refactor account name generation --- .../paymentmethods/AdvancedCashForm.java | 18 +- .../components/paymentmethods/AssetsForm.java | 7 +- .../paymentmethods/CapitualForm.java | 9 +- .../paymentmethods/JapanBankTransferForm.java | 229 ++++++++---------- .../paymentmethods/MoneyGramForm.java | 8 +- .../paymentmethods/PaymentMethodForm.java | 7 +- .../fiataccounts/FiatAccountsView.java | 2 +- .../java/bisq/desktop/util/DisplayUtils.java | 12 + 8 files changed, 129 insertions(+), 163 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java index f384b5a1c63..caf34bdf327 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java @@ -34,8 +34,6 @@ import bisq.common.util.Tuple2; -import org.apache.commons.lang3.StringUtils; - import javafx.scene.control.Label; import javafx.scene.layout.FlowPane; import javafx.scene.layout.GridPane; @@ -62,8 +60,13 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public AdvancedCashForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AdvancedCashValidator advancedCashValidator, - InputValidator inputValidator, GridPane gridPane, int gridRow, CoinFormatter formatter) { + public AdvancedCashForm(PaymentAccount paymentAccount, + AccountAgeWitnessService accountAgeWitnessService, + AdvancedCashValidator advancedCashValidator, + InputValidator inputValidator, + GridPane gridPane, + int gridRow, + CoinFormatter formatter) { super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); this.advancedCashAccount = (AdvancedCashAccount) paymentAccount; this.advancedCashValidator = advancedCashValidator; @@ -101,12 +104,7 @@ private void addCurrenciesGrid(boolean isEditable) { @Override protected void autoFillNameTextField() { - if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { - String accountNr = accountNrInputTextField.getText(); - accountNr = StringUtils.abbreviate(accountNr, 9); - String method = Res.get(paymentAccount.getPaymentMethod().getId()); - accountNameTextField.setText(method.concat(": ").concat(accountNr)); - } + setAccountNameWithString(accountNrInputTextField.getText()); } @Override diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java index 2a72811dead..625b267d4ab 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java @@ -41,8 +41,6 @@ import bisq.common.UserThread; import bisq.common.util.Tuple3; -import org.apache.commons.lang3.StringUtils; - import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; @@ -53,6 +51,7 @@ import javafx.util.StringConverter; +import static bisq.desktop.util.DisplayUtils.createAssetsAccountName; import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField; import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextFieldWithCopyIcon; import static bisq.desktop.util.FormBuilder.addLabelCheckBox; @@ -169,9 +168,7 @@ protected void autoFillNameTextField() { if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { String currency = paymentAccount.getSingleTradeCurrency() != null ? paymentAccount.getSingleTradeCurrency().getCode() : ""; if (currency != null) { - String address = addressInputTextField.getText(); - address = StringUtils.abbreviate(address, 9); - accountNameTextField.setText(currency.concat(": ").concat(address)); + accountNameTextField.setText(createAssetsAccountName(currency, addressInputTextField.getText())); } } } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/CapitualForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/CapitualForm.java index e4fa6163a4d..4f7201cc542 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/CapitualForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/CapitualForm.java @@ -34,8 +34,6 @@ import bisq.common.util.Tuple2; -import org.apache.commons.lang3.StringUtils; - import javafx.scene.control.Label; import javafx.scene.layout.FlowPane; import javafx.scene.layout.GridPane; @@ -100,12 +98,7 @@ private void addCurrenciesGrid(boolean isEditable) { @Override protected void autoFillNameTextField() { - if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { - String accountNr = accountNrInputTextField.getText(); - accountNr = StringUtils.abbreviate(accountNr, 9); - String method = Res.get(paymentAccount.getPaymentMethod().getId()); - accountNameTextField.setText(method.concat(": ").concat(accountNr)); - } + setAccountNameWithString(accountNrInputTextField.getText()); } @Override diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/JapanBankTransferForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/JapanBankTransferForm.java index 22eac439a5f..bfbde452b10 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/JapanBankTransferForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/JapanBankTransferForm.java @@ -25,7 +25,6 @@ import bisq.desktop.util.validation.JapanBankAccountNumberValidator; import bisq.desktop.util.validation.JapanBankBranchCodeValidator; import bisq.desktop.util.validation.JapanBankBranchNameValidator; -import bisq.desktop.util.validation.JapanBankTransferValidator; import bisq.desktop.util.validation.LengthValidator; import bisq.core.account.witness.AccountAgeWitnessService; @@ -57,24 +56,17 @@ import static bisq.desktop.util.FormBuilder.*; import static bisq.desktop.util.GUIUtil.getComboBoxButtonCell; -public class JapanBankTransferForm extends PaymentMethodForm -{ +public class JapanBankTransferForm extends PaymentMethodForm { private final JapanBankAccount japanBankAccount; - protected ComboBox bankComboBox, bankAccountTypeComboBox; - private InputTextField bankAccountNumberInputTextField; + protected ComboBox bankComboBox; - private JapanBankTransferValidator japanBankTransferValidator; - private JapanBankBranchNameValidator japanBankBranchNameValidator; - private JapanBankBranchCodeValidator japanBankBranchCodeValidator; - private JapanBankAccountNameValidator japanBankAccountNameValidator; - private JapanBankAccountNumberValidator japanBankAccountNumberValidator; + private final JapanBankBranchNameValidator japanBankBranchNameValidator; + private final JapanBankBranchCodeValidator japanBankBranchCodeValidator; + private final JapanBankAccountNameValidator japanBankAccountNameValidator; + private final JapanBankAccountNumberValidator japanBankAccountNumberValidator; - private LengthValidator lengthValidator; - private RegexValidator regexValidator; - - public static int addFormForBuyer(GridPane gridPane, int gridRow, // {{{ - PaymentAccountPayload paymentAccountPayload) - { + public static int addFormForBuyer(GridPane gridPane, int gridRow, + PaymentAccountPayload paymentAccountPayload) { JapanBankAccountPayload japanBankAccount = ((JapanBankAccountPayload) paymentAccountPayload); String bankText = japanBankAccount.getBankCode() + " " + japanBankAccount.getBankName(); @@ -90,30 +82,26 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, // {{{ addCompactTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1, Res.get("payment.japan.recipient"), accountNameText); return gridRow; - } // }}} + } public JapanBankTransferForm(PaymentAccount paymentAccount, - AccountAgeWitnessService accountAgeWitnessService, - JapanBankTransferValidator japanBankTransferValidator, - InputValidator inputValidator, GridPane gridPane, - int gridRow, CoinFormatter formatter) - { + AccountAgeWitnessService accountAgeWitnessService, + InputValidator inputValidator, GridPane gridPane, + int gridRow, CoinFormatter formatter) { super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); this.japanBankAccount = (JapanBankAccount) paymentAccount; - this.japanBankTransferValidator = japanBankTransferValidator; this.japanBankBranchCodeValidator = new JapanBankBranchCodeValidator(); this.japanBankAccountNumberValidator = new JapanBankAccountNumberValidator(); - this.lengthValidator = new LengthValidator(); - this.regexValidator = new RegexValidator(); + LengthValidator lengthValidator = new LengthValidator(); + RegexValidator regexValidator = new RegexValidator(); this.japanBankBranchNameValidator = new JapanBankBranchNameValidator(lengthValidator, regexValidator); this.japanBankAccountNameValidator = new JapanBankAccountNameValidator(lengthValidator, regexValidator); } @Override - public void addFormForDisplayAccount() // {{{ - { + public void addFormForDisplayAccount() { gridRowFrom = gridRow; addTopLabelTextField(gridPane, ++gridRow, Res.get("payment.account.name"), @@ -128,37 +116,36 @@ public void addFormForDisplayAccount() // {{{ addBankAccountTypeDisplay(); addLimitations(true); - } // }}} - private void addBankDisplay() // {{{ - { + } + + private void addBankDisplay() { String bankText = japanBankAccount.getBankCode() + " " + japanBankAccount.getBankName(); TextField bankTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("bank"), bankText).second; bankTextField.setEditable(false); - } // }}} - private void addBankBranchDisplay() // {{{ - { + } + + private void addBankBranchDisplay() { String branchText = japanBankAccount.getBankBranchCode() + " " + japanBankAccount.getBankBranchName(); TextField branchTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("branch"), branchText).second; branchTextField.setEditable(false); - } // }}} - private void addBankAccountDisplay() // {{{ - { + } + + private void addBankAccountDisplay() { String accountText = japanBankAccount.getBankAccountNumber() + " " + japanBankAccount.getBankAccountName(); TextField accountTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("account"), accountText).second; accountTextField.setEditable(false); - } // }}} - private void addBankAccountTypeDisplay() // {{{ - { + } + + private void addBankAccountTypeDisplay() { TradeCurrency singleTradeCurrency = japanBankAccount.getSingleTradeCurrency(); String currency = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : "null"; String accountTypeText = currency + " " + japanBankAccount.getBankAccountType(); TextField accountTypeTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("account.type"), accountTypeText).second; accountTypeTextField.setEditable(false); - } // }}} + } @Override - public void addFormForAddAccount() // {{{ - { + public void addFormForAddAccount() { gridRowFrom = gridRow; addBankInput(); @@ -168,9 +155,9 @@ public void addFormForAddAccount() // {{{ addLimitations(false); addAccountNameTextFieldWithAutoFillToggleButton(); - } // }}} - private void addBankInput() // {{{ - { + } + + private void addBankInput() { gridRow++; Tuple4> tuple4 = addTopLabelTextFieldAutocompleteComboBox(gridPane, gridRow, JapanBankData.getString("bank.code"), JapanBankData.getString("bank.name"), 10); @@ -185,14 +172,13 @@ private void addBankInput() // {{{ bankComboBox = tuple4.fourth; bankComboBox.setPromptText(JapanBankData.getString("bank.select")); bankComboBox.setButtonCell(getComboBoxButtonCell(JapanBankData.getString("bank.name"), bankComboBox)); - bankComboBox.getEditor().focusedProperty().addListener(observable -> { - bankComboBox.setPromptText(""); - }); - bankComboBox.setConverter(new StringConverter() { + bankComboBox.getEditor().focusedProperty().addListener(observable -> bankComboBox.setPromptText("")); + bankComboBox.setConverter(new StringConverter<>() { @Override public String toString(String bank) { return bank != null ? bank : ""; } + public String fromString(String s) { return s != null ? s : ""; } @@ -208,8 +194,7 @@ public String fromString(String s) { // parse first 4 characters as bank code String bankCode = StringUtils.substring(bank, 0, 4); - if (bankCode != null) - { + if (bankCode != null) { // set bank code field to this value bankCodeField.setText(bankCode); // save to payload @@ -217,26 +202,20 @@ public String fromString(String s) { // parse remainder as bank name String bankNameFull = StringUtils.substringAfter(bank, JapanBankData.SPACE); - if (bankNameFull != null) - { - // parse beginning as Japanese bank name - String bankNameJa = StringUtils.substringBefore(bankNameFull, JapanBankData.SPACE); - if (bankNameJa != null) - { - // set bank name field to this value - bankComboBox.getEditor().setText(bankNameJa); - // save to payload - japanBankAccount.setBankName(bankNameJa); - } - } + // parse beginning as Japanese bank name + String bankNameJa = StringUtils.substringBefore(bankNameFull, JapanBankData.SPACE); + // set bank name field to this value + bankComboBox.getEditor().setText(bankNameJa); + // save to payload + japanBankAccount.setBankName(bankNameJa); } updateFromInputs(); }); - } // }}} - private void addBankBranchInput() // {{{ - { + } + + private void addBankBranchInput() { gridRow++; Tuple2 tuple2 = addInputTextFieldInputTextField(gridPane, gridRow, JapanBankData.getString("branch.code"), JapanBankData.getString("branch.name")); @@ -259,14 +238,14 @@ private void addBankBranchInput() // {{{ japanBankAccount.setBankBranchName(newValue); updateFromInputs(); }); - } // }}} - private void addBankAccountInput() // {{{ - { + } + + private void addBankAccountInput() { gridRow++; Tuple2 tuple2 = addInputTextFieldInputTextField(gridPane, gridRow, JapanBankData.getString("account.number"), JapanBankData.getString("account.name")); // account number - bankAccountNumberInputTextField = tuple2.first; + InputTextField bankAccountNumberInputTextField = tuple2.first; bankAccountNumberInputTextField.setValidator(japanBankAccountNumberValidator); bankAccountNumberInputTextField.setPrefWidth(200); bankAccountNumberInputTextField.setMaxWidth(200); @@ -284,9 +263,9 @@ private void addBankAccountInput() // {{{ japanBankAccount.setBankAccountName(newValue); updateFromInputs(); }); - } // }}} - private void addBankAccountTypeInput() // {{{ - { + } + + private void addBankAccountTypeInput() { // account currency gridRow++; @@ -299,13 +278,13 @@ private void addBankAccountTypeInput() // {{{ ToggleGroup toggleGroup = new ToggleGroup(); Tuple3 tuple3 = - addTopLabelRadioButtonRadioButton( - gridPane, gridRow, toggleGroup, - JapanBankData.getString("account.type.select"), - JapanBankData.getString("account.type.futsu"), - JapanBankData.getString("account.type.touza"), - 0 - ); + addTopLabelRadioButtonRadioButton( + gridPane, gridRow, toggleGroup, + JapanBankData.getString("account.type.select"), + JapanBankData.getString("account.type.futsu"), + JapanBankData.getString("account.type.touza"), + 0 + ); toggleGroup.getToggles().get(0).setSelected(true); japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.futsu.ja")); @@ -314,66 +293,60 @@ private void addBankAccountTypeInput() // {{{ RadioButton touza = tuple3.third; toggleGroup.selectedToggleProperty().addListener - ( - (ov, oldValue, newValue) -> - { - if (futsu.isSelected()) - japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.futsu.ja")); - if (touza.isSelected()) - japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.touza.ja")); - } - ); - } // }}} + ( + (ov, oldValue, newValue) -> + { + if (futsu.isSelected()) + japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.futsu.ja")); + if (touza.isSelected()) + japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.touza.ja")); + } + ); + } @Override - public void updateFromInputs() // {{{ - { + public void updateFromInputs() { System.out.println("JapanBankTransferForm: updateFromInputs()"); - System.out.println("bankName: "+japanBankAccount.getBankName()); - System.out.println("bankCode: "+japanBankAccount.getBankCode()); - System.out.println("bankBranchName: "+japanBankAccount.getBankBranchName()); - System.out.println("bankBranchCode: "+japanBankAccount.getBankBranchCode()); - System.out.println("bankAccountType: "+japanBankAccount.getBankAccountType()); - System.out.println("bankAccountName: "+japanBankAccount.getBankAccountName()); - System.out.println("bankAccountNumber: "+japanBankAccount.getBankAccountNumber()); + System.out.println("bankName: " + japanBankAccount.getBankName()); + System.out.println("bankCode: " + japanBankAccount.getBankCode()); + System.out.println("bankBranchName: " + japanBankAccount.getBankBranchName()); + System.out.println("bankBranchCode: " + japanBankAccount.getBankBranchCode()); + System.out.println("bankAccountType: " + japanBankAccount.getBankAccountType()); + System.out.println("bankAccountName: " + japanBankAccount.getBankAccountName()); + System.out.println("bankAccountNumber: " + japanBankAccount.getBankAccountNumber()); super.updateFromInputs(); - } // }}} + } @Override - protected void autoFillNameTextField() // {{{ - { - if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) - { + protected void autoFillNameTextField() { + if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { accountNameTextField.setText( Res.get(paymentAccount.getPaymentMethod().getId()) - .concat(": ") - .concat(japanBankAccount.getBankName()) - .concat(" ") - .concat(japanBankAccount.getBankBranchName()) - .concat(" ") - .concat(japanBankAccount.getBankAccountNumber()) - .concat(" ") - .concat(japanBankAccount.getBankAccountName()) + .concat(": ") + .concat(japanBankAccount.getBankName()) + .concat(" ") + .concat(japanBankAccount.getBankBranchName()) + .concat(" ") + .concat(japanBankAccount.getBankAccountNumber()) + .concat(" ") + .concat(japanBankAccount.getBankAccountName()) ); } - } // }}} + } @Override - public void updateAllInputsValid() // {{{ - { + public void updateAllInputsValid() { boolean result = - ( - isAccountNameValid() && - inputValidator.validate(japanBankAccount.getBankCode()).isValid && - inputValidator.validate(japanBankAccount.getBankName()).isValid && - japanBankBranchCodeValidator.validate(japanBankAccount.getBankBranchCode()).isValid && - japanBankBranchNameValidator.validate(japanBankAccount.getBankBranchName()).isValid && - japanBankAccountNumberValidator.validate(japanBankAccount.getBankAccountNumber()).isValid && - japanBankAccountNameValidator.validate(japanBankAccount.getBankAccountName()).isValid && - inputValidator.validate(japanBankAccount.getBankAccountType()).isValid - ); + ( + isAccountNameValid() && + inputValidator.validate(japanBankAccount.getBankCode()).isValid && + inputValidator.validate(japanBankAccount.getBankName()).isValid && + japanBankBranchCodeValidator.validate(japanBankAccount.getBankBranchCode()).isValid && + japanBankBranchNameValidator.validate(japanBankAccount.getBankBranchName()).isValid && + japanBankAccountNumberValidator.validate(japanBankAccount.getBankAccountNumber()).isValid && + japanBankAccountNameValidator.validate(japanBankAccount.getBankAccountName()).isValid && + inputValidator.validate(japanBankAccount.getBankAccountType()).isValid + ); allInputsValid.set(result); - } // }}} + } } - -// vim:ts=4:sw=4:expandtab:foldmethod=marker:nowrap: diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java index 799a79a35f8..f02e59dbada 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java @@ -37,8 +37,6 @@ import bisq.common.util.Tuple2; -import org.apache.commons.lang3.StringUtils; - import javafx.scene.control.Label; import javafx.scene.layout.FlowPane; import javafx.scene.layout.GridPane; @@ -172,11 +170,7 @@ private MoneyGramAccount getMoneyGramPaymentAccount() { @Override protected void autoFillNameTextField() { - if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { - accountNameTextField.setText(Res.get(paymentAccount.getPaymentMethod().getId()) - .concat(": ") - .concat(StringUtils.abbreviate(holderNameInputTextField.getText(), 9))); - } + setAccountNameWithString(holderNameInputTextField.getText()); } @Override diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java index df2a8fd2d33..5909dd0f54a 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java @@ -73,6 +73,7 @@ import lombok.extern.slf4j.Slf4j; +import static bisq.desktop.util.DisplayUtils.createAccountName; import static bisq.desktop.util.FormBuilder.*; @Slf4j @@ -287,10 +288,8 @@ void applyTradeCurrency(TradeCurrency tradeCurrency, FiatCurrency defaultCurrenc void setAccountNameWithString(String name) { if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { - name = name.trim(); - name = StringUtils.abbreviate(name, 9); - String method = Res.get(paymentAccount.getPaymentMethod().getId()); - accountNameTextField.setText(method.concat(": ").concat(name)); + String accountName = createAccountName(paymentAccount.getPaymentMethod().getId(), name); + accountNameTextField.setText(accountName); } } diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java index baf3dd625f5..4742864e446 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java @@ -520,7 +520,7 @@ private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod, Paym case PaymentMethod.SPECIFIC_BANKS_ID: return new SpecificBankForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); case PaymentMethod.JAPAN_BANK_ID: - return new JapanBankTransferForm(paymentAccount, accountAgeWitnessService, japanBankTransferValidator, inputValidator, root, gridRow, formatter); + return new JapanBankTransferForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); case PaymentMethod.AUSTRALIA_PAYID_ID: return new AustraliaPayidForm(paymentAccount, accountAgeWitnessService, australiapayidValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.ALI_PAY_ID: diff --git a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java index e3ebb02d566..80f159fd48b 100644 --- a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java +++ b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java @@ -251,4 +251,16 @@ public static boolean hasBtcValidDecimals(String input, CoinFormatter coinFormat public static Coin reduceTo4Decimals(Coin coin, CoinFormatter coinFormatter) { return ParsingUtils.parseToCoin(coinFormatter.formatCoin(coin), coinFormatter); } + + public static String createAccountName(String paymentMethodId, String name) { + name = name.trim(); + name = StringUtils.abbreviate(name, 9); + String method = Res.get(paymentMethodId); + return method.concat(": ").concat(name); + } + + public static String createAssetsAccountName(String currency, String address) { + address = StringUtils.abbreviate(address, 9); + return currency.concat(": ").concat(address); + } } From a5b2859d7e4ee6523dc924b724516b8e8762b4d3 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:41:46 +0100 Subject: [PATCH 17/25] Simplify and clean up data models Conflicts: desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java --- .../AltCoinAccountsDataModel.java | 29 ++----------------- .../fiataccounts/FiatAccountsDataModel.java | 17 +++-------- 2 files changed, 7 insertions(+), 39 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java index da91488357a..183d4f14195 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java @@ -20,9 +20,7 @@ import bisq.desktop.common.model.ActivatableDataModel; import bisq.desktop.util.GUIUtil; -import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CryptoCurrency; -import bisq.core.locale.FiatCurrency; import bisq.core.locale.TradeCurrency; import bisq.core.offer.OpenOfferManager; import bisq.core.payment.AssetAccount; @@ -44,7 +42,6 @@ import java.util.ArrayList; import java.util.Comparator; -import java.util.List; import java.util.stream.Collectors; class AltCoinAccountsDataModel extends ActivatableDataModel { @@ -53,7 +50,6 @@ class AltCoinAccountsDataModel extends ActivatableDataModel { private final Preferences preferences; private final OpenOfferManager openOfferManager; private final TradeManager tradeManager; - private final AccountAgeWitnessService accountAgeWitnessService; final ObservableList paymentAccounts = FXCollections.observableArrayList(); private final SetChangeListener setChangeListener; private final String accountsFileName = "AltcoinPaymentAccounts"; @@ -65,14 +61,12 @@ public AltCoinAccountsDataModel(User user, Preferences preferences, OpenOfferManager openOfferManager, TradeManager tradeManager, - AccountAgeWitnessService accountAgeWitnessService, PersistenceProtoResolver persistenceProtoResolver, CorruptedStorageFileHandler corruptedStorageFileHandler) { this.user = user; this.preferences = preferences; this.openOfferManager = openOfferManager; this.tradeManager = tradeManager; - this.accountAgeWitnessService = accountAgeWitnessService; this.persistenceProtoResolver = persistenceProtoResolver; this.corruptedStorageFileHandler = corruptedStorageFileHandler; setChangeListener = change -> fillAndSortPaymentAccounts(); @@ -105,25 +99,8 @@ protected void deactivate() { public void onSaveNewAccount(PaymentAccount paymentAccount) { TradeCurrency singleTradeCurrency = paymentAccount.getSingleTradeCurrency(); - List tradeCurrencies = paymentAccount.getTradeCurrencies(); - if (singleTradeCurrency != null) { - if (singleTradeCurrency instanceof FiatCurrency) - preferences.addFiatCurrency((FiatCurrency) singleTradeCurrency); - else - preferences.addCryptoCurrency((CryptoCurrency) singleTradeCurrency); - } else if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) { - tradeCurrencies.forEach(tradeCurrency -> { - if (tradeCurrency instanceof FiatCurrency) - preferences.addFiatCurrency((FiatCurrency) tradeCurrency); - else - preferences.addCryptoCurrency((CryptoCurrency) tradeCurrency); - }); - } - + preferences.addCryptoCurrency((CryptoCurrency) singleTradeCurrency); user.addPaymentAccount(paymentAccount); - - if (!(paymentAccount instanceof AssetAccount)) - accountAgeWitnessService.publishMyAccountAgeWitness(paymentAccount.getPaymentAccountPayload()); } public boolean onDeleteAccount(PaymentAccount paymentAccount) { @@ -147,9 +124,9 @@ public void onSelectAccount(PaymentAccount paymentAccount) { public void exportAccounts(Stage stage) { if (user.getPaymentAccounts() != null) { - ArrayList accounts = new ArrayList<>(user.getPaymentAccounts().stream() + ArrayList accounts = user.getPaymentAccounts().stream() .filter(paymentAccount -> paymentAccount instanceof AssetAccount) - .collect(Collectors.toList())); + .collect(Collectors.toCollection(ArrayList::new)); GUIUtil.exportAccounts(accounts, accountsFileName, preferences, stage, persistenceProtoResolver, corruptedStorageFileHandler); } } diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java index f3c30abc368..b114c4cbbcb 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java @@ -21,7 +21,6 @@ import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; -import bisq.core.locale.CryptoCurrency; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.FiatCurrency; import bisq.core.locale.TradeCurrency; @@ -109,22 +108,14 @@ public void onSaveNewAccount(PaymentAccount paymentAccount) { TradeCurrency singleTradeCurrency = paymentAccount.getSingleTradeCurrency(); List tradeCurrencies = paymentAccount.getTradeCurrencies(); if (singleTradeCurrency != null) { - if (singleTradeCurrency instanceof FiatCurrency) - preferences.addFiatCurrency((FiatCurrency) singleTradeCurrency); - else - preferences.addCryptoCurrency((CryptoCurrency) singleTradeCurrency); + preferences.addFiatCurrency((FiatCurrency) singleTradeCurrency); } else if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) { if (tradeCurrencies.contains(CurrencyUtil.getDefaultTradeCurrency())) paymentAccount.setSelectedTradeCurrency(CurrencyUtil.getDefaultTradeCurrency()); else paymentAccount.setSelectedTradeCurrency(tradeCurrencies.get(0)); - tradeCurrencies.forEach(tradeCurrency -> { - if (tradeCurrency instanceof FiatCurrency) - preferences.addFiatCurrency((FiatCurrency) tradeCurrency); - else - preferences.addCryptoCurrency((CryptoCurrency) tradeCurrency); - }); + tradeCurrencies.forEach(tradeCurrency -> preferences.addFiatCurrency((FiatCurrency) tradeCurrency)); } user.addPaymentAccount(paymentAccount); @@ -154,9 +145,9 @@ public void onSelectAccount(PaymentAccount paymentAccount) { public void exportAccounts(Stage stage) { if (user.getPaymentAccounts() != null) { - ArrayList accounts = new ArrayList<>(user.getPaymentAccounts().stream() + ArrayList accounts = user.getPaymentAccounts().stream() .filter(paymentAccount -> !(paymentAccount instanceof AssetAccount)) - .collect(Collectors.toList())); + .collect(Collectors.toCollection(ArrayList::new)); GUIUtil.exportAccounts(accounts, accountsFileName, preferences, stage, persistenceProtoResolver, corruptedStorageFileHandler); } } From b7c4e5ed1718da25dd278e011b8f74a5a099a49b Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:46:27 +0100 Subject: [PATCH 18/25] Create BSQ account and take offer if not existing Conflicts: desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java desktop/src/main/java/bisq/desktop/util/DisplayUtils.java --- .../resources/i18n/displayStrings.properties | 2 + .../components/paymentmethods/AssetsForm.java | 5 +- .../main/offer/bisq_v1/MutableOfferView.java | 11 ++- .../bisq_v1/takeoffer/TakeOfferDataModel.java | 4 + .../bisq_v1/takeoffer/TakeOfferView.java | 20 ++++- .../bisq_v1/takeoffer/TakeOfferViewModel.java | 4 + .../main/offer/offerbook/OfferBookView.java | 73 +++++++++++-------- .../offer/offerbook/OfferBookViewModel.java | 52 +++++++++++-- .../java/bisq/desktop/util/DisplayUtils.java | 8 +- 9 files changed, 131 insertions(+), 48 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index fca54c8adb4..849ed0a3d78 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -336,6 +336,7 @@ market.trades.showVolumeInUSD=Show volume in USD offerbook.createOffer=Create offer offerbook.takeOffer=Take offer +offerbook.takeOffer.createAccount=Create account and take offer offerbook.takeOfferToBuy=Take offer to buy {0} offerbook.takeOfferToSell=Take offer to sell {0} offerbook.trader=Trader @@ -403,6 +404,7 @@ offerbook.warning.noTradingAccountForCurrency.headline=No payment account for se offerbook.warning.noTradingAccountForCurrency.msg=You don't have a payment account set up for the selected currency.\n\nWould you like to create an offer for another currency instead? offerbook.warning.noMatchingAccount.headline=No matching payment account. offerbook.warning.noMatchingAccount.msg=This offer uses a payment method you haven't set up yet. \n\nWould you like to set up a new payment account now? +offerbook.warning.noMatchingBsqAccount.msg=This offer uses BSQ as a payment method you haven't set up yet. \n\nWould you like to automatically create an account now? offerbook.warning.counterpartyTradeRestrictions=This offer cannot be taken due to counterparty trade restrictions diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java index 625b267d4ab..30f32c9ee52 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java @@ -166,10 +166,7 @@ public void updateFromInputs() { @Override protected void autoFillNameTextField() { if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) { - String currency = paymentAccount.getSingleTradeCurrency() != null ? paymentAccount.getSingleTradeCurrency().getCode() : ""; - if (currency != null) { - accountNameTextField.setText(createAssetsAccountName(currency, addressInputTextField.getText())); - } + accountNameTextField.setText(createAssetsAccountName(paymentAccount, addressInputTextField.getText())); } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index 8310f49cbba..1789d58ecb0 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -274,6 +274,11 @@ protected void doActivate() { buyBsqBox.setManaged(false); } + if (!model.isShowBuyBsqHint()) { + buyBsqBox.setVisible(false); + buyBsqBox.setManaged(false); + } + Label popOverLabel = OfferViewUtil.createPopOverLabel(Res.get("createOffer.triggerPrice.tooltip")); triggerPriceInfoInputTextField.setContentForPopOver(popOverLabel, AwesomeIcon.SHIELD); } @@ -405,11 +410,11 @@ private void onShowPayFundsScreen() { cancelButton1.setVisible(false); cancelButton1.setManaged(false); cancelButton1.setOnAction(null); - buyBsqBox.setVisible(false); - buyBsqBox.setManaged(false); tradeFeeInBtcToggle.setMouseTransparent(true); tradeFeeInBsqToggle.setMouseTransparent(true); + buyBsqBox.setVisible(false); + buyBsqBox.setManaged(false); setDepositTitledGroupBg.setVisible(false); setDepositTitledGroupBg.setManaged(false); @@ -896,6 +901,7 @@ private void createListeners() { tradeFeeInBsqToggle.setVisible(newValue); if (model.isShowBuyBsqHint()) { buyBsqBox.setVisible(newValue); + buyBsqBox.setManaged(newValue); } } }; @@ -1102,6 +1108,7 @@ private void addOptionsGroup() { Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( navigation, preferences); buyBsqBox = buyBsqButtonBox.second; + buyBsqBox.setManaged(false); buyBsqBox.setVisible(false); advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), getTradeFeeFieldsBox(), buyBsqBox); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java index c5914b0869b..a0ced384b14 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java @@ -712,4 +712,8 @@ boolean isTakerFeeValid() { public boolean isBsqForFeeAvailable() { return offerUtil.isBsqForTakerFeeAvailable(amount.get()); } + + public boolean isBuyBsqOffer() { + return !isBuyOffer() && getOffer().getCurrencyCode().equals("BSQ"); + } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index 2c9f6a2e90f..f87aa496cdb 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -132,7 +132,7 @@ public class TakeOfferView extends ActivatableViewAndModel buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( navigation, model.dataModel.preferences); + buyBsqBox = buyBsqButtonBox.second; + buyBsqBox.setManaged(false); + buyBsqBox.setVisible(false); - advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox(), buyBsqButtonBox.second); + advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox(), buyBsqBox); } private void addButtons() { diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java index 1376b9baec0..61c52a4355e 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java @@ -800,4 +800,8 @@ String getPercentagePriceDescription() { Res.get("shared.aboveInPercent"); } } + + public boolean isShowBuyBsqHint() { + return !dataModel.isBsqForFeeAvailable() && !dataModel.isBuyBsqOffer(); + } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java index 4998f645524..191068be48c 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java @@ -33,6 +33,7 @@ import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.MainView; import bisq.desktop.main.account.AccountView; +import bisq.desktop.main.account.content.altcoinaccounts.AltCoinAccountsView; import bisq.desktop.main.account.content.fiataccounts.FiatAccountsView; import bisq.desktop.main.funds.FundsView; import bisq.desktop.main.funds.withdrawal.WithdrawalView; @@ -136,11 +137,15 @@ public class OfferBookView extends ActivatableViewAndModel paymentMethodComboBox; private AutoTooltipButton createOfferButton; private AutoTooltipSlideToggleButton matchingOffersToggle; - private AutoTooltipTableColumn amountColumn, volumeColumn, marketColumn, - priceColumn, paymentMethodColumn, depositColumn, signingStateColumn, avatarColumn; + private AutoTooltipTableColumn amountColumn; + private AutoTooltipTableColumn volumeColumn; + private AutoTooltipTableColumn marketColumn; + private AutoTooltipTableColumn priceColumn; + private AutoTooltipTableColumn depositColumn; + private AutoTooltipTableColumn signingStateColumn; + private AutoTooltipTableColumn avatarColumn; private TableView tableView; - private OfferView.OfferActionHandler offerActionHandler; private int gridRow = 0; private Label nrOfOffersLabel; private ListChangeListener offerListListener; @@ -243,7 +248,7 @@ public void initialize() { tableView.getColumns().add(amountColumn); volumeColumn = getVolumeColumn(); tableView.getColumns().add(volumeColumn); - paymentMethodColumn = getPaymentMethodColumn(); + AutoTooltipTableColumn paymentMethodColumn = getPaymentMethodColumn(); tableView.getColumns().add(paymentMethodColumn); depositColumn = getDepositColumn(); tableView.getColumns().add(depositColumn); @@ -559,7 +564,7 @@ private void disableCreateOfferButton() { disabledCreateOfferButtonTooltip.setManaged(true); disabledCreateOfferButtonTooltip.setVisible(true); - offerActionHandler.onCreateOffer(model.getSelectedTradeCurrency(), model.selectedPaymentMethod); + model.onCreateOffer(); } public void setDirection(OfferDirection direction) { @@ -603,7 +608,7 @@ private void setDirectionTitles() { } public void setOfferActionHandler(OfferView.OfferActionHandler offerActionHandler) { - this.offerActionHandler = offerActionHandler; + model.setOfferActionHandler(offerActionHandler); } public void onTabSelected(boolean isSelected) { @@ -620,9 +625,7 @@ private void onCreateOffer() { new Popup().headLine(Res.get("offerbook.warning.noTradingAccountForCurrency.headline")) .instruction(Res.get("offerbook.warning.noTradingAccountForCurrency.msg")) .actionButtonText(Res.get("offerbook.yesCreateOffer")) - .onAction(() -> { - disableCreateOfferButton(); - }) + .onAction(this::disableCreateOfferButton) .secondaryActionButtonText(Res.get("offerbook.setupNewAccount")) .onSecondaryAction(() -> { navigation.setReturnPath(navigation.getCurrentPath()); @@ -639,17 +642,12 @@ private void onCreateOffer() { private void onShowInfo(Offer offer, OfferFilterService.Result result) { switch (result) { - case VALID: - break; case API_DISABLED: DevEnv.logErrorAndThrowIfDevMode("We are in desktop and in the taker position " + "viewing offers, so it cannot be that we got that result as we are not an API user."); break; case HAS_NO_PAYMENT_ACCOUNT_VALID_FOR_OFFER: - openPopupForMissingAccountSetup(Res.get("offerbook.warning.noMatchingAccount.headline"), - Res.get("offerbook.warning.noMatchingAccount.msg"), - FiatAccountsView.class, - "navigation.account"); + openPopupForMissingAccountSetup(offer); break; case HAS_NOT_SAME_PROTOCOL_VERSION: new Popup().warning(Res.get("offerbook.warning.wrongTradeProtocol")).show(); @@ -693,6 +691,7 @@ private void onShowInfo(Offer offer, OfferFilterService.Result result) { case HIDE_BSQ_SWAPS_DUE_DAO_DEACTIVATED: new Popup().warning(Res.get("offerbook.warning.hideBsqSwapsDueDaoDeactivated")).show(); break; + case VALID: default: break; } @@ -704,10 +703,10 @@ private void onTakeOffer(Offer offer) { offer.getPaymentMethod().getId().equals(PaymentMethod.CASH_DEPOSIT.getId())) { new Popup().confirmation(Res.get("popup.info.cashDepositInfo", offer.getBankId())) .actionButtonText(Res.get("popup.info.cashDepositInfo.confirm")) - .onAction(() -> offerActionHandler.onTakeOffer(offer)) + .onAction(() -> model.onTakeOffer(offer)) .show(); } else { - offerActionHandler.onTakeOffer(offer); + model.onTakeOffer(offer); } } } @@ -746,14 +745,26 @@ private void doRemoveOffer(Offer offer) { }); } - private void openPopupForMissingAccountSetup(String headLine, String message, Class target, String targetAsString) { - new Popup().headLine(headLine) - .instruction(message) - .actionButtonTextWithGoTo(targetAsString) - .onAction(() -> { - navigation.setReturnPath(navigation.getCurrentPath()); - navigation.navigateTo(MainView.class, AccountView.class, target); - }).show(); + private void openPopupForMissingAccountSetup(Offer offer) { + String headline = Res.get("offerbook.warning.noMatchingAccount.headline"); + + if (offer.getCurrencyCode().equals("BSQ")) { + new Popup().headLine(headline) + .instruction(Res.get("offerbook.warning.noMatchingBsqAccount.msg")) + .actionButtonText(Res.get("offerbook.takeOffer.createAccount")) + .onAction(() -> model.createBsqAccountAndTakeOffer(offer)).show(); + } else { + + var accountViewClass = CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()) ? FiatAccountsView.class : AltCoinAccountsView.class; + + new Popup().headLine(headline) + .instruction(Res.get("offerbook.warning.noMatchingAccount.msg")) + .actionButtonTextWithGoTo("navigation.account") + .onAction(() -> { + navigation.setReturnPath(navigation.getCurrentPath()); + navigation.navigateTo(MainView.class, AccountView.class, accountViewClass); + }).show(); + } } /////////////////////////////////////////////////////////////////////////////////////////// @@ -1086,13 +1097,11 @@ public void updateItem(final OfferBookListItem item, boolean empty) { tableRow.setOnMousePressed(null); } else { button.setDefaultButton(false); - if (!myOffer) { - tableRow.setOnMousePressed(e -> { - // ugly hack to get the icon clickable when deactivated - if (!(e.getTarget() instanceof ImageView || e.getTarget() instanceof Canvas)) - onShowInfo(offer, canTakeOfferResult); - }); - } + tableRow.setOnMousePressed(e -> { + // ugly hack to get the icon clickable when deactivated + if (!(e.getTarget() instanceof ImageView || e.getTarget() instanceof Canvas)) + onShowInfo(offer, canTakeOfferResult); + }); } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index 1e9a4d226b4..5bd62a5b7da 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -20,13 +20,17 @@ import bisq.desktop.Navigation; import bisq.desktop.common.model.ActivatableViewModel; import bisq.desktop.main.MainView; +import bisq.desktop.main.offer.OfferView; +import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.settings.SettingsView; import bisq.desktop.main.settings.preferences.PreferencesView; import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; +import bisq.core.api.CoreApi; import bisq.core.btc.setup.WalletsSetup; +import bisq.core.btc.wallet.BsqWalletService; import bisq.core.locale.BankUtil; import bisq.core.locale.CountryUtil; import bisq.core.locale.CryptoCurrency; @@ -111,6 +115,8 @@ class OfferBookViewModel extends ActivatableViewModel { private final BsqFormatter bsqFormatter; private final FilteredList filteredItems; + private final BsqWalletService bsqWalletService; + private final CoreApi coreApi; private final SortedList sortedItems; private final ListChangeListener tradeCurrencyListChangeListener; private final ListChangeListener filterItemsListener; @@ -121,6 +127,8 @@ class OfferBookViewModel extends ActivatableViewModel { final StringProperty tradeCurrencyCode = new SimpleStringProperty(); + private OfferView.OfferActionHandler offerActionHandler; + // If id is empty string we ignore filter (display all methods) PaymentMethod selectedPaymentMethod = getShowAllEntryForPaymentMethod(); @@ -154,7 +162,9 @@ public OfferBookViewModel(User user, PriceUtil priceUtil, OfferFilterService offerFilterService, @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter, - BsqFormatter bsqFormatter) { + BsqFormatter bsqFormatter, + BsqWalletService bsqWalletService, + CoreApi coreApi) { super(); this.openOfferManager = openOfferManager; @@ -173,6 +183,8 @@ public OfferBookViewModel(User user, this.bsqFormatter = bsqFormatter; this.filteredItems = new FilteredList<>(offerBook.getOfferBookListItems()); + this.bsqWalletService = bsqWalletService; + this.coreApi = coreApi; this.sortedItems = new SortedList<>(filteredItems); tradeCurrencyListChangeListener = c -> fillAllTradeCurrencies(); @@ -207,7 +219,7 @@ public OfferBookViewModel(User user, .filter(o -> o.getOffer().isUseMarketBasedPrice()) .max(Comparator.comparing(o -> new DecimalFormat("#0.00").format(o.getOffer().getMarketPriceMargin() * 100).length())); - highestMarketPriceMarginOffer.ifPresent(offerBookListItem -> maxPlacesForMarketPriceMargin.set(formatMarketPriceMargin(offerBookListItem.getOffer(), false).length())); + highestMarketPriceMarginOffer.ifPresent(offerBookListItem -> maxPlacesForMarketPriceMargin.set(formatMarketPriceMargin(offerBookListItem.getOffer()).length())); }; } @@ -413,16 +425,12 @@ public Optional getMarketBasedPrice(Offer offer) { return priceUtil.getMarketBasedPrice(offer, direction); } - String formatMarketPriceMargin(Offer offer, boolean decimalAligned) { + String formatMarketPriceMargin(Offer offer) { String postFix = ""; if (offer.isUseMarketBasedPrice()) { postFix = " (" + FormattingUtils.formatPercentagePrice(offer.getMarketPriceMargin()) + ")"; } - if (decimalAligned) { - postFix = FormattingUtils.fillUpPlacesWithEmptyStrings(postFix, maxPlacesForMarketPriceMargin.get()); - } - return postFix; } @@ -670,4 +678,34 @@ private TradeCurrency getEditEntryForCurrency() { PaymentMethod getShowAllEntryForPaymentMethod() { return PaymentMethod.getDummyPaymentMethod(GUIUtil.SHOW_ALL_FLAG); } + + public void createBsqAccountAndTakeOffer(Offer offer) { + var unusedBsqAddressAsString = bsqWalletService.getUnusedBsqAddressAsString(); + + // create required BSQ payment account + boolean isInstantPaymentMethod = offer.getPaymentMethod().equals(PaymentMethod.BLOCK_CHAINS_INSTANT); + coreApi.createCryptoCurrencyPaymentAccount(DisplayUtils.createAssetsAccountName("BSQ", unusedBsqAddressAsString), + "BSQ", + unusedBsqAddressAsString, + isInstantPaymentMethod); + + if (isInstantPaymentMethod) { + new Popup().information(Res.get("payment.altcoin.tradeInstant.popup")).show(); + } + + // take offer + onTakeOffer(offer); + } + + public void setOfferActionHandler(OfferView.OfferActionHandler offerActionHandler) { + this.offerActionHandler = offerActionHandler; + } + + public void onCreateOffer() { + offerActionHandler.onCreateOffer(getSelectedTradeCurrency(), selectedPaymentMethod); + } + + public void onTakeOffer(Offer offer) { + offerActionHandler.onTakeOffer(offer); + } } diff --git a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java index 80f159fd48b..fb9674f9dd0 100644 --- a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java +++ b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java @@ -6,8 +6,9 @@ import bisq.core.monetary.Price; import bisq.core.monetary.Volume; import bisq.core.offer.Offer; -import bisq.core.offer.OfferDirection; import bisq.core.util.FormattingUtils; +import bisq.core.offer.OfferDirection; +import bisq.core.payment.PaymentAccount; import bisq.core.util.ParsingUtils; import bisq.core.util.VolumeUtil; import bisq.core.util.coin.CoinFormatter; @@ -259,6 +260,11 @@ public static String createAccountName(String paymentMethodId, String name) { return method.concat(": ").concat(name); } + public static String createAssetsAccountName(PaymentAccount paymentAccount, String address) { + String currency = paymentAccount.getSingleTradeCurrency() != null ? paymentAccount.getSingleTradeCurrency().getCode() : ""; + return createAssetsAccountName(currency, address); + } + public static String createAssetsAccountName(String currency, String address) { address = StringUtils.abbreviate(address, 9); return currency.concat(": ").concat(address); From 55826cb4a23ff374aed6d4f4ed4f63ee5c576ffa Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Wed, 13 Oct 2021 12:46:51 +0200 Subject: [PATCH 19/25] Fix failing tests --- .../offerbook/OfferBookViewModelTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/desktop/src/test/java/bisq/desktop/main/offer/offerbook/OfferBookViewModelTest.java b/desktop/src/test/java/bisq/desktop/main/offer/offerbook/OfferBookViewModelTest.java index d8fd3ca11af..5e5e25cb8fa 100644 --- a/desktop/src/test/java/bisq/desktop/main/offer/offerbook/OfferBookViewModelTest.java +++ b/desktop/src/test/java/bisq/desktop/main/offer/offerbook/OfferBookViewModelTest.java @@ -239,7 +239,7 @@ public void testMaxCharactersForAmountWithNoOffers() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); assertEquals(0, model.maxPlacesForAmount.intValue()); } @@ -253,7 +253,7 @@ public void testMaxCharactersForAmount() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); model.activate(); assertEquals(6, model.maxPlacesForAmount.intValue()); @@ -271,7 +271,7 @@ public void testMaxCharactersForAmountRange() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); model.activate(); assertEquals(15, model.maxPlacesForAmount.intValue()); @@ -290,7 +290,7 @@ public void testMaxCharactersForVolumeWithNoOffers() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); assertEquals(0, model.maxPlacesForVolume.intValue()); } @@ -304,7 +304,7 @@ public void testMaxCharactersForVolume() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); model.activate(); assertEquals(5, model.maxPlacesForVolume.intValue()); @@ -322,7 +322,7 @@ public void testMaxCharactersForVolumeRange() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); model.activate(); assertEquals(9, model.maxPlacesForVolume.intValue()); @@ -341,7 +341,7 @@ public void testMaxCharactersForPriceWithNoOffers() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); assertEquals(0, model.maxPlacesForPrice.intValue()); } @@ -355,7 +355,7 @@ public void testMaxCharactersForPrice() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); model.activate(); assertEquals(7, model.maxPlacesForPrice.intValue()); @@ -373,7 +373,7 @@ public void testMaxCharactersForPriceDistanceWithNoOffers() { when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems); final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); assertEquals(0, model.maxPlacesForMarketPriceMargin.intValue()); } @@ -408,7 +408,7 @@ public void testMaxCharactersForPriceDistance() { offerBookListItems.addAll(item1, item2); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, priceFeedService, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); model.activate(); assertEquals(8, model.maxPlacesForMarketPriceMargin.intValue()); //" (1.97%)" @@ -429,7 +429,7 @@ public void testGetPrice() { when(priceFeedService.getMarketPrice(anyString())).thenReturn(new MarketPrice("USD", 12684.0450, Instant.now().getEpochSecond(), true)); final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null, - null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter()); + null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter(), null, null); final OfferBookListItem item = make(btcBuyItem.but( with(useMarketBasedPrice, true), From e17fd9ef54646b6e3084864f585290b0850002b0 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Fri, 15 Oct 2021 11:10:18 +0200 Subject: [PATCH 20/25] Add informational popup after account creation --- .../resources/i18n/displayStrings.properties | 7 +++++++ .../main/offer/offerbook/OfferBookView.java | 13 +++++++++++- .../offer/offerbook/OfferBookViewModel.java | 20 +++++++------------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 849ed0a3d78..fc6a23dfe5d 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -443,6 +443,13 @@ offerbook.info.buyAtFixedPrice=You will buy at this fixed price. offerbook.info.sellAtFixedPrice=You will sell at this fixed price. offerbook.info.noArbitrationInUserLanguage=In case of a dispute, please note that arbitration for this offer will be handled in {0}. Language is currently set to {1}. offerbook.info.roundedFiatVolume=The amount was rounded to increase the privacy of your trade. +offerbook.info.accountCreated.headline=Congratulations +offerbook.info.accountCreated.message=You''ve just successfully created a BSQ payment account.\n\ + Your account can be found under Account > Altcoins Accounts > {0} and your BSQ wallet under DAO > BSQ Wallet.\n\n +offerbook.info.accountCreated.tradeInstant=As you've chosen to take a BSQ instant offer a BSQ instant account was created for you. \ + For instant trading it is required that both trading peers are online to be able \ + to complete the trade in less than 1 hour.\n\n +offerbook.info.accountCreated.takeOffer=You can no proceed to take this offer after closing this popup. offerbook.bsqSwap.createOffer=Create Bsq swap offer diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java index 191068be48c..4d5c9055ebb 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java @@ -752,7 +752,18 @@ private void openPopupForMissingAccountSetup(Offer offer) { new Popup().headLine(headline) .instruction(Res.get("offerbook.warning.noMatchingBsqAccount.msg")) .actionButtonText(Res.get("offerbook.takeOffer.createAccount")) - .onAction(() -> model.createBsqAccountAndTakeOffer(offer)).show(); + .onAction(() -> { + var bsqAccount = model.createBsqAccount(offer); + var message = Res.get("offerbook.info.accountCreated.message", bsqAccount.getAccountName()); + if (model.isInstantPaymentMethod(offer)) { + message += Res.get("offerbook.info.accountCreated.tradeInstant"); + } + message += Res.get("offerbook.info.accountCreated.takeOffer"); + new Popup().headLine(Res.get("offerbook.info.accountCreated.headline")) + .information(message) + .onClose(() -> model.onTakeOffer(offer)) + .show(); + }).show(); } else { var accountViewClass = CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()) ? FiatAccountsView.class : AltCoinAccountsView.class; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index 5bd62a5b7da..51c0da573a0 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -21,7 +21,6 @@ import bisq.desktop.common.model.ActivatableViewModel; import bisq.desktop.main.MainView; import bisq.desktop.main.offer.OfferView; -import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.settings.SettingsView; import bisq.desktop.main.settings.preferences.PreferencesView; import bisq.desktop.util.DisplayUtils; @@ -679,22 +678,17 @@ PaymentMethod getShowAllEntryForPaymentMethod() { return PaymentMethod.getDummyPaymentMethod(GUIUtil.SHOW_ALL_FLAG); } - public void createBsqAccountAndTakeOffer(Offer offer) { + public boolean isInstantPaymentMethod(Offer offer) { + return offer.getPaymentMethod().equals(PaymentMethod.BLOCK_CHAINS_INSTANT); + } + + public PaymentAccount createBsqAccount(Offer offer) { var unusedBsqAddressAsString = bsqWalletService.getUnusedBsqAddressAsString(); - // create required BSQ payment account - boolean isInstantPaymentMethod = offer.getPaymentMethod().equals(PaymentMethod.BLOCK_CHAINS_INSTANT); - coreApi.createCryptoCurrencyPaymentAccount(DisplayUtils.createAssetsAccountName("BSQ", unusedBsqAddressAsString), + return coreApi.createCryptoCurrencyPaymentAccount(DisplayUtils.createAssetsAccountName("BSQ", unusedBsqAddressAsString), "BSQ", unusedBsqAddressAsString, - isInstantPaymentMethod); - - if (isInstantPaymentMethod) { - new Popup().information(Res.get("payment.altcoin.tradeInstant.popup")).show(); - } - - // take offer - onTakeOffer(offer); + isInstantPaymentMethod(offer)); } public void setOfferActionHandler(OfferView.OfferActionHandler offerActionHandler) { From 0e4933f8d1814a901aafddb4b49df0e536c24f6a Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 10:55:51 +0100 Subject: [PATCH 21/25] Fix rebase merge errors --- .../java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java | 2 +- .../java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java | 1 + .../desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java | 2 +- .../bisq/desktop/main/offer/offerbook/OfferBookViewModel.java | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index 1789d58ecb0..244c2f52997 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -121,7 +121,7 @@ import org.jetbrains.annotations.NotNull; import static bisq.core.payment.payload.PaymentMethod.HAL_CASH_ID; -import static bisq.desktop.main.offer.OfferViewUtil.addPayInfoEntry; +import static bisq.desktop.main.offer.bisq_v1.OfferViewUtil.addPayInfoEntry; import static bisq.desktop.util.FormBuilder.*; import static javafx.beans.binding.Bindings.createStringBinding; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 816ad8cac81..2558c62a455 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -22,6 +22,7 @@ import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.main.MainView; +import bisq.desktop.main.offer.SellOfferView; import bisq.desktop.main.offer.offerbook.OfferBookView; import bisq.desktop.main.overlays.popups.Popup; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index f87aa496cdb..520eb9d9f3e 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -117,7 +117,7 @@ import org.jetbrains.annotations.NotNull; -import static bisq.desktop.main.offer.OfferViewUtil.addPayInfoEntry; +import static bisq.desktop.main.offer.bisq_v1.OfferViewUtil.addPayInfoEntry; import static bisq.desktop.util.FormBuilder.*; import static javafx.beans.binding.Bindings.createStringBinding; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index 51c0da573a0..6ac643e533e 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -688,7 +688,8 @@ public PaymentAccount createBsqAccount(Offer offer) { return coreApi.createCryptoCurrencyPaymentAccount(DisplayUtils.createAssetsAccountName("BSQ", unusedBsqAddressAsString), "BSQ", unusedBsqAddressAsString, - isInstantPaymentMethod(offer)); + isInstantPaymentMethod(offer), + false); } public void setOfferActionHandler(OfferView.OfferActionHandler offerActionHandler) { From fac4b3c5c30186af64737955f180f433403230c5 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 13:22:32 +0100 Subject: [PATCH 22/25] Fix combobox BSQ selection error --- .../main/offer/offerbook/OfferBookView.java | 5 ++++ .../offer/offerbook/OfferBookViewModel.java | 29 ++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java index 4d5c9055ebb..4f571c2bc13 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java @@ -613,6 +613,11 @@ public void setOfferActionHandler(OfferView.OfferActionHandler offerActionHandle public void onTabSelected(boolean isSelected) { model.onTabSelected(isSelected); + + if (isSelected) { + updateCurrencyComboBoxFromModel(); + root.requestFocus(); + } } /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index 6ac643e533e..fa747c27d11 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -226,16 +226,7 @@ public OfferBookViewModel(User user, protected void activate() { filteredItems.addListener(filterItemsListener); - String code = direction == OfferDirection.BUY ? preferences.getBuyScreenCurrencyCode() : preferences.getSellScreenCurrencyCode(); - if (code != null && !code.isEmpty() && !isShowAllEntry(code) && - CurrencyUtil.getTradeCurrency(code).isPresent()) { - showAllTradeCurrenciesProperty.set(false); - selectedTradeCurrency = CurrencyUtil.getTradeCurrency(code).get(); - } else { - showAllTradeCurrenciesProperty.set(true); - selectedTradeCurrency = GlobalSettings.getDefaultTradeCurrency(); - } - tradeCurrencyCode.set(selectedTradeCurrency.getCode()); + updateSelectedTradeCurrency(); if (user != null) { disableMatchToggle.set(user.getPaymentAccounts() == null || user.getPaymentAccounts().isEmpty()); @@ -269,6 +260,11 @@ void initWithDirection(OfferDirection direction) { void onTabSelected(boolean isSelected) { this.isTabSelected = isSelected; setMarketPriceFeedCurrency(); + + if (isTabSelected) { + updateSelectedTradeCurrency(); + filterOffers(); + } } /////////////////////////////////////////////////////////////////////////////////////////// @@ -703,4 +699,17 @@ public void onCreateOffer() { public void onTakeOffer(Offer offer) { offerActionHandler.onTakeOffer(offer); } + + private void updateSelectedTradeCurrency() { + String code = direction == OfferDirection.BUY ? preferences.getBuyScreenCurrencyCode() : preferences.getSellScreenCurrencyCode(); + if (code != null && !code.isEmpty() && !isShowAllEntry(code) && + CurrencyUtil.getTradeCurrency(code).isPresent()) { + showAllTradeCurrenciesProperty.set(false); + selectedTradeCurrency = CurrencyUtil.getTradeCurrency(code).get(); + } else { + showAllTradeCurrenciesProperty.set(true); + selectedTradeCurrency = GlobalSettings.getDefaultTradeCurrency(); + } + tradeCurrencyCode.set(selectedTradeCurrency.getCode()); + } } From 12cd88ce3248d2a7870e9322ea4550ea2dd43e60 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Thu, 4 Nov 2021 13:23:00 +0100 Subject: [PATCH 23/25] Fix translations --- core/src/main/resources/i18n/displayStrings.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index fc6a23dfe5d..0fbc9aa99af 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -446,10 +446,10 @@ offerbook.info.roundedFiatVolume=The amount was rounded to increase the privacy offerbook.info.accountCreated.headline=Congratulations offerbook.info.accountCreated.message=You''ve just successfully created a BSQ payment account.\n\ Your account can be found under Account > Altcoins Accounts > {0} and your BSQ wallet under DAO > BSQ Wallet.\n\n -offerbook.info.accountCreated.tradeInstant=As you've chosen to take a BSQ instant offer a BSQ instant account was created for you. \ - For instant trading it is required that both trading peers are online to be able \ - to complete the trade in less than 1 hour.\n\n -offerbook.info.accountCreated.takeOffer=You can no proceed to take this offer after closing this popup. +offerbook.info.accountCreated.tradeInstant=You've chosen to take a BSQ instant offer, so a BSQ instant payment account was created for you. \ + Be aware that instant trades are meant to be completed within 1 hour, \ + so you should be online and available for the next 1 hour.\n\n +offerbook.info.accountCreated.takeOffer=You can now proceed to take this offer after closing this popup. offerbook.bsqSwap.createOffer=Create Bsq swap offer From 2b906332639224e7c5ed3197599d3b2b1d233bdd Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Mon, 8 Nov 2021 11:05:27 +0100 Subject: [PATCH 24/25] Improve naming of helper method --- .../desktop/main/offer/bisq_v1/MutableOfferDataModel.java | 4 +++- .../desktop/main/offer/bisq_v1/MutableOfferViewModel.java | 2 +- .../main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java | 4 +++- .../main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java index da401709ee2..f5fdba99dc4 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferDataModel.java @@ -781,7 +781,9 @@ boolean isBsqForFeeAvailable() { return offerUtil.isBsqForMakerFeeAvailable(amount.get()); } - boolean isBuyBsqOffer() { + boolean isAttemptToBuyBsq() { + // When you buy an asset you actually sell BTC. + // This is why an offer to buy BSQ is actually an offer to sell BTC for BSQ. return !isBuyOffer() && getTradeCurrency().getCode().equals("BSQ"); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java index c07dde3d61a..3ab607ca958 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferViewModel.java @@ -1355,6 +1355,6 @@ private void updateMarketPriceToManual() { } public boolean isShowBuyBsqHint() { - return !dataModel.isBsqForFeeAvailable() && !dataModel.isBuyBsqOffer(); + return !dataModel.isBsqForFeeAvailable() && !dataModel.isAttemptToBuyBsq(); } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java index a0ced384b14..26171216a1b 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferDataModel.java @@ -713,7 +713,9 @@ public boolean isBsqForFeeAvailable() { return offerUtil.isBsqForTakerFeeAvailable(amount.get()); } - public boolean isBuyBsqOffer() { + public boolean isAttemptToBuyBsq() { + // When you buy an asset you actually sell BTC. + // This is why an offer to buy BSQ is actually an offer to sell BTC for BSQ. return !isBuyOffer() && getOffer().getCurrencyCode().equals("BSQ"); } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java index 61c52a4355e..5d8c180d351 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferViewModel.java @@ -802,6 +802,6 @@ String getPercentagePriceDescription() { } public boolean isShowBuyBsqHint() { - return !dataModel.isBsqForFeeAvailable() && !dataModel.isBuyBsqOffer(); + return !dataModel.isBsqForFeeAvailable() && !dataModel.isAttemptToBuyBsq(); } } From 07e224e40ad838a968b1883be3ff8bfa6384abb0 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Mon, 8 Nov 2021 11:06:00 +0100 Subject: [PATCH 25/25] Simplify containers and improve truncation behavior --- .../main/offer/bisq_v1/MutableOfferView.java | 11 +++++++---- .../desktop/main/offer/bisq_v1/OfferViewUtil.java | 15 ++++++--------- .../offer/bisq_v1/takeoffer/TakeOfferView.java | 11 +++++++---- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java index 244c2f52997..af7581701aa 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/MutableOfferView.java @@ -153,10 +153,10 @@ public abstract class MutableOfferView> exten private ComboBox paymentAccountsComboBox; private ComboBox currencyComboBox; private ImageView qrCodeImageView; - private VBox currencySelection, fixedPriceBox, percentagePriceBox, currencyTextFieldBox, triggerPriceVBox, buyBsqBox; + private VBox currencySelection, fixedPriceBox, percentagePriceBox, currencyTextFieldBox, triggerPriceVBox; private HBox fundingHBox, firstRowHBox, secondRowHBox, placeOfferBox, amountValueCurrencyBox, priceAsPercentageValueCurrencyBox, volumeValueCurrencyBox, priceValueCurrencyBox, - minAmountValueCurrencyBox, advancedOptionsBox, triggerPriceHBox; + minAmountValueCurrencyBox, advancedOptionsBox, triggerPriceHBox, buyBsqBox; private Subscription isWaitingForFundsSubscription, balanceSubscription; private ChangeListener amountFocusedListener, minAmountFocusedListener, volumeFocusedListener, @@ -1100,18 +1100,21 @@ private void addOptionsGroup() { advancedOptionsBox.setSpacing(40); GridPane.setRowIndex(advancedOptionsBox, gridRow); + GridPane.setColumnSpan(advancedOptionsBox, GridPane.REMAINING); GridPane.setColumnIndex(advancedOptionsBox, 0); GridPane.setHalignment(advancedOptionsBox, HPos.LEFT); GridPane.setMargin(advancedOptionsBox, new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); gridPane.getChildren().add(advancedOptionsBox); - Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( + Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( navigation, preferences); buyBsqBox = buyBsqButtonBox.second; buyBsqBox.setManaged(false); buyBsqBox.setVisible(false); - advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), getTradeFeeFieldsBox(), buyBsqBox); + VBox tradeFeeFieldsBox = getTradeFeeFieldsBox(); + tradeFeeFieldsBox.setMinWidth(240); + advancedOptionsBox.getChildren().addAll(getBuyerSecurityDepositBox(), tradeFeeFieldsBox, buyBsqBox); Tuple2 tuple = add2ButtonsAfterGroup(gridPane, ++gridRow, Res.get("shared.nextStep"), Res.get("shared.cancel")); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java index 2558c62a455..712a8fdd20b 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/OfferViewUtil.java @@ -36,7 +36,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; import javafx.geometry.HPos; import javafx.geometry.Insets; @@ -85,12 +84,13 @@ public static void addPayInfoEntry(GridPane infoGridPane, int row, String labelT infoGridPane.getChildren().addAll(label, textField); } - public static Tuple2 createBuyBsqButtonBox(Navigation navigation, + public static Tuple2 createBuyBsqButtonBox(Navigation navigation, Preferences preferences) { String buyBsqText = Res.get("shared.buyCurrency", "BSQ"); var buyBsqButton = new AutoTooltipButton(buyBsqText); buyBsqButton.getStyleClass().add("action-button"); buyBsqButton.getStyleClass().add("tiny-button"); + buyBsqButton.setMinWidth(60); buyBsqButton.setOnAction(e -> openBuyBsqOfferBook(navigation, preferences) ); @@ -101,17 +101,14 @@ public static Tuple2 createBuyBsqButtonBox(Navigation n .actionButtonText(buyBsqText) .buttonAlignment(HPos.CENTER) .onAction(() -> openBuyBsqOfferBook(navigation, preferences)).show()); + learnMore.setMinWidth(100); - final HBox buyBsqBox = new HBox(buyBsqButton, info, learnMore); + HBox buyBsqBox = new HBox(buyBsqButton, info, learnMore); buyBsqBox.setAlignment(Pos.BOTTOM_LEFT); buyBsqBox.setSpacing(10); + buyBsqBox.setPadding(new Insets(0, 0, 4, -20)); - final VBox buyBsqButtonVBox = new VBox(buyBsqBox); - buyBsqButtonVBox.setAlignment(Pos.BOTTOM_LEFT); - buyBsqButtonVBox.setPadding(new Insets(0, 0, 0, -20)); - VBox.setMargin(buyBsqButton, new Insets(0, 0, 4, 0)); - - return new Tuple2<>(buyBsqButton, buyBsqButtonVBox); + return new Tuple2<>(buyBsqButton, buyBsqBox); } private static void openBuyBsqOfferBook(Navigation navigation, Preferences preferences) { diff --git a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java index 520eb9d9f3e..21a08d06e35 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/bisq_v1/takeoffer/TakeOfferView.java @@ -132,10 +132,10 @@ public class TakeOfferView extends ActivatableViewAndModel paymentAccountsComboBox; private Label amountDescriptionLabel, paymentMethodLabel, @@ -878,18 +878,21 @@ private void addOptionsGroup() { advancedOptionsBox.setSpacing(40); GridPane.setRowIndex(advancedOptionsBox, gridRow); + GridPane.setColumnSpan(advancedOptionsBox, GridPane.REMAINING); GridPane.setColumnIndex(advancedOptionsBox, 0); GridPane.setHalignment(advancedOptionsBox, HPos.LEFT); GridPane.setMargin(advancedOptionsBox, new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); gridPane.getChildren().add(advancedOptionsBox); - Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( + Tuple2 buyBsqButtonBox = OfferViewUtil.createBuyBsqButtonBox( navigation, model.dataModel.preferences); buyBsqBox = buyBsqButtonBox.second; buyBsqBox.setManaged(false); buyBsqBox.setVisible(false); - advancedOptionsBox.getChildren().addAll(getTradeFeeFieldsBox(), buyBsqBox); + VBox tradeFeeFieldsBox = getTradeFeeFieldsBox(); + tradeFeeFieldsBox.setMinWidth(240); + advancedOptionsBox.getChildren().addAll(tradeFeeFieldsBox, buyBsqBox); } private void addButtons() {