improve device detection and display

This commit is contained in:
Craig Raw 2020-08-31 15:55:36 +02:00
parent 10edf31e13
commit 68239e9472
7 changed files with 43 additions and 31 deletions

View file

@ -13,8 +13,8 @@ public class DeviceAddressDialog extends DeviceDialog<String> {
private final Wallet wallet; private final Wallet wallet;
private final KeyDerivation keyDerivation; private final KeyDerivation keyDerivation;
public DeviceAddressDialog(List<Device> devices, Wallet wallet, KeyDerivation keyDerivation) { public DeviceAddressDialog(List<String> operationFingerprints, Wallet wallet, KeyDerivation keyDerivation) {
super(devices); super(operationFingerprints);
this.wallet = wallet; this.wallet = wallet;
this.keyDerivation = keyDerivation; this.keyDerivation = keyDerivation;

View file

@ -15,10 +15,12 @@ import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import org.controlsfx.glyphfont.Glyph; import org.controlsfx.glyphfont.Glyph;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
public abstract class DeviceDialog<R> extends Dialog<R> { public abstract class DeviceDialog<R> extends Dialog<R> {
private final List<Device> operationDevices; private final List<String> operationFingerprints;
private final Accordion deviceAccordion; private final Accordion deviceAccordion;
private final VBox scanBox; private final VBox scanBox;
private final Label scanLabel; private final Label scanLabel;
@ -27,8 +29,8 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
this(null); this(null);
} }
public DeviceDialog(List<Device> operationDevices) { public DeviceDialog(List<String> operationFingerprints) {
this.operationDevices = operationDevices; this.operationFingerprints = operationFingerprints;
final DialogPane dialogPane = getDialogPane(); final DialogPane dialogPane = getDialogPane();
dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm()); dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm());
@ -104,16 +106,20 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
} }
protected void setDevices(List<Device> devices) { protected void setDevices(List<Device> devices) {
List<Device> dialogDevices = devices; List<Device> dialogDevices = new ArrayList<>(devices);
if(operationDevices != null && dialogDevices.containsAll(operationDevices)) { dialogDevices.removeIf(Objects::isNull);
dialogDevices = operationDevices;
if(operationFingerprints != null) {
dialogDevices.removeIf(device -> {
return device.getFingerprint() != null && !operationFingerprints.contains(device.getFingerprint()) && !(device.getNeedsPinSent() || device.getNeedsPassphraseSent());
});
} }
deviceAccordion.getPanes().clear(); deviceAccordion.getPanes().clear();
if(dialogDevices.isEmpty()) { if(dialogDevices.isEmpty()) {
scanBox.setVisible(true); scanBox.setVisible(true);
scanLabel.setText("No devices found"); scanLabel.setText("No matching devices found");
} else { } else {
scanBox.setVisible(false); scanBox.setVisible(false);
for(Device device : dialogDevices) { for(Device device : dialogDevices) {

View file

@ -15,6 +15,7 @@ import com.sparrowwallet.sparrow.io.Device;
import com.sparrowwallet.sparrow.io.Hwi; import com.sparrowwallet.sparrow.io.Hwi;
import com.sparrowwallet.drongo.wallet.WalletModel; import com.sparrowwallet.drongo.wallet.WalletModel;
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5; import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -273,6 +274,8 @@ public class DevicePane extends TitledDescriptionPane {
contentBox.getChildren().add(sendPassphraseButton); contentBox.getChildren().add(sendPassphraseButton);
contentBox.setPadding(new Insets(10, 30, 10, 30)); contentBox.setPadding(new Insets(10, 30, 10, 30));
Platform.runLater(passphraseField::requestFocus);
return contentBox; return contentBox;
} }
@ -342,8 +345,7 @@ public class DevicePane extends TitledDescriptionPane {
if(device.getFingerprint() != null) { if(device.getFingerprint() != null) {
setPassphraseButton.setVisible(false); setPassphraseButton.setVisible(false);
device.setNeedsPassphraseSent(false); setDescription("Passphrase sent");
setDefaultStatus();
showOperationButton(); showOperationButton();
} else { } else {
setError("Passphrase send failed", null); setError("Passphrase send failed", null);

View file

@ -11,8 +11,8 @@ import java.util.List;
public class DeviceSignDialog extends DeviceDialog<PSBT> { public class DeviceSignDialog extends DeviceDialog<PSBT> {
private final PSBT psbt; private final PSBT psbt;
public DeviceSignDialog(List<Device> devices, PSBT psbt) { public DeviceSignDialog(List<String> operationFingerprints, PSBT psbt) {
super(devices); super(operationFingerprints);
this.psbt = psbt; this.psbt = psbt;
EventManager.get().register(this); EventManager.get().register(this);
setOnCloseRequest(event -> { setOnCloseRequest(event -> {

View file

@ -689,9 +689,7 @@ public class HeadersController extends TransactionFormController implements Init
return; return;
} }
signingDevices.addAll(AppController.getDevices().stream().filter(device -> device.getNeedsPinSent() || device.getNeedsPassphraseSent()).collect(Collectors.toList())); DeviceSignDialog dlg = new DeviceSignDialog(fingerprints, headersForm.getPsbt());
DeviceSignDialog dlg = new DeviceSignDialog(signingDevices.isEmpty() ? null : signingDevices, headersForm.getPsbt());
dlg.initModality(Modality.NONE); dlg.initModality(Modality.NONE);
Stage stage = (Stage)dlg.getDialogPane().getScene().getWindow(); Stage stage = (Stage)dlg.getDialogPane().getScene().getWindow();
stage.setAlwaysOnTop(true); stage.setAlwaysOnTop(true);

View file

@ -7,6 +7,7 @@ import com.sparrowwallet.drongo.protocol.NonStandardScriptException;
import com.sparrowwallet.drongo.protocol.TransactionInput; import com.sparrowwallet.drongo.protocol.TransactionInput;
import com.sparrowwallet.drongo.protocol.TransactionOutput; import com.sparrowwallet.drongo.protocol.TransactionOutput;
import com.sparrowwallet.drongo.wallet.BlockTransaction; import com.sparrowwallet.drongo.wallet.BlockTransaction;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.control.AddressLabel; import com.sparrowwallet.sparrow.control.AddressLabel;
import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CoinLabel;
@ -87,19 +88,9 @@ public class OutputController extends TransactionFormController implements Initi
walletType.managedProperty().bind(walletType.visibleProperty()); walletType.managedProperty().bind(walletType.visibleProperty());
walletType.setVisible(false); walletType.setVisible(false);
outputForm.signingWalletProperty().addListener((observable, oldValue, signingWallet) -> { outputForm.signingWalletProperty().addListener((observable, oldValue, signingWallet) -> {
if(signingWallet != null) { updateWalletType(txOutput, signingWallet);
walletType.setVisible(true);
if(signingWallet.getWalletOutputScripts(KeyPurpose.RECEIVE).containsKey(txOutput.getScript())) {
walletType.setText("(Consolidation)");
} else if(signingWallet.getWalletOutputScripts(KeyPurpose.CHANGE).containsKey(txOutput.getScript())) {
walletType.setText("(Change)");
} else {
walletType.setText("(Payment)");
}
} else {
walletType.setVisible(false);
}
}); });
updateWalletType(txOutput, outputForm.getSigningWallet());
spentField.managedProperty().bind(spentField.visibleProperty()); spentField.managedProperty().bind(spentField.visibleProperty());
spentByField.managedProperty().bind(spentByField.visibleProperty()); spentByField.managedProperty().bind(spentByField.visibleProperty());
@ -118,6 +109,21 @@ public class OutputController extends TransactionFormController implements Initi
scriptPubKeyArea.appendScript(txOutput.getScript(), null, null); scriptPubKeyArea.appendScript(txOutput.getScript(), null, null);
} }
private void updateWalletType(TransactionOutput txOutput, Wallet signingWallet) {
if(signingWallet != null) {
walletType.setVisible(true);
if(signingWallet.getWalletOutputScripts(KeyPurpose.RECEIVE).containsKey(txOutput.getScript())) {
walletType.setText("(Consolidation)");
} else if(signingWallet.getWalletOutputScripts(KeyPurpose.CHANGE).containsKey(txOutput.getScript())) {
walletType.setText("(Change)");
} else {
walletType.setText("(Payment)");
}
} else {
walletType.setVisible(false);
}
}
private void updateSpent(List<BlockTransaction> outputTransactions) { private void updateSpent(List<BlockTransaction> outputTransactions) {
int outputIndex = outputForm.getIndex(); int outputIndex = outputForm.getIndex();
if(outputIndex < outputForm.getMaxOutputFetched()) { if(outputIndex < outputForm.getMaxOutputFetched()) {

View file

@ -211,21 +211,21 @@ public class ReceiveController extends WalletFormController implements Initializ
List<Device> possibleDevices = (List<Device>)displayAddress.getUserData(); List<Device> possibleDevices = (List<Device>)displayAddress.getUserData();
if(possibleDevices != null && !possibleDevices.isEmpty()) { if(possibleDevices != null && !possibleDevices.isEmpty()) {
if(possibleDevices.size() > 1 || possibleDevices.get(0).getNeedsPinSent() || possibleDevices.get(0).getNeedsPassphraseSent()) { if(possibleDevices.size() > 1 || possibleDevices.get(0).getNeedsPinSent() || possibleDevices.get(0).getNeedsPassphraseSent()) {
DeviceAddressDialog dlg = new DeviceAddressDialog(possibleDevices.size() == 1 ? List.of(possibleDevices.get(0)) : null, wallet, fullDerivation); DeviceAddressDialog dlg = new DeviceAddressDialog(List.of(keystore.getKeyDerivation().getMasterFingerprint()), wallet, fullDerivation);
dlg.showAndWait(); dlg.showAndWait();
} else { } else {
Device actualDevice = possibleDevices.get(0); Device actualDevice = possibleDevices.get(0);
Hwi.DisplayAddressService displayAddressService = new Hwi.DisplayAddressService(actualDevice, "", wallet.getScriptType(), fullDerivation.getDerivationPath()); Hwi.DisplayAddressService displayAddressService = new Hwi.DisplayAddressService(actualDevice, "", wallet.getScriptType(), fullDerivation.getDerivationPath());
displayAddressService.setOnFailed(failedEvent -> { displayAddressService.setOnFailed(failedEvent -> {
Platform.runLater(() -> { Platform.runLater(() -> {
DeviceAddressDialog dlg = new DeviceAddressDialog(null, wallet, fullDerivation); DeviceAddressDialog dlg = new DeviceAddressDialog(List.of(keystore.getKeyDerivation().getMasterFingerprint()), wallet, fullDerivation);
dlg.showAndWait(); dlg.showAndWait();
}); });
}); });
displayAddressService.start(); displayAddressService.start();
} }
} else { } else {
DeviceAddressDialog dlg = new DeviceAddressDialog(null, wallet, fullDerivation); DeviceAddressDialog dlg = new DeviceAddressDialog(List.of(keystore.getKeyDerivation().getMasterFingerprint()), wallet, fullDerivation);
dlg.showAndWait(); dlg.showAndWait();
} }
} }