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 0000000000..f0e7284109 --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/components/ExplorerAddressTextField.java @@ -0,0 +1,137 @@ +/* + * 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 { + private static Preferences preferences; + + public static void setPreferences(Preferences preferences) { + ExplorerAddressTextField.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("txIdTextField.copyIcon.tooltip"))); + AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY); + AnchorPane.setRightAnchor(copyIcon, 30.0); + + Tooltip tooltip = new Tooltip(Res.get("txIdTextField.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("txIdTextField.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 addressId) { + if (addressId == 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(addressId); + textField.setOnMouseClicked(mouseEvent -> openBlockExplorer(addressId)); + blockExplorerIcon.setOnMouseClicked(mouseEvent -> openBlockExplorer(addressId)); + copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(addressId)); + } + + public void cleanup() { + textField.setOnMouseClicked(null); + blockExplorerIcon.setOnMouseClicked(null); + copyIcon.setOnMouseClicked(null); + textField.setText(""); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void openBlockExplorer(String addressId) { + if (preferences != null) { + BlockChainExplorer blockChainExplorer = isBsq ? + preferences.getBsqBlockChainExplorer() : + preferences.getBlockChainExplorer(); + GUIUtil.openWebPage(blockChainExplorer.addressUrl + addressId, false); + } + } +} diff --git a/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java b/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java index 4141750307..84cea87e54 100644 --- a/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java +++ b/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java @@ -66,8 +66,6 @@ public class TxIdTextField extends AnchorPane { private TxConfidenceListener txConfidenceListener; @Setter private boolean isBsq; - @Setter - private boolean isAddress = false; /////////////////////////////////////////////////////////////////////////////////////////// @@ -175,8 +173,7 @@ public class TxIdTextField extends AnchorPane { BlockChainExplorer blockChainExplorer = isBsq ? preferences.getBsqBlockChainExplorer() : preferences.getBlockChainExplorer(); - String url = this.isAddress ? blockChainExplorer.addressUrl : blockChainExplorer.txUrl; - GUIUtil.openWebPage(url + txId, false); + GUIUtil.openWebPage(blockChainExplorer.txUrl + txId, false); } } diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index abba0a66b9..4a50a3bcc1 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 @@ package bisq.desktop.main; 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 class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener { 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 90ba24dbe0..0a61814417 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 @@ -18,6 +18,7 @@ package bisq.desktop.main.overlays.windows; import bisq.desktop.components.BisqTextArea; +import bisq.desktop.components.ExplorerAddressTextField; import bisq.desktop.components.TxIdTextField; import bisq.desktop.main.MainView; import bisq.desktop.main.overlays.Overlay; @@ -258,9 +259,8 @@ public class ContractWindow extends Overlay { addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxId"), dispute.getDelayedPayoutTxId()); if (dispute.getDonationAddressOfDelayedPayoutTx() != null) { - Tuple2 field = addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxReceiverAddress"), + addLabelExplorerAddressTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxReceiverAddress"), dispute.getDonationAddressOfDelayedPayoutTx()); - field.second.setAddress(true); } if (dispute.getPayoutTxSerialized() != null) 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 02c6aac52a..795203175d 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 class MarketPricePresentation { 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 51faf17f93..472ee4d862 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.BisqTextArea; 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 class FormBuilder { 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