highlight default button and allow actioning from keyboard when only one usb device is listed

This commit is contained in:
Craig Raw
2021-06-14 16:55:01 +02:00
parent f1510de360
commit e6c536930b
11 changed files with 54 additions and 26 deletions
@@ -25,8 +25,8 @@ public class DeviceAddressDialog extends DeviceDialog<String> {
}
@Override
protected DevicePane getDevicePane(Device device) {
return new DevicePane(wallet, outputDescriptor, device);
protected DevicePane getDevicePane(Device device, boolean defaultDevice) {
return new DevicePane(wallet, outputDescriptor, device, defaultDevice);
}
@Subscribe
@@ -22,6 +22,7 @@ import java.util.Objects;
public abstract class DeviceDialog<R> extends Dialog<R> {
private final List<String> operationFingerprints;
private final Accordion deviceAccordion;
private final Button scanButton;
private final VBox scanBox;
private final Label scanLabel;
@@ -57,18 +58,19 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
Glyph usb = new Glyph(FontAwesome5Brands.FONT_NAME, FontAwesome5Brands.Glyph.USB);
usb.setFontSize(50);
scanLabel = new Label("Connect Hardware Wallet");
Button button = new Button("Scan...");
button.setPrefSize(120, 60);
button.setOnAction(event -> {
scanButton = new Button("Scan...");
scanButton.setPrefSize(120, 60);
scanButton.setOnAction(event -> {
scan();
});
scanBox.getChildren().addAll(usb, scanLabel, button);
scanBox.getChildren().addAll(usb, scanLabel, scanButton);
scanBox.managedProperty().bind(scanBox.visibleProperty());
stackPane.getChildren().addAll(anchorPane, scanBox);
List<Device> devices = AppServices.getDevices();
if(devices == null || devices.isEmpty()) {
scanButton.setDefaultButton(true);
scanBox.setVisible(true);
} else {
Platform.runLater(() -> setDevices(devices));
@@ -97,15 +99,21 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
private void scan() {
Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(null);
enumerateService.setOnSucceeded(workerStateEvent -> {
scanButton.setText("Scan...");
List<Device> devices = enumerateService.getValue();
setDevices(devices);
Platform.runLater(() -> EventManager.get().post(new UsbDeviceEvent(devices)));
});
enumerateService.setOnFailed(workerStateEvent -> {
scanButton.setText("Scan...");
deviceAccordion.getPanes().clear();
scanButton.setDefaultButton(true);
scanBox.setVisible(true);
scanLabel.setText(workerStateEvent.getSource().getException().getMessage());
});
enumerateService.setOnRunning(workerStateEvent -> {
scanButton.setText("Scanning...");
});
enumerateService.start();
}
@@ -122,16 +130,17 @@ public abstract class DeviceDialog<R> extends Dialog<R> {
deviceAccordion.getPanes().clear();
if(dialogDevices.isEmpty()) {
scanButton.setDefaultButton(true);
scanBox.setVisible(true);
scanLabel.setText("No matching devices found");
} else {
scanBox.setVisible(false);
for(Device device : dialogDevices) {
DevicePane devicePane = getDevicePane(device);
DevicePane devicePane = getDevicePane(device, dialogDevices.size() == 1);
deviceAccordion.getPanes().add(devicePane);
}
}
}
protected abstract DevicePane getDevicePane(Device device);
protected abstract DevicePane getDevicePane(Device device, boolean defaultDevice);
}
@@ -59,7 +59,9 @@ public class DevicePane extends TitledDescriptionPane {
private final SimpleStringProperty passphrase = new SimpleStringProperty("");
public DevicePane(Wallet wallet, Device device) {
private boolean defaultDevice;
public DevicePane(Wallet wallet, Device device, boolean defaultDevice) {
super(device.getModel().toDisplayString(), "", "", "image/" + device.getType() + ".png");
this.deviceOperation = DeviceOperation.IMPORT;
this.wallet = wallet;
@@ -68,6 +70,7 @@ public class DevicePane extends TitledDescriptionPane {
this.keyDerivation = null;
this.message = null;
this.device = device;
this.defaultDevice = defaultDevice;
setDefaultStatus();
showHideLink.setVisible(false);
@@ -80,7 +83,7 @@ public class DevicePane extends TitledDescriptionPane {
buttonBox.getChildren().addAll(setPassphraseButton, importButton);
}
public DevicePane(PSBT psbt, Device device) {
public DevicePane(PSBT psbt, Device device, boolean defaultDevice) {
super(device.getModel().toDisplayString(), "", "", "image/" + device.getType() + ".png");
this.deviceOperation = DeviceOperation.SIGN;
this.wallet = null;
@@ -89,6 +92,7 @@ public class DevicePane extends TitledDescriptionPane {
this.keyDerivation = null;
this.message = null;
this.device = device;
this.defaultDevice = defaultDevice;
setDefaultStatus();
showHideLink.setVisible(false);
@@ -101,7 +105,7 @@ public class DevicePane extends TitledDescriptionPane {
buttonBox.getChildren().addAll(setPassphraseButton, signButton);
}
public DevicePane(Wallet wallet, OutputDescriptor outputDescriptor, Device device) {
public DevicePane(Wallet wallet, OutputDescriptor outputDescriptor, Device device, boolean defaultDevice) {
super(device.getModel().toDisplayString(), "", "", "image/" + device.getType() + ".png");
this.deviceOperation = DeviceOperation.DISPLAY_ADDRESS;
this.wallet = wallet;
@@ -110,6 +114,7 @@ public class DevicePane extends TitledDescriptionPane {
this.keyDerivation = null;
this.message = null;
this.device = device;
this.defaultDevice = defaultDevice;
setDefaultStatus();
showHideLink.setVisible(false);
@@ -122,7 +127,7 @@ public class DevicePane extends TitledDescriptionPane {
buttonBox.getChildren().addAll(setPassphraseButton, displayAddressButton);
}
public DevicePane(Wallet wallet, String message, KeyDerivation keyDerivation, Device device) {
public DevicePane(Wallet wallet, String message, KeyDerivation keyDerivation, Device device, boolean defaultDevice) {
super(device.getModel().toDisplayString(), "", "", "image/" + device.getType() + ".png");
this.deviceOperation = DeviceOperation.SIGN_MESSAGE;
this.wallet = wallet;
@@ -131,6 +136,7 @@ public class DevicePane extends TitledDescriptionPane {
this.keyDerivation = keyDerivation;
this.message = message;
this.device = device;
this.defaultDevice = defaultDevice;
setDefaultStatus();
showHideLink.setVisible(false);
@@ -145,6 +151,7 @@ public class DevicePane extends TitledDescriptionPane {
private void initialise(Device device) {
if(device.isNeedsPinSent()) {
unlockButton.setDefaultButton(defaultDevice);
unlockButton.setVisible(true);
} else if(device.isNeedsPassphraseSent()) {
setPassphraseButton.setVisible(true);
@@ -229,7 +236,6 @@ public class DevicePane extends TitledDescriptionPane {
private void createSignButton() {
signButton = new Button("Sign");
signButton.setDefaultButton(true);
signButton.setAlignment(Pos.CENTER_RIGHT);
signButton.setMinWidth(44);
signButton.setOnAction(event -> {
@@ -242,7 +248,6 @@ public class DevicePane extends TitledDescriptionPane {
private void createDisplayAddressButton() {
displayAddressButton = new Button("Display Address");
displayAddressButton.setDefaultButton(true);
displayAddressButton.setAlignment(Pos.CENTER_RIGHT);
displayAddressButton.setOnAction(event -> {
displayAddressButton.setDisable(true);
@@ -259,7 +264,6 @@ public class DevicePane extends TitledDescriptionPane {
private void createSignMessageButton() {
signMessageButton = new Button("Sign Message");
signMessageButton.setDefaultButton(true);
signMessageButton.setAlignment(Pos.CENTER_RIGHT);
signMessageButton.setOnAction(event -> {
signMessageButton.setDisable(true);
@@ -284,7 +288,9 @@ public class DevicePane extends TitledDescriptionPane {
vBox.setMaxHeight(120);
vBox.setSpacing(42);
pinField = (CustomPasswordField)TextFields.createClearablePasswordField();
Platform.runLater(() -> pinField.requestFocus());
enterPinButton = new Button("Enter PIN");
enterPinButton.setDefaultButton(true);
enterPinButton.setOnAction(event -> {
enterPinButton.setDisable(true);
sendPin(pinField.getText());
@@ -324,9 +330,15 @@ public class DevicePane extends TitledDescriptionPane {
CustomPasswordField passphraseField = (CustomPasswordField)TextFields.createClearablePasswordField();
passphrase.bind(passphraseField.textProperty());
HBox.setHgrow(passphraseField, Priority.ALWAYS);
passphraseField.setOnAction(event -> {
setExpanded(false);
setDescription("Confirm passphrase on device...");
sendPassphrase(passphrase.get());
});
SplitMenuButton sendPassphraseButton = new SplitMenuButton();
sendPassphraseButton.setText("Send Passphrase");
sendPassphraseButton.getStyleClass().add("default-button");
sendPassphraseButton.setOnAction(event -> {
setExpanded(false);
setDescription("Confirm passphrase on device...");
@@ -604,17 +616,23 @@ public class DevicePane extends TitledDescriptionPane {
private void showOperationButton() {
if(deviceOperation.equals(DeviceOperation.IMPORT)) {
if(defaultDevice) {
importButton.getStyleClass().add("default-button");
}
importButton.setVisible(true);
showHideLink.setText("Show derivation...");
showHideLink.setVisible(true);
setContent(getDerivationEntry(wallet.getScriptType() == null ? ScriptType.P2WPKH.getDefaultDerivation() : wallet.getScriptType().getDefaultDerivation()));
} else if(deviceOperation.equals(DeviceOperation.SIGN)) {
signButton.setDefaultButton(defaultDevice);
signButton.setVisible(true);
showHideLink.setVisible(false);
} else if(deviceOperation.equals(DeviceOperation.DISPLAY_ADDRESS)) {
displayAddressButton.setDefaultButton(defaultDevice);
displayAddressButton.setVisible(true);
showHideLink.setVisible(false);
} else if(deviceOperation.equals(DeviceOperation.SIGN_MESSAGE)) {
signMessageButton.setDefaultButton(defaultDevice);
signMessageButton.setVisible(true);
showHideLink.setVisible(false);
}
@@ -22,8 +22,8 @@ public class DeviceSignDialog extends DeviceDialog<PSBT> {
}
@Override
protected DevicePane getDevicePane(Device device) {
return new DevicePane(psbt, device);
protected DevicePane getDevicePane(Device device, boolean defaultDevice) {
return new DevicePane(psbt, device, defaultDevice);
}
@Subscribe
@@ -26,8 +26,8 @@ public class DeviceSignMessageDialog extends DeviceDialog<String> {
}
@Override
protected DevicePane getDevicePane(Device device) {
return new DevicePane(wallet, message, keyDerivation, device);
protected DevicePane getDevicePane(Device device, boolean defaultDevice) {
return new DevicePane(wallet, message, keyDerivation, device, defaultDevice);
}
@Subscribe
@@ -92,7 +92,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
List<Device> devices = enumerateService.getValue();
importAccordion.getPanes().removeIf(titledPane -> titledPane instanceof DevicePane);
for(Device device : devices) {
DevicePane devicePane = new DevicePane(new Wallet(), device);
DevicePane devicePane = new DevicePane(new Wallet(), device, devices.size() == 1);
importAccordion.getPanes().add(0, devicePane);
}
Platform.runLater(() -> EventManager.get().post(new UsbDeviceEvent(devices)));
@@ -2,7 +2,6 @@ package com.sparrowwallet.sparrow.keystoreimport;
import com.sparrowwallet.sparrow.control.DevicePane;
import com.sparrowwallet.sparrow.io.Device;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.Accordion;
@@ -14,7 +13,7 @@ public class HwUsbDevicesController extends KeystoreImportDetailController {
public void initializeView(List<Device> devices) {
for(Device device : devices) {
DevicePane devicePane = new DevicePane(getMasterController().getWallet(), device);
DevicePane devicePane = new DevicePane(getMasterController().getWallet(), device, devices.size() == 1);
deviceAccordion.getPanes().add(devicePane);
}
}
@@ -462,7 +462,9 @@ public class WalletForm {
for(WalletTabData tabData : event.getClosedWalletTabData()) {
if(tabData.getWalletForm() == this) {
storage.close();
AppServices.clearTransactionHistoryCache(wallet);
if(wallet.isValid()) {
AppServices.clearTransactionHistoryCache(wallet);
}
EventManager.get().unregister(this);
}
}