mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-03-15 10:26:37 -04:00
add qr code support and payment url to wallet app
This commit is contained in:
parent
4e2f977ff0
commit
e2bf6ec652
6
pom.xml
6
pom.xml
@ -240,6 +240,12 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.glxn</groupId>
|
||||
<artifactId>qrgen</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
@ -35,7 +35,7 @@ public class BitSquare extends Application
|
||||
|
||||
public static boolean fillFormsWithDummyData = true;
|
||||
|
||||
private static String APP_NAME = "bitsquare";
|
||||
private static String APP_NAME = "Bitsquare";
|
||||
private static Stage primaryStage;
|
||||
private WalletFacade walletFacade;
|
||||
private MessageFacade messageFacade;
|
||||
|
@ -32,6 +32,7 @@
|
||||
-fx-fill: red;
|
||||
}
|
||||
|
||||
|
||||
/* main nav */
|
||||
#nav-button {
|
||||
-fx-cursor: hand;
|
||||
@ -78,14 +79,19 @@
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
#qr-code-icon {
|
||||
-fx-fill: #0096c9;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
#copy-icon {
|
||||
-fx-fill: black;
|
||||
-fx-cursor: hand;
|
||||
-fx-fill: #0096c9;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
#copy-icon .hover{
|
||||
-fx-fill: #0096c9;
|
||||
-fx-cursor: hand;
|
||||
-fx-fill: #0096c9;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
@ -97,6 +103,22 @@
|
||||
-fx-fill: black;
|
||||
}
|
||||
|
||||
/* Same stlye like non editable textfield. But textfield spans a whole column in a grid, so we use generally textfield */
|
||||
#label-with-background {
|
||||
-fx-background-color: #FAFAFA;
|
||||
-fx-border-radius: 4;
|
||||
-fx-padding: 4 4 4 4;
|
||||
}
|
||||
|
||||
#address-label {
|
||||
-fx-cursor: hand;
|
||||
-fx-text-fill: #0096c9;
|
||||
-fx-underline: true;
|
||||
-fx-background-color: #FAFAFA;
|
||||
-fx-border-radius: 4;
|
||||
-fx-padding: 4 4 4 4;
|
||||
}
|
||||
|
||||
#funds-confidence {
|
||||
-fx-progress-color: dimgrey;
|
||||
}
|
||||
|
@ -1,18 +1,36 @@
|
||||
package io.bitsquare.gui.components.btc;
|
||||
|
||||
import com.google.bitcoin.uri.BitcoinURI;
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.BitSquare;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import java.awt.Desktop;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Window;
|
||||
import net.glxn.qrgen.QRCode;
|
||||
import net.glxn.qrgen.image.ImageType;
|
||||
import org.controlsfx.control.PopOver;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AddressTextField extends AnchorPane
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(AddressTextField.class);
|
||||
|
||||
private final Label copyIcon;
|
||||
private final TextField addressTextField;
|
||||
private final Label addressLabel;
|
||||
private final Label qrCode;
|
||||
private String address;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -21,12 +39,15 @@ public class AddressTextField extends AnchorPane
|
||||
|
||||
public AddressTextField()
|
||||
{
|
||||
addressTextField = new TextField();
|
||||
addressTextField.setFocusTraversable(false);
|
||||
addressTextField.setEditable(false);
|
||||
addressLabel = new Label();
|
||||
addressLabel.setFocusTraversable(false);
|
||||
addressLabel.setId("address-label");
|
||||
|
||||
copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.setId("copy-icon");
|
||||
Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
copyIcon.setOnMouseClicked(e -> {
|
||||
if (address != null && address.length() > 0)
|
||||
{
|
||||
@ -37,30 +58,72 @@ public class AddressTextField extends AnchorPane
|
||||
}
|
||||
});
|
||||
|
||||
Tooltip copyIconTooltip = new Tooltip("Copy address to clipboard");
|
||||
Tooltip.install(copyIcon, copyIconTooltip);
|
||||
|
||||
qrCode = new Label();
|
||||
qrCode.setId("qr-code-icon");
|
||||
qrCode.setLayoutY(3);
|
||||
AwesomeDude.setIcon(qrCode, AwesomeIcon.QRCODE);
|
||||
Tooltip.install(qrCode, new Tooltip("Show QR code for this address"));
|
||||
qrCode.setOnMouseClicked(e -> {
|
||||
if (address != null && address.length() > 0)
|
||||
{
|
||||
final byte[] imageBytes = QRCode
|
||||
.from(getBitcoinURI())
|
||||
.withSize(300, 220)
|
||||
.to(ImageType.PNG)
|
||||
.stream()
|
||||
.toByteArray();
|
||||
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
|
||||
ImageView view = new ImageView(qrImage);
|
||||
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
copyIcon.setId("copy-icon");
|
||||
Pane pane = new Pane(view);
|
||||
pane.setPrefSize(320, 240);
|
||||
view.relocate(10, 10);
|
||||
|
||||
AnchorPane.setRightAnchor(copyIcon, 5.0);
|
||||
AnchorPane.setRightAnchor(addressTextField, 35.0);
|
||||
AnchorPane.setLeftAnchor(addressTextField, 0.0);
|
||||
PopOver popOver = new PopOver(pane);
|
||||
popOver.setDetachedTitle("Scan QR code for this address");
|
||||
popOver.setDetached(true);
|
||||
|
||||
getChildren().addAll(addressTextField, copyIcon);
|
||||
Window window = getScene().getWindow();
|
||||
double x = Math.round(window.getX() + (window.getWidth() - 320) / 2);
|
||||
double y = Math.round(window.getY() + (window.getHeight() - 240) / 2);
|
||||
popOver.show(getScene().getWindow(), x, y);
|
||||
}
|
||||
});
|
||||
|
||||
AnchorPane.setRightAnchor(qrCode, 5.0);
|
||||
AnchorPane.setRightAnchor(copyIcon, 30.0);
|
||||
AnchorPane.setRightAnchor(addressLabel, 55.0);
|
||||
AnchorPane.setLeftAnchor(addressLabel, 0.0);
|
||||
|
||||
getChildren().addAll(addressLabel, copyIcon, qrCode);
|
||||
|
||||
addressLabel.setOnMouseClicked(mouseEvent -> {
|
||||
try
|
||||
{
|
||||
if (address != null)
|
||||
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
|
||||
} catch (IOException e)
|
||||
{
|
||||
log.warn(e.getMessage());
|
||||
Popups.openWarningPopup("Opening wallet app failed", "Perhaps you don't have one installed?");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getBitcoinURI()
|
||||
{
|
||||
return BitcoinURI.convertToBitcoinURI(address, null, BitSquare.getAppName(), null);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public void setAddress(String address)
|
||||
{
|
||||
this.address = address;
|
||||
addressTextField.setText(address);
|
||||
addressLabel.setText(address);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class BalanceTextField extends AnchorPane
|
||||
Tooltip.install(progressIndicator, progressIndicatorTooltip);
|
||||
|
||||
AnchorPane.setRightAnchor(progressIndicator, 0.0);
|
||||
AnchorPane.setRightAnchor(balanceTextField, 35.0);
|
||||
AnchorPane.setRightAnchor(balanceTextField, 55.0);
|
||||
AnchorPane.setLeftAnchor(balanceTextField, 0.0);
|
||||
|
||||
getChildren().addAll(balanceTextField, progressIndicator);
|
||||
|
@ -105,7 +105,7 @@ public class CreateOfferController extends CachedViewController
|
||||
|
||||
setupBindings();
|
||||
setupValidation();
|
||||
|
||||
|
||||
//TODO just for dev testing
|
||||
if (BitSquare.fillFormsWithDummyData)
|
||||
{
|
||||
@ -171,7 +171,7 @@ public class CreateOfferController extends CachedViewController
|
||||
if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() && amountTextField.getIsValid())
|
||||
{
|
||||
viewModel.isPlaceOfferButtonDisabled.set(true);
|
||||
|
||||
|
||||
tradeManager.requestPlaceOffer(offerId,
|
||||
direction,
|
||||
BitSquareFormatter.parseToDouble(viewModel.price.get()),
|
||||
|
Loading…
x
Reference in New Issue
Block a user