mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-04 21:36:45 +00:00
add tor status indicator to status bar
This commit is contained in:
parent
ca1f934138
commit
e12f7a634a
6 changed files with 131 additions and 0 deletions
|
@ -1602,6 +1602,29 @@ public class AppController implements Initializable {
|
||||||
tabLabel.getGraphic().getStyleClass().remove("failure");
|
tabLabel.getGraphic().getStyleClass().remove("failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setTorIcon() {
|
||||||
|
TorStatusLabel torStatusLabel = null;
|
||||||
|
for(Node node : statusBar.getRightItems()) {
|
||||||
|
if(node instanceof TorStatusLabel) {
|
||||||
|
torStatusLabel = (TorStatusLabel)node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!AppServices.isUsingProxy()) {
|
||||||
|
if(torStatusLabel != null) {
|
||||||
|
torStatusLabel.update();
|
||||||
|
statusBar.getRightItems().removeAll(torStatusLabel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(torStatusLabel == null) {
|
||||||
|
torStatusLabel = new TorStatusLabel();
|
||||||
|
statusBar.getRightItems().add(Math.max(statusBar.getRightItems().size() - 2, 0), torStatusLabel);
|
||||||
|
} else {
|
||||||
|
torStatusLabel.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void themeChanged(ThemeChangedEvent event) {
|
public void themeChanged(ThemeChangedEvent event) {
|
||||||
String darkCss = getClass().getResource("darktheme.css").toExternalForm();
|
String darkCss = getClass().getResource("darktheme.css").toExternalForm();
|
||||||
|
@ -1859,6 +1882,7 @@ public class AppController implements Initializable {
|
||||||
String status = CONNECTION_FAILED_PREFIX + event.getMessage();
|
String status = CONNECTION_FAILED_PREFIX + event.getMessage();
|
||||||
statusUpdated(new StatusEvent(status));
|
statusUpdated(new StatusEvent(status));
|
||||||
serverToggleStopAnimation();
|
serverToggleStopAnimation();
|
||||||
|
setTorIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -1867,6 +1891,7 @@ public class AppController implements Initializable {
|
||||||
statusUpdated(new StatusEvent(status));
|
statusUpdated(new StatusEvent(status));
|
||||||
setServerToggleTooltip(event.getBlockHeight());
|
setServerToggleTooltip(event.getBlockHeight());
|
||||||
serverToggleStopAnimation();
|
serverToggleStopAnimation();
|
||||||
|
setTorIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -1993,18 +2018,21 @@ public class AppController implements Initializable {
|
||||||
public void torBootStatus(TorBootStatusEvent event) {
|
public void torBootStatus(TorBootStatusEvent event) {
|
||||||
serverToggle.setDisable(true);
|
serverToggle.setDisable(true);
|
||||||
statusUpdated(new StatusEvent(event.getStatus(), 120));
|
statusUpdated(new StatusEvent(event.getStatus(), 120));
|
||||||
|
setTorIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void torFailedStatus(TorFailedStatusEvent event) {
|
public void torFailedStatus(TorFailedStatusEvent event) {
|
||||||
serverToggle.setDisable(false);
|
serverToggle.setDisable(false);
|
||||||
statusUpdated(new StatusEvent(event.getStatus()));
|
statusUpdated(new StatusEvent(event.getStatus()));
|
||||||
|
setTorIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void torReadyStatus(TorReadyStatusEvent event) {
|
public void torReadyStatus(TorReadyStatusEvent event) {
|
||||||
serverToggle.setDisable(false);
|
serverToggle.setDisable(false);
|
||||||
statusUpdated(new StatusEvent(event.getStatus()));
|
statusUpdated(new StatusEvent(event.getStatus()));
|
||||||
|
setTorIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|
|
@ -119,6 +119,11 @@ public class AppServices {
|
||||||
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean online) {
|
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean online) {
|
||||||
if(online) {
|
if(online) {
|
||||||
if(Config.get().requiresInternalTor() && !isTorRunning()) {
|
if(Config.get().requiresInternalTor() && !isTorRunning()) {
|
||||||
|
if(torService.getState() == Worker.State.SCHEDULED) {
|
||||||
|
torService.cancel();
|
||||||
|
torService.reset();
|
||||||
|
}
|
||||||
|
|
||||||
torService.start();
|
torService.start();
|
||||||
} else {
|
} else {
|
||||||
restartServices();
|
restartServices();
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
|
import javafx.concurrent.ScheduledService;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Tooltip;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
import org.controlsfx.glyphfont.Glyph;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class TorStatusLabel extends Label {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TorStatusLabel.class);
|
||||||
|
|
||||||
|
private final TorConnectionTest torConnectionTest = new TorConnectionTest();
|
||||||
|
|
||||||
|
public TorStatusLabel() {
|
||||||
|
getStyleClass().add("tor-status");
|
||||||
|
setPadding(new Insets(1, 0, 0, 3));
|
||||||
|
setGraphic(getIcon());
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
boolean proxyInUse = AppServices.isUsingProxy();
|
||||||
|
boolean internal = AppServices.isTorRunning();
|
||||||
|
|
||||||
|
if(!proxyInUse || internal) {
|
||||||
|
torConnectionTest.cancel();
|
||||||
|
if(internal) {
|
||||||
|
setTooltip(new Tooltip("Internal Tor proxy enabled"));
|
||||||
|
}
|
||||||
|
} else if(!torConnectionTest.isRunning()) {
|
||||||
|
torConnectionTest.setPeriod(Duration.seconds(20.0));
|
||||||
|
torConnectionTest.setOnSucceeded(workerStateEvent -> {
|
||||||
|
getStyleClass().remove("failure");
|
||||||
|
setTooltip(new Tooltip("External Tor proxy enabled"));
|
||||||
|
});
|
||||||
|
torConnectionTest.setOnFailed(workerStateEvent -> {
|
||||||
|
if(!getStyleClass().contains("failure")) {
|
||||||
|
getStyleClass().add("failure");
|
||||||
|
}
|
||||||
|
setTooltip(new Tooltip("External Tor proxy error: " + workerStateEvent.getSource().getException().getMessage()));
|
||||||
|
log.warn("Failed to connect to external Tor proxy: " + workerStateEvent.getSource().getException().getMessage());
|
||||||
|
});
|
||||||
|
torConnectionTest.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node getIcon() {
|
||||||
|
Glyph adjust = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.ADJUST);
|
||||||
|
adjust.setFontSize(15);
|
||||||
|
adjust.setRotate(180);
|
||||||
|
|
||||||
|
Glyph bullseye = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.BULLSEYE);
|
||||||
|
bullseye.setFontSize(14);
|
||||||
|
|
||||||
|
Group group = new Group();
|
||||||
|
group.getChildren().addAll(adjust, bullseye);
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TorConnectionTest extends ScheduledService<Void> {
|
||||||
|
@Override
|
||||||
|
protected Task<Void> createTask() {
|
||||||
|
return new Task<>() {
|
||||||
|
protected Void call() throws IOException {
|
||||||
|
HostAndPort proxyHostAndPort = HostAndPort.fromString(Config.get().getProxyServer());
|
||||||
|
Socket socket = new Socket(proxyHostAndPort.getHost(), proxyHostAndPort.getPort());
|
||||||
|
socket.close();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ public class FontAwesome5 extends GlyphFont {
|
||||||
* The individual glyphs offered by the FontAwesome5 font.
|
* The individual glyphs offered by the FontAwesome5 font.
|
||||||
*/
|
*/
|
||||||
public static enum Glyph implements INamedCharacter {
|
public static enum Glyph implements INamedCharacter {
|
||||||
|
ADJUST('\uf042'),
|
||||||
ARROW_CIRCLE_DOWN('\uf0ab'),
|
ARROW_CIRCLE_DOWN('\uf0ab'),
|
||||||
ANGLE_DOUBLE_RIGHT('\uf101'),
|
ANGLE_DOUBLE_RIGHT('\uf101'),
|
||||||
ARROW_DOWN('\uf063'),
|
ARROW_DOWN('\uf063'),
|
||||||
|
@ -22,6 +23,7 @@ public class FontAwesome5 extends GlyphFont {
|
||||||
BAN('\uf05e'),
|
BAN('\uf05e'),
|
||||||
BIOHAZARD('\uf780'),
|
BIOHAZARD('\uf780'),
|
||||||
BTC('\uf15a'),
|
BTC('\uf15a'),
|
||||||
|
BULLSEYE('\uf140'),
|
||||||
CAMERA('\uf030'),
|
CAMERA('\uf030'),
|
||||||
CHECK_CIRCLE('\uf058'),
|
CHECK_CIRCLE('\uf058'),
|
||||||
CIRCLE('\uf111'),
|
CIRCLE('\uf111'),
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
-fx-text-fill: rgb(202, 18, 67);
|
-fx-text-fill: rgb(202, 18, 67);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tor-status.failure .glyph-font {
|
||||||
|
-fx-text-fill: rgb(202, 18, 67);
|
||||||
|
}
|
||||||
|
|
||||||
.master-only {
|
.master-only {
|
||||||
-fx-tab-max-height: 0;
|
-fx-tab-max-height: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,10 @@
|
||||||
-fx-fill: #e06c75;
|
-fx-fill: #e06c75;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-bar .tor-status.failure .glyph-font {
|
||||||
|
-fx-text-fill: #e06c75;
|
||||||
|
}
|
||||||
|
|
||||||
.root .titled-description-pane .status-error .text, .root .titled-description-pane .description-error .text {
|
.root .titled-description-pane .status-error .text, .root .titled-description-pane .description-error .text {
|
||||||
-fx-fill: #e06c75;
|
-fx-fill: #e06c75;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue