diff --git a/src/main/java/com/sparrowwallet/sparrow/AppServices.java b/src/main/java/com/sparrowwallet/sparrow/AppServices.java index 9ab973b7..9d1f78e3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppServices.java @@ -846,6 +846,7 @@ public class AppServices { addMempoolRateSizes(event.getMempoolRateSizes()); minimumRelayFeeRate = event.getMinimumRelayFeeRate(); latestBlockHeader = event.getBlockHeader(); + Config.get().addRecentServer(); } @Subscribe diff --git a/src/main/java/com/sparrowwallet/sparrow/control/ComboBoxTextField.java b/src/main/java/com/sparrowwallet/sparrow/control/ComboBoxTextField.java index f0ce04a4..efb037ee 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/ComboBoxTextField.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/ComboBoxTextField.java @@ -12,6 +12,8 @@ import org.controlsfx.control.textfield.CustomTextField; public class ComboBoxTextField extends CustomTextField { private final ObjectProperty> comboProperty = new SimpleObjectProperty<>(); + private boolean comboShowing; + public ComboBoxTextField() { super(); getStyleClass().add("combo-text-field"); @@ -26,7 +28,13 @@ public class ComboBoxTextField extends CustomTextField { showComboButtonPane.setCursor(Cursor.DEFAULT); showComboButtonPane.setOnMouseReleased(e -> { if(comboProperty.isNotNull().get()) { - comboProperty.get().show(); + if(comboShowing) { + comboProperty.get().hide(); + } else { + comboProperty.get().show(); + } + + comboShowing = !comboShowing; } }); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Config.java b/src/main/java/com/sparrowwallet/sparrow/io/Config.java index fbd2e695..c7acd008 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Config.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Config.java @@ -13,10 +13,7 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.Currency; -import java.util.List; -import java.util.Random; +import java.util.*; import java.util.stream.Collectors; public class Config { @@ -52,10 +49,12 @@ public class Config { private ServerType serverType; private String publicElectrumServer; private String coreServer; + private List recentCoreServers; private CoreAuthType coreAuthType; private File coreDataDir; private String coreAuth; private String electrumServer; + private List recentElectrumServers; private File electrumServerCert; private boolean useProxy; private String proxyServer; @@ -397,6 +396,23 @@ public class Config { flush(); } + public List getRecentCoreServers() { + return recentCoreServers; + } + + public void addRecentCoreServer(String coreServer) { + if(recentCoreServers == null) { + recentCoreServers = new ArrayList<>(); + } + + if(!recentCoreServers.contains(coreServer)) { + recentCoreServers.stream().filter(url -> Objects.equals(Protocol.getHost(url), Protocol.getHost(coreServer))) + .findFirst().ifPresent(existingUrl -> recentCoreServers.remove(existingUrl)); + recentCoreServers.add(coreServer); + flush(); + } + } + public CoreAuthType getCoreAuthType() { return coreAuthType; } @@ -433,6 +449,31 @@ public class Config { flush(); } + public List getRecentElectrumServers() { + return recentElectrumServers; + } + + public void addRecentServer() { + if(serverType == ServerType.BITCOIN_CORE && coreServer != null) { + addRecentCoreServer(coreServer); + } else if(serverType == ServerType.ELECTRUM_SERVER && electrumServer != null) { + addRecentElectrumServer(electrumServer); + } + } + + public void addRecentElectrumServer(String electrumServer) { + if(recentElectrumServers == null) { + recentElectrumServers = new ArrayList<>(); + } + + if(!recentElectrumServers.contains(electrumServer)) { + recentElectrumServers.stream().filter(url -> Objects.equals(Protocol.getHost(url), Protocol.getHost(electrumServer))) + .findFirst().ifPresent(existingUrl -> recentElectrumServers.remove(existingUrl)); + recentElectrumServers.add(electrumServer); + flush(); + } + } + public File getElectrumServerCert() { return electrumServerCert; } diff --git a/src/main/java/com/sparrowwallet/sparrow/net/Protocol.java b/src/main/java/com/sparrowwallet/sparrow/net/Protocol.java index 593b1470..aed19ae3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/net/Protocol.java +++ b/src/main/java/com/sparrowwallet/sparrow/net/Protocol.java @@ -144,4 +144,13 @@ public enum Protocol { return null; } + + public static String getHost(String url) { + Protocol protocol = getProtocol(url); + if(protocol != null) { + return protocol.getServerHostAndPort(url).getHost(); + } + + return null; + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java b/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java index 0b3a6385..1b9ec57d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java @@ -6,6 +6,7 @@ import com.sparrowwallet.drongo.Network; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.Mode; +import com.sparrowwallet.sparrow.control.ComboBoxTextField; import com.sparrowwallet.sparrow.control.TextFieldValidator; import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch; import com.sparrowwallet.sparrow.event.*; @@ -23,6 +24,7 @@ import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.stage.Stage; import javafx.util.Duration; +import javafx.util.StringConverter; import org.berndpruenster.netlayer.tor.Tor; import org.controlsfx.control.SegmentedButton; import org.controlsfx.glyphfont.Glyph; @@ -41,6 +43,7 @@ import java.io.FileInputStream; import java.security.cert.CertificateFactory; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Random; @@ -76,7 +79,10 @@ public class ServerPreferencesController extends PreferencesDetailController { private Form coreForm; @FXML - private TextField coreHost; + private ComboBox recentCoreServers; + + @FXML + private ComboBoxTextField coreHost; @FXML private TextField corePort; @@ -115,7 +121,10 @@ public class ServerPreferencesController extends PreferencesDetailController { private Form electrumForm; @FXML - private TextField electrumHost; + private ComboBox recentElectrumServers; + + @FXML + private ComboBoxTextField electrumHost; @FXML private TextField electrumPort; @@ -258,6 +267,29 @@ public class ServerPreferencesController extends PreferencesDetailController { } }); + recentCoreServers.setConverter(new UrlHostConverter()); + recentCoreServers.setItems(FXCollections.observableList(Config.get().getRecentCoreServers() == null ? new ArrayList<>() : Config.get().getRecentCoreServers())); + recentCoreServers.prefWidthProperty().bind(coreHost.widthProperty()); + recentCoreServers.valueProperty().addListener((observable, oldValue, newValue) -> { + if(newValue != null && Protocol.getProtocol(newValue) != null) { + HostAndPort hostAndPort = Protocol.getProtocol(newValue).getServerHostAndPort(newValue); + coreHost.setText(hostAndPort.getHost()); + corePort.setText(Integer.toString(hostAndPort.getPort())); + } + }); + + recentElectrumServers.setConverter(new UrlHostConverter()); + recentElectrumServers.setItems(FXCollections.observableList(Config.get().getRecentElectrumServers() == null ? new ArrayList<>() : Config.get().getRecentElectrumServers())); + recentElectrumServers.prefWidthProperty().bind(electrumHost.widthProperty()); + recentElectrumServers.valueProperty().addListener((observable, oldValue, newValue) -> { + if(newValue != null && Protocol.getProtocol(newValue) != null) { + HostAndPort hostAndPort = Protocol.getProtocol(newValue).getServerHostAndPort(newValue); + electrumHost.setText(hostAndPort.getHost()); + electrumPort.setText(Integer.toString(hostAndPort.getPort())); + electrumUseSsl.setSelected(Protocol.getProtocol(newValue) == Protocol.SSL); + } + }); + electrumUseSsl.selectedProperty().addListener((observable, oldValue, newValue) -> { setElectrumServerInConfig(config); electrumCertificate.setDisable(!newValue); @@ -507,6 +539,7 @@ public class ServerPreferencesController extends PreferencesDetailController { publicProxyHost.setDisable(!editable); publicProxyPort.setDisable(!editable); + recentCoreServers.setVisible(editable); coreHost.setDisable(!editable); corePort.setDisable(!editable); coreAuthToggleGroup.getToggles().forEach(toggle -> ((ToggleButton)toggle).setDisable(!editable)); @@ -518,6 +551,7 @@ public class ServerPreferencesController extends PreferencesDetailController { coreProxyHost.setDisable(!editable); coreProxyPort.setDisable(!editable); + recentElectrumServers.setVisible(editable); electrumHost.setDisable(!editable); electrumPort.setDisable(!editable); electrumUseSsl.setDisable(!editable); @@ -808,4 +842,16 @@ public class ServerPreferencesController extends PreferencesDetailController { } }); } + + private static class UrlHostConverter extends StringConverter { + @Override + public String toString(String serverUrl) { + return serverUrl == null || Protocol.getProtocol(serverUrl) == null ? "" : Protocol.getProtocol(serverUrl).getServerHostAndPort(serverUrl).getHost(); + } + + @Override + public String fromString(String string) { + return null; + } + } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/preferences/server.fxml b/src/main/resources/com/sparrowwallet/sparrow/preferences/server.fxml index ff4e2305..43691886 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/preferences/server.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/preferences/server.fxml @@ -16,9 +16,9 @@ - - + + @@ -100,7 +100,10 @@
- + + + + @@ -147,7 +150,10 @@
- + + + +