diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index bdf67008e7b..d68529e3636 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -3095,6 +3095,10 @@ addressTextField.copyToClipboard=Copy address to clipboard addressTextField.addressCopiedToClipboard=Address has been copied to clipboard addressTextField.openWallet.failed=Opening a default Bitcoin wallet application has failed. Perhaps you don't have one installed? +explorerAddressTextField.copyToClipboard=Copy address to clipboard +explorerAddressTextField.blockExplorerIcon.tooltip=Open a blockchain explorer with this address +explorerAddressTextField.missingTx.warning.tooltip=Missing required address + peerInfoIcon.tooltip={0}\nTag: {1} txIdTextField.copyIcon.tooltip=Copy transaction ID to clipboard diff --git a/desktop/src/main/java/bisq/desktop/components/ExplorerAddressTextField.java b/desktop/src/main/java/bisq/desktop/components/ExplorerAddressTextField.java new file mode 100644 index 00000000000..1f2efb58bb1 --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/components/ExplorerAddressTextField.java @@ -0,0 +1,134 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.components; + +import bisq.desktop.util.GUIUtil; + +import bisq.core.locale.Res; +import bisq.core.user.BlockChainExplorer; +import bisq.core.user.Preferences; + +import bisq.common.util.Utilities; + +import de.jensd.fx.fontawesome.AwesomeDude; +import de.jensd.fx.fontawesome.AwesomeIcon; + +import com.jfoenix.controls.JFXTextField; + +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.AnchorPane; + +import lombok.Getter; +import lombok.Setter; + +import javax.annotation.Nullable; + +public class ExplorerAddressTextField extends AnchorPane { + @Setter + private static Preferences preferences; + + @Getter + private final TextField textField; + private final Label copyIcon, blockExplorerIcon, missingAddressWarningIcon; + @Setter + private boolean isBsq; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + public ExplorerAddressTextField() { + copyIcon = new Label(); + copyIcon.setLayoutY(3); + copyIcon.getStyleClass().addAll("icon", "highlight"); + copyIcon.setTooltip(new Tooltip(Res.get("explorerAddressTextField.copyToClipboard"))); + AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY); + AnchorPane.setRightAnchor(copyIcon, 30.0); + + Tooltip tooltip = new Tooltip(Res.get("explorerAddressTextField.blockExplorerIcon.tooltip")); + + blockExplorerIcon = new Label(); + blockExplorerIcon.getStyleClass().addAll("icon", "highlight"); + blockExplorerIcon.setTooltip(tooltip); + AwesomeDude.setIcon(blockExplorerIcon, AwesomeIcon.EXTERNAL_LINK); + blockExplorerIcon.setMinWidth(20); + AnchorPane.setRightAnchor(blockExplorerIcon, 52.0); + AnchorPane.setTopAnchor(blockExplorerIcon, 4.0); + + missingAddressWarningIcon = new Label(); + missingAddressWarningIcon.getStyleClass().addAll("icon", "error-icon"); + AwesomeDude.setIcon(missingAddressWarningIcon, AwesomeIcon.WARNING_SIGN); + missingAddressWarningIcon.setTooltip(new Tooltip(Res.get("explorerAddressTextField.missingTx.warning.tooltip"))); + missingAddressWarningIcon.setMinWidth(20); + AnchorPane.setRightAnchor(missingAddressWarningIcon, 52.0); + AnchorPane.setTopAnchor(missingAddressWarningIcon, 4.0); + missingAddressWarningIcon.setVisible(false); + missingAddressWarningIcon.setManaged(false); + + textField = new JFXTextField(); + textField.setId("address-text-field"); + textField.setEditable(false); + textField.setTooltip(tooltip); + AnchorPane.setRightAnchor(textField, 80.0); + AnchorPane.setLeftAnchor(textField, 0.0); + textField.focusTraversableProperty().set(focusTraversableProperty().get()); + getChildren().addAll(textField, missingAddressWarningIcon, blockExplorerIcon, copyIcon); + } + + public void setup(@Nullable String address) { + if (address == null) { + textField.setText(Res.get("shared.na")); + textField.setId("address-text-field-error"); + blockExplorerIcon.setVisible(false); + blockExplorerIcon.setManaged(false); + copyIcon.setVisible(false); + copyIcon.setManaged(false); + missingAddressWarningIcon.setVisible(true); + missingAddressWarningIcon.setManaged(true); + return; + } + + textField.setText(address); + textField.setOnMouseClicked(mouseEvent -> openBlockExplorer(address)); + blockExplorerIcon.setOnMouseClicked(mouseEvent -> openBlockExplorer(address)); + copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(address)); + } + + public void cleanup() { + textField.setOnMouseClicked(null); + blockExplorerIcon.setOnMouseClicked(null); + copyIcon.setOnMouseClicked(null); + textField.setText(""); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void openBlockExplorer(String address) { + if (preferences != null) { + BlockChainExplorer blockChainExplorer = isBsq ? + preferences.getBsqBlockChainExplorer() : + preferences.getBlockChainExplorer(); + GUIUtil.openWebPage(blockChainExplorer.addressUrl + address, false); + } + } +} diff --git a/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java b/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java index 84cea87e541..084fd5fba45 100644 --- a/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java +++ b/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java @@ -46,18 +46,11 @@ import javax.annotation.Nullable; public class TxIdTextField extends AnchorPane { + @Setter private static Preferences preferences; - - public static void setPreferences(Preferences preferences) { - TxIdTextField.preferences = preferences; - } - + @Setter private static BtcWalletService walletService; - public static void setWalletService(BtcWalletService walletService) { - TxIdTextField.walletService = walletService; - } - @Getter private final TextField textField; private final Tooltip progressIndicatorTooltip; diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index abba0a66b96..4a50a3bcc1f 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -19,6 +19,7 @@ import bisq.desktop.app.BisqApp; import bisq.desktop.common.model.ViewModel; +import bisq.desktop.components.ExplorerAddressTextField; import bisq.desktop.components.TxIdTextField; import bisq.desktop.main.overlays.Overlay; import bisq.desktop.main.overlays.notifications.NotificationCenter; @@ -205,6 +206,7 @@ public MainViewModel(BisqSetup bisqSetup, this.corruptedStorageFileHandler = corruptedStorageFileHandler; TxIdTextField.setPreferences(preferences); + ExplorerAddressTextField.setPreferences(preferences); TxIdTextField.setWalletService(btcWalletService); diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java index 4f025afec0b..49bc879aa4c 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java @@ -256,7 +256,7 @@ private void addContent() { addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxId"), dispute.getDelayedPayoutTxId()); if (dispute.getDonationAddressOfDelayedPayoutTx() != null) { - addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxReceiverAddress"), + addLabelExplorerAddressTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxReceiverAddress"), dispute.getDonationAddressOfDelayedPayoutTx()); } diff --git a/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java b/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java index 02c6aac52a0..795203175d6 100644 --- a/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java +++ b/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java @@ -17,6 +17,7 @@ package bisq.desktop.main.presentation; +import bisq.desktop.components.ExplorerAddressTextField; import bisq.desktop.components.TxIdTextField; import bisq.desktop.main.shared.PriceFeedComboBoxItem; import bisq.desktop.util.GUIUtil; @@ -94,6 +95,7 @@ public MarketPricePresentation(BtcWalletService btcWalletService, this.preferences = preferences; TxIdTextField.setPreferences(preferences); + ExplorerAddressTextField.setPreferences(preferences); // TODO TxIdTextField.setWalletService(btcWalletService); diff --git a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java index 51faf17f93d..472ee4d8620 100644 --- a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java +++ b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java @@ -29,6 +29,7 @@ import bisq.desktop.components.BisqTextField; import bisq.desktop.components.BsqAddressTextField; import bisq.desktop.components.BusyAnimation; +import bisq.desktop.components.ExplorerAddressTextField; import bisq.desktop.components.ExternalHyperlink; import bisq.desktop.components.FundsTextField; import bisq.desktop.components.HyperlinkWithIcon; @@ -699,6 +700,24 @@ public static Tuple2 addLabelTxIdTextField(GridPane gridPa return new Tuple2<>(label, txTextField); } + /////////////////////////////////////////////////////////////////////////////////////////// + // Label + ExplorerAddressTextField + /////////////////////////////////////////////////////////////////////////////////////////// + public static void addLabelExplorerAddressTextField(GridPane gridPane, + int rowIndex, + String title, + String address) { + Label label = addLabel(gridPane, rowIndex, title, 0); + label.getStyleClass().add("confirmation-label"); + GridPane.setHalignment(label, HPos.LEFT); + + ExplorerAddressTextField addressTextField = new ExplorerAddressTextField(); + addressTextField.setup(address); + GridPane.setRowIndex(addressTextField, rowIndex); + GridPane.setColumnIndex(addressTextField, 1); + gridPane.getChildren().add(addressTextField); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Label + InputTextField