Merge pull request #6383 from Android-X13/option_for_qr_codes

Include option for non-URI addresses in QR codes
This commit is contained in:
Alejandro García 2022-11-29 14:42:05 +02:00 committed by GitHub
commit 8d2f0a5d12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 95 additions and 24 deletions

View File

@ -830,6 +830,11 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
requestPersistence();
}
public void setUseBitcoinUrisInQrCodes(boolean value) {
prefPayload.setUseBitcoinUrisInQrCodes(value);
requestPersistence();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getter
@ -1148,6 +1153,8 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
void setUseFullModeDaoMonitor(boolean value);
void setUseBitcoinUrisInQrCodes(boolean value);
void setClearDataAfterDays(int value);
void setBuyScreenCryptoCurrencyCode(String buyScreenCurrencyCode);

View File

@ -140,6 +140,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
private boolean denyApiTaker;
private boolean notifyOnPreRelease;
private boolean useFullModeDaoMonitor;
private boolean useBitcoinUrisInQrCodes = true;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@ -209,7 +210,8 @@ public final class PreferencesPayload implements PersistableEnvelope {
.setShowOffersMatchingMyAccounts(showOffersMatchingMyAccounts)
.setDenyApiTaker(denyApiTaker)
.setNotifyOnPreRelease(notifyOnPreRelease)
.setUseFullModeDaoMonitor(useFullModeDaoMonitor);
.setUseFullModeDaoMonitor(useFullModeDaoMonitor)
.setUseBitcoinUrisInQrCodes(useBitcoinUrisInQrCodes);
Optional.ofNullable(backupDirectory).ifPresent(builder::setBackupDirectory);
Optional.ofNullable(preferredTradeCurrency).ifPresent(e -> builder.setPreferredTradeCurrency((protobuf.TradeCurrency) e.toProtoMessage()));
@ -313,7 +315,8 @@ public final class PreferencesPayload implements PersistableEnvelope {
proto.getShowOffersMatchingMyAccounts(),
proto.getDenyApiTaker(),
proto.getNotifyOnPreRelease(),
proto.getUseFullModeDaoMonitor()
proto.getUseFullModeDaoMonitor(),
proto.getUseBitcoinUrisInQrCodes()
);
}
}

View File

@ -1327,6 +1327,11 @@ setting.preferences.txFeeTooLarge=Your input is above any reasonable value (>500
setting.preferences.ignorePeers=Ignored peers [onion address:port]
setting.preferences.ignoreDustThreshold=Min. non-dust output value
setting.preferences.clearDataAfterDays=Clear sensitive data after (days)
setting.preferences.useBitcoinUris=Use bitcoin URIs in QR codes
setting.preferences.useBitcoinUris.tooltip=Bisq's QR codes can either store bitcoin URIs containing the address along\n\
with some extra parameters (amount & label) or plain bitcoin addresses\n\
with no additional data. Disable this option if your external wallet's\n\
scanner cannot handle the bitcoin URI scheme format.
setting.preferences.currenciesInList=Currencies in market price feed list
setting.preferences.prefCurrency=Preferred currency
setting.preferences.displayFiat=Display national currencies

View File

@ -63,6 +63,7 @@ import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
@ -89,6 +90,7 @@ import java.io.ByteArrayInputStream;
import java.util.Comparator;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.jetbrains.annotations.NotNull;
@ -184,7 +186,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
() -> UserThread.runAfter(
() -> new QRCodeWindow(getBitcoinURI()).show(),
() -> new QRCodeWindow(getStringToEncode()).show(),
200, TimeUnit.MILLISECONDS)));
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setRowSpan(qrCodeImageView, 4);
@ -201,6 +203,12 @@ public class DepositView extends ActivatableView<VBox, Void> {
if (DevEnv.isDevMode())
amountTextField.setText("10");
Pattern pattern = Pattern.compile("^\\d+\\.?\\d*");
amountTextField.setTextFormatter(new TextFormatter<>(change -> {
String newText = change.getControlNewText();
return newText.isEmpty() || pattern.matcher(newText).matches() ? change : null;
}));
titledGroupBg.setVisible(false);
titledGroupBg.setManaged(false);
qrCodeImageView.setVisible(false);
@ -263,6 +271,15 @@ public class DepositView extends ActivatableView<VBox, Void> {
if (tableView.getSelectionModel().getSelectedItem() == null && !sortedList.isEmpty())
tableView.getSelectionModel().select(0);
if (!GUIUtil.getPreferences().isUseBitcoinUrisInQrCodes()) {
if (!amountTextField.getText().isEmpty()) {
amountTextField.clear();
}
amountTextField.setDisable(true);
} else {
amountTextField.setDisable(false);
}
}
@Override
@ -299,7 +316,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
private void updateQRCode() {
if (addressTextField.getAddress() != null && !addressTextField.getAddress().isEmpty()) {
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.from(getStringToEncode())
.withSize(150, 150) // code has 41 elements 8 px is border with 150 we get 3x scale and min. border
.to(ImageType.PNG)
.stream()
@ -331,6 +348,14 @@ public class DepositView extends ActivatableView<VBox, Void> {
paymentLabelString);
}
@NotNull
private String getStringToEncode() {
String address = addressTextField.getAddress() != null ?
addressTextField.getAddress() : "";
return GUIUtil.getPreferences().isUseBitcoinUrisInQrCodes() ?
getBitcoinURI() : address;
}
///////////////////////////////////////////////////////////////////////////////////////////
// ColumnCellFactories
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -847,7 +847,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
missingCoinListener = (observable, oldValue, newValue) -> {
if (!newValue.toString().equals("")) {
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.from(getStringToEncode())
.withSize(98, 98) // code has 41 elements 8 px is border with 98 we get double scale and min. border
.to(ImageType.PNG)
.stream()
@ -1231,7 +1231,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
() -> UserThread.runAfter(
() -> new QRCodeWindow(getBitcoinURI()).show(),
() -> new QRCodeWindow(getStringToEncode()).show(),
200, TimeUnit.MILLISECONDS)));
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 1);
@ -1340,6 +1340,14 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
model.getPaymentLabel());
}
@NotNull
private String getStringToEncode() {
String address = addressTextField.getAddress() != null ?
addressTextField.getAddress() : "";
return GUIUtil.getPreferences().isUseBitcoinUrisInQrCodes() ?
getBitcoinURI() : address;
}
private void addAmountPriceFields() {
// amountBox
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getEditableValueBox(Res.get("createOffer.amount.prompt"));

View File

@ -555,7 +555,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.from(getStringToEncode())
.withSize(98, 98) // code has 41 elements 8 px is border with 98 we get double scale and min. border
.to(ImageType.PNG)
.stream()
@ -973,7 +973,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
() -> UserThread.runAfter(
() -> new QRCodeWindow(getBitcoinURI()).show(),
() -> new QRCodeWindow(getStringToEncode()).show(),
200, TimeUnit.MILLISECONDS)));
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 1);
@ -1079,6 +1079,14 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
model.getPaymentLabel());
}
@NotNull
private String getStringToEncode() {
String address = addressTextField.getAddress() != null ?
addressTextField.getAddress() : "";
return GUIUtil.getPreferences().isUseBitcoinUrisInQrCodes() ?
getBitcoinURI() : address;
}
private void addAmountPriceFields() {
// amountBox
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getEditableValueBox(Res.get("takeOffer.amount.prompt"));

View File

@ -17,7 +17,6 @@
package bisq.desktop.main.overlays.windows;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.main.overlays.Overlay;
import bisq.core.locale.Res;
@ -25,14 +24,11 @@ import bisq.core.locale.Res;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import java.io.ByteArrayInputStream;
@ -42,12 +38,12 @@ import org.slf4j.LoggerFactory;
public class QRCodeWindow extends Overlay<QRCodeWindow> {
private static final Logger log = LoggerFactory.getLogger(QRCodeWindow.class);
private final ImageView qrCodeImageView;
private final String bitcoinURI;
private final String bitcoinAddressOrURI;
public QRCodeWindow(String bitcoinURI) {
this.bitcoinURI = bitcoinURI;
public QRCodeWindow(String bitcoinAddressOrURI) {
this.bitcoinAddressOrURI = bitcoinAddressOrURI;
final byte[] imageBytes = QRCode
.from(bitcoinURI)
.from(bitcoinAddressOrURI)
.withSize(250, 250)
.to(ImageType.PNG)
.stream()
@ -71,10 +67,11 @@ public class QRCodeWindow extends Overlay<QRCodeWindow> {
GridPane.setHalignment(qrCodeImageView, HPos.CENTER);
gridPane.getChildren().add(qrCodeImageView);
message = bitcoinURI.replace("%20", " ").replace("?", "\n?").replace("&", "\n&");
message = bitcoinAddressOrURI.replace("%20", " ").replace("?", "\n?").replace("&", "\n&");
setTruncatedMessage();
addMessage();
GridPane.setHalignment(messageLabel, HPos.CENTER);
addButtons();
applyStyles();
display();

View File

@ -80,6 +80,7 @@ import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
@ -97,6 +98,7 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.util.Callback;
import javafx.util.Duration;
import javafx.util.StringConverter;
import java.io.File;
@ -122,7 +124,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
private ToggleButton showOwnOffersInOfferBook, useAnimations, useDarkMode, sortMarketCurrenciesNumerically,
avoidStandbyMode, useCustomFee, autoConfirmXmrToggle, hideNonAccountPaymentMethodsToggle, denyApiTakerToggle,
notifyOnPreReleaseToggle, isDaoFullNodeToggleButton, fullModeDaoMonitorToggleButton;
notifyOnPreReleaseToggle, isDaoFullNodeToggleButton, fullModeDaoMonitorToggleButton, useBitcoinUrisToggle;
private int gridRow = 0;
private int displayCurrenciesGridRowIndex = 0;
private InputTextField transactionFeeInputTextField, ignoreTradersListInputTextField, ignoreDustThresholdInputTextField,
@ -263,7 +265,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
///////////////////////////////////////////////////////////////////////////////////////////
private void initializeGeneralOptions() {
int titledGroupBgRowSpan = displayStandbyModeFeature ? 10 : 9;
int titledGroupBgRowSpan = displayStandbyModeFeature ? 11 : 10;
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, titledGroupBgRowSpan, Res.get("setting.preferences.general"));
GridPane.setColumnSpan(titledGroupBg, 1);
@ -416,6 +418,13 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
avoidStandbyMode = addSlideToggleButton(root, ++gridRow,
Res.get("setting.preferences.avoidStandbyMode"));
}
useBitcoinUrisToggle = addSlideToggleButton(root, ++gridRow, Res.get("setting.preferences.useBitcoinUris"));
Tooltip tooltip = new Tooltip(Res.get("setting.preferences.useBitcoinUris.tooltip"));
tooltip.setShowDuration(Duration.millis(8000));
tooltip.setShowDelay(Duration.millis(300));
tooltip.setHideDelay(Duration.millis(0));
Tooltip.install(useBitcoinUrisToggle, tooltip);
}
private void initializeSeparator() {
@ -904,6 +913,10 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
}
});
useBitcoinUrisToggle.setSelected(preferences.isUseBitcoinUrisInQrCodes());
useBitcoinUrisToggle.setOnAction(e ->
preferences.setUseBitcoinUrisInQrCodes(useBitcoinUrisToggle.isSelected()));
btcExplorerTextField.setText(preferences.getBlockChainExplorer().name);
bsqExplorerTextField.setText(preferences.getBsqBlockChainExplorer().name);
@ -1172,6 +1185,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
userCountryComboBox.setOnAction(null);
editCustomBtcExplorer.setOnAction(null);
editCustomBsqExplorer.setOnAction(null);
useBitcoinUrisToggle.setOnAction(null);
deviationInputTextField.textProperty().removeListener(deviationListener);
deviationInputTextField.focusedProperty().removeListener(deviationFocusedListener);
transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);

View File

@ -147,6 +147,8 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
@ -173,16 +175,14 @@ public class GUIUtil {
public static TradeCurrency TOP_ALTCOIN = CurrencyUtil.getTradeCurrency("XMR").get();
private static FeeService feeService;
@Getter
@Setter
private static Preferences preferences;
public static void setFeeService(FeeService feeService) {
GUIUtil.feeService = feeService;
}
public static void setPreferences(Preferences preferences) {
GUIUtil.preferences = preferences;
}
public static String getUserLanguage() {
return preferences.getUserLanguage();
}
@ -788,6 +788,9 @@ public class GUIUtil {
}
public static String getBitcoinURI(String address, Coin amount, String label) {
if (amount.isZero()) {
amount = null;
}
return address != null ?
BitcoinURI.convertToBitcoinURI(Address.fromString(Config.baseCurrencyNetworkParameters(),
address), amount, label, null) :

View File

@ -1956,6 +1956,7 @@ message PreferencesPayload {
int32 clear_data_after_days = 63;
string buy_screen_crypto_currency_code = 64;
string sell_screen_crypto_currency_code = 65;
bool use_bitcoin_uris_in_qr_codes = 66;
}
message AutoConfirmSettings {