P2P status indicator with update prompt

Co-authored-by: jmacxx <47253594+jmacxx@users.noreply.github.com>
Co-authored-by: Christoph Atteneder <christoph.atteneder@gmail.com>
This commit is contained in:
napoly 2022-11-20 21:01:42 +01:00 committed by woodser
parent a2929035bc
commit bd70b935e4
13 changed files with 354 additions and 64 deletions

View file

@ -21,6 +21,10 @@
-fx-image: url("../../images/green_circle.png");
}
#image-yellow_circle {
-fx-image: url("../../images/yellow_circle.png");
}
#image-blue_circle {
-fx-image: url("../../images/blue_circle.png");
}

View file

@ -34,6 +34,7 @@ import bisq.desktop.main.market.offerbook.OfferBookChartView;
import bisq.desktop.main.offer.BuyOfferView;
import bisq.desktop.main.offer.SellOfferView;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.TorNetworkSettingsWindow;
import bisq.desktop.main.portfolio.PortfolioView;
import bisq.desktop.main.settings.SettingsView;
import bisq.desktop.main.shared.PriceFeedComboBoxItem;
@ -58,6 +59,10 @@ import com.jfoenix.controls.JFXBadge;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXProgressBar;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
@ -91,6 +96,8 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.util.Duration;
import java.text.DecimalFormat;
import java.text.NumberFormat;
@ -114,6 +121,22 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
private final static int SHOW_TOR_SETTINGS_DELAY_SEC = 90;
@Setter
private Runnable onApplicationStartedHandler;
private static Transitions transitions;
private static StackPane rootContainer;
private final ViewLoader viewLoader;
private final Navigation navigation;
private final ToggleGroup navButtons = new ToggleGroup();
private ChangeListener<String> walletServiceErrorMsgListener;
private ChangeListener<String> btcSyncIconIdListener;
private ChangeListener<String> splashP2PNetworkErrorMsgListener;
private ChangeListener<String> splashP2PNetworkIconIdListener;
private ChangeListener<Boolean> splashP2PNetworkVisibleListener;
private BusyAnimation splashP2PNetworkBusyAnimation;
private Label splashP2PNetworkLabel;
private ProgressBar btcSyncIndicator, p2pNetworkProgressBar;
private Label btcSplashInfo;
private Popup p2PNetworkWarnMsgPopup, btcNetworkWarnMsgPopup;
private final TorNetworkSettingsWindow torNetworkSettingsWindow;
public static StackPane getRootContainer() {
return MainView.rootContainer;
@ -135,34 +158,17 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
transitions.removeEffect(MainView.rootContainer);
}
private static Transitions transitions;
private static StackPane rootContainer;
private final ViewLoader viewLoader;
private final Navigation navigation;
private final ToggleGroup navButtons = new ToggleGroup();
private ChangeListener<String> walletServiceErrorMsgListener;
private ChangeListener<String> btcSyncIconIdListener;
private ChangeListener<String> splashP2PNetworkErrorMsgListener;
private ChangeListener<String> splashP2PNetworkIconIdListener;
private ChangeListener<Boolean> splashP2PNetworkVisibleListener;
private BusyAnimation splashP2PNetworkBusyAnimation;
private Label splashP2PNetworkLabel;
private ProgressBar btcSyncIndicator, p2pNetworkProgressBar;
private Label btcSplashInfo;
private Popup p2PNetworkWarnMsgPopup, btcNetworkWarnMsgPopup;
@Inject
public MainView(MainViewModel model,
CachingViewLoader viewLoader,
Navigation navigation,
Transitions transitions) {
Transitions transitions,
TorNetworkSettingsWindow torNetworkSettingsWindow) {
super(model);
this.viewLoader = viewLoader;
this.navigation = navigation;
MainView.transitions = transitions;
this.torNetworkSettingsWindow = torNetworkSettingsWindow;
}
@Override
@ -596,6 +602,9 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
splashP2PNetworkIcon.setVisible(false);
splashP2PNetworkIcon.setManaged(false);
HBox.setMargin(splashP2PNetworkIcon, new Insets(0, 0, 5, 0));
splashP2PNetworkIcon.setOnMouseClicked(e -> {
torNetworkSettingsWindow.show();
});
Timer showTorNetworkSettingsTimer = UserThread.runAfter(() -> {
showTorNetworkSettingsButton.setVisible(true);
@ -737,6 +746,40 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
p2PNetworkWarnMsgPopup.hide();
}
});
p2PNetworkIcon.setOnMouseClicked(e -> {
torNetworkSettingsWindow.show();
});
ImageView p2PNetworkStatusIcon = new ImageView();
setRightAnchor(p2PNetworkStatusIcon, 30d);
setBottomAnchor(p2PNetworkStatusIcon, 7d);
Tooltip p2pNetworkStatusToolTip = new Tooltip();
Tooltip.install(p2PNetworkStatusIcon, p2pNetworkStatusToolTip);
p2PNetworkStatusIcon.setOnMouseEntered(e -> p2pNetworkStatusToolTip.setText(model.getP2pConnectionSummary()));
Timeline flasher = new Timeline(
new KeyFrame(Duration.seconds(0.5), e -> p2PNetworkStatusIcon.setOpacity(0.2)),
new KeyFrame(Duration.seconds(1.0), e -> p2PNetworkStatusIcon.setOpacity(1))
);
flasher.setCycleCount(Animation.INDEFINITE);
model.getP2PNetworkStatusIconId().addListener((ov, oldValue, newValue) -> {
if (newValue.equalsIgnoreCase("flashing:image-yellow_circle")) {
p2PNetworkStatusIcon.setId("image-yellow_circle");
flasher.play();
} else {
p2PNetworkStatusIcon.setId(newValue);
flasher.stop();
p2PNetworkStatusIcon.setOpacity(1);
}
});
p2PNetworkStatusIcon.setOnMouseClicked(e -> {
if (p2PNetworkStatusIcon.getId().equalsIgnoreCase("image-alert-round")) {
new Popup().warning(Res.get("popup.info.p2pStatusIndicator.red", model.getP2pConnectionSummary())).show();
} else if (p2PNetworkStatusIcon.getId().equalsIgnoreCase("image-yellow_circle")) {
new Popup().information(Res.get("popup.info.p2pStatusIndicator.yellow", model.getP2pConnectionSummary())).show();
} else {
new Popup().information(Res.get("popup.info.p2pStatusIndicator.green", model.getP2pConnectionSummary())).show();
}
});
model.getUpdatedDataReceived().addListener((observable, oldValue, newValue) -> {
UserThread.execute(() -> {
@ -752,10 +795,10 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
VBox vBox = new VBox();
vBox.setAlignment(Pos.CENTER_RIGHT);
vBox.getChildren().addAll(p2PNetworkLabel, p2pNetworkProgressBar);
setRightAnchor(vBox, 33d);
setRightAnchor(vBox, 53d);
setBottomAnchor(vBox, 5d);
return new AnchorPane(separator, btcInfoLabel, versionBox, vBox, p2PNetworkIcon) {{
return new AnchorPane(separator, btcInfoLabel, versionBox, vBox, p2PNetworkStatusIcon, p2PNetworkIcon) {{
setId("footer-pane");
setMinHeight(30);
setMaxHeight(30);

View file

@ -17,9 +17,12 @@
package bisq.desktop.main;
import bisq.desktop.Navigation;
import bisq.desktop.app.HavenoApp;
import bisq.desktop.common.model.ViewModel;
import bisq.desktop.components.TxIdTextField;
import bisq.desktop.main.account.AccountView;
import bisq.desktop.main.account.content.backup.BackupView;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.overlays.notifications.NotificationCenter;
import bisq.desktop.main.overlays.popups.Popup;
@ -133,6 +136,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
@Getter
private final TorNetworkSettingsWindow torNetworkSettingsWindow;
private final CorruptedStorageFileHandler corruptedStorageFileHandler;
private final Navigation navigation;
@Getter
private final BooleanProperty showAppScreen = new SimpleBooleanProperty();
@ -175,7 +179,8 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
LocalBitcoinNode localBitcoinNode,
AccountAgeWitnessService accountAgeWitnessService,
TorNetworkSettingsWindow torNetworkSettingsWindow,
CorruptedStorageFileHandler corruptedStorageFileHandler) {
CorruptedStorageFileHandler corruptedStorageFileHandler,
Navigation navigation) {
this.bisqSetup = bisqSetup;
this.connectionService = connectionService;
this.user = user;
@ -199,6 +204,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
this.accountAgeWitnessService = accountAgeWitnessService;
this.torNetworkSettingsWindow = torNetworkSettingsWindow;
this.corruptedStorageFileHandler = corruptedStorageFileHandler;
this.navigation = navigation;
TxIdTextField.setPreferences(preferences);
@ -411,6 +417,12 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
.show();
});
bisqSetup.setTorAddressUpgradeHandler(() -> new Popup().information(Res.get("popup.info.torMigration.msg"))
.actionButtonTextWithGoTo("navigation.account.backup")
.onAction(() -> {
navigation.setReturnPath(navigation.getCurrentPath());
navigation.navigateTo(MainView.class, AccountView.class, BackupView.class);
}).show());
corruptedStorageFileHandler.getFiles().ifPresent(files -> new Popup()
.warning(Res.get("popup.warning.incompatibleDB", files.toString(), config.appDataDir))
@ -704,6 +716,10 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
return bisqSetup.getP2PNetworkIconId();
}
StringProperty getP2PNetworkStatusIconId() {
return bisqSetup.getP2PNetworkStatusIconId();
}
BooleanProperty getUpdatedDataReceived() {
return bisqSetup.getUpdatedDataReceived();
}
@ -767,4 +783,10 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
overlay.show();
}
}
public String getP2pConnectionSummary() {
return Res.get("mainView.status.connections",
p2PService.getNetworkNode().getInboundConnectionCount(),
p2PService.getNetworkNode().getOutboundConnectionCount());
}
}

View file

@ -123,7 +123,7 @@ public class TorNetworkSettingsWindow extends Overlay<TorNetworkSettingsWindow>
headLine = Res.get("torNetworkSettingWindow.header");
width = 1068;
rowIndex = 0;
createGridPane();
gridPane.getColumnConstraints().get(0).setHalignment(HPos.LEFT);