diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 13e02c07db4..47ac0d2ad2e 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -234,6 +234,8 @@ mainView.footer.usingTor=(using Tor) mainView.footer.localhostBitcoinNode=(localhost) mainView.footer.btcInfo=Bitcoin network peers: {0} / {1} {2} mainView.footer.btcInfo.initializing=Initializing +mainView.footer.bsqInfo.initializing=/ Initializing DAO +mainView.footer.bsqInfo.synchronizing=/ Synchronizing DAO mainView.footer.btcInfo.synchronizedWith=synchronized with mainView.footer.btcInfo.connectingTo=connecting to mainView.footer.btcInfo.connectionFailed=connection failed diff --git a/desktop/src/main/java/bisq/desktop/DesktopModule.java b/desktop/src/main/java/bisq/desktop/DesktopModule.java index aeef737f3b5..3d7b601c166 100644 --- a/desktop/src/main/java/bisq/desktop/DesktopModule.java +++ b/desktop/src/main/java/bisq/desktop/DesktopModule.java @@ -22,7 +22,6 @@ import bisq.desktop.common.view.ViewFactory; import bisq.desktop.common.view.ViewLoader; import bisq.desktop.common.view.guice.InjectorViewFactory; -import bisq.desktop.main.MarketPricePresentation; import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.main.funds.transactions.DisplayedTransactionsFactory; import bisq.desktop.main.funds.transactions.TradableRepository; @@ -31,6 +30,8 @@ import bisq.desktop.main.offer.offerbook.OfferBook; import bisq.desktop.main.overlays.notifications.NotificationCenter; import bisq.desktop.main.overlays.windows.TorNetworkSettingsWindow; +import bisq.desktop.main.presentation.DaoPresentation; +import bisq.desktop.main.presentation.MarketPricePresentation; import bisq.desktop.util.Transitions; import bisq.core.app.AppOptionKeys; @@ -72,6 +73,7 @@ protected void configure() { bind(BsqFormatter.class).in(Singleton.class); bind(TorNetworkSettingsWindow.class).in(Singleton.class); bind(MarketPricePresentation.class).in(Singleton.class); + bind(DaoPresentation.class).in(Singleton.class); bind(Transitions.class).in(Singleton.class); diff --git a/desktop/src/main/java/bisq/desktop/main/MainView.java b/desktop/src/main/java/bisq/desktop/main/MainView.java index f65eca819df..8c9ac145120 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainView.java +++ b/desktop/src/main/java/bisq/desktop/main/MainView.java @@ -592,8 +592,8 @@ private AnchorPane createFooter() { btcInfoLabel.setId("footer-pane"); btcInfoLabel.textProperty().bind(model.getBtcInfo()); - ProgressBar blockchainSyncIndicator = new ProgressBar(-1); - blockchainSyncIndicator.setPrefWidth(120); + ProgressBar blockchainSyncIndicator = new JFXProgressBar(-1); + blockchainSyncIndicator.setPrefWidth(80); blockchainSyncIndicator.setMaxHeight(10); blockchainSyncIndicator.progressProperty().bind(model.getBtcSyncProgress()); diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index f4ed4173134..ea375a77b95 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -29,6 +29,7 @@ import bisq.desktop.main.overlays.windows.WalletPasswordWindow; import bisq.desktop.main.overlays.windows.downloadupdate.DisplayUpdateDownloadWindow; import bisq.desktop.main.presentation.DaoPresentation; +import bisq.desktop.main.presentation.MarketPricePresentation; import bisq.desktop.util.GUIUtil; import bisq.core.alert.PrivateNotificationManager; @@ -66,11 +67,14 @@ import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.monadic.MonadicBinding; +import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.ObservableList; @@ -109,6 +113,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList @Getter private BooleanProperty showAppScreen = new SimpleBooleanProperty(); + private DoubleProperty combinedSyncProgress = new SimpleDoubleProperty(); private final BooleanProperty isSplashScreenRemoved = new SimpleBooleanProperty(); private Timer checkNumberOfBtcPeersTimer; private Timer checkNumberOfP2pNetworkPeersTimer; @@ -354,6 +359,10 @@ private void setupHandlers() { tradeManager.setTakeOfferRequestErrorMessageHandler(errorMessage -> new Popup<>() .warning(Res.get("popup.error.takeOfferRequestFailed", errorMessage)) .show()); + + bisqSetup.getBtcSyncProgress().addListener((observable, oldValue, newValue) -> updateBtcSyncProgress()); + daoPresentation.getBsqSyncProgress().addListener((observable, oldValue, newValue) -> updateBtcSyncProgress()); + } private void setupP2PNumPeersWatcher() { @@ -460,6 +469,16 @@ public void onUpdatedDataReceived() { } } + private void updateBtcSyncProgress() { + final DoubleProperty btcSyncProgress = bisqSetup.getBtcSyncProgress(); + + if (btcSyncProgress.doubleValue() < 1) { + combinedSyncProgress.set(btcSyncProgress.doubleValue()); + } else { + combinedSyncProgress.set(daoPresentation.getBsqSyncProgress().doubleValue()); + } + } + /////////////////////////////////////////////////////////////////////////////////////////// // MainView delegate getters @@ -500,11 +519,13 @@ StringProperty getLockedBalance() { // Wallet StringProperty getBtcInfo() { - return bisqSetup.getBtcInfo(); + final StringProperty combinedInfo = new SimpleStringProperty(); + combinedInfo.bind(Bindings.concat(bisqSetup.getBtcInfo(), " ", daoPresentation.getBsqInfo())); + return combinedInfo; } DoubleProperty getBtcSyncProgress() { - return bisqSetup.getBtcSyncProgress(); + return combinedSyncProgress; } StringProperty getWalletServiceErrorMsg() { diff --git a/desktop/src/main/java/bisq/desktop/main/presentation/DaoPresentation.java b/desktop/src/main/java/bisq/desktop/main/presentation/DaoPresentation.java index 9396931e90d..63ab195a62c 100644 --- a/desktop/src/main/java/bisq/desktop/main/presentation/DaoPresentation.java +++ b/desktop/src/main/java/bisq/desktop/main/presentation/DaoPresentation.java @@ -1,30 +1,115 @@ package bisq.desktop.main.presentation; import bisq.core.app.BisqEnvironment; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.DaoStateListener; +import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.locale.Res; import bisq.core.user.Preferences; import javax.inject.Inject; import javafx.beans.property.BooleanProperty; +import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ChangeListener; import javafx.collections.MapChangeListener; -public class DaoPresentation { +import lombok.Getter; + +public class DaoPresentation implements DaoStateListener { - private final Preferences preferences; public static final String DAO_NEWS = "daoNewsVersion0.9.4"; + private final Preferences preferences; + private final BtcWalletService btcWalletService; + private final DaoFacade daoFacade; + private final BsqWalletService bsqWalletService; + private final DaoStateService daoStateService; + + private final ChangeListener walletChainHeightListener; + + @Getter + private final DoubleProperty bsqSyncProgress = new SimpleDoubleProperty(-1); + @Getter + private final StringProperty bsqInfo = new SimpleStringProperty(Res.get("mainView.footer.bsqInfo.initializing")); private final SimpleBooleanProperty showNotification = new SimpleBooleanProperty(false); @Inject - public DaoPresentation(Preferences preferences) { + public DaoPresentation(Preferences preferences, + BtcWalletService btcWalletService, + BsqWalletService bsqWalletService, + DaoStateService daoStateService, + DaoFacade daoFacade) { this.preferences = preferences; + this.btcWalletService = btcWalletService; + this.bsqWalletService = bsqWalletService; + this.daoFacade = daoFacade; + this.daoStateService = daoStateService; + preferences.getDontShowAgainMapAsObservable().addListener((MapChangeListener) change -> { if (change.getKey().equals(DAO_NEWS) && !BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) { showNotification.set(!change.wasAdded()); } }); + + walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void onUpdateAnyChainHeight() { + final int bsqBlockChainHeight = daoFacade.getChainHeight(); + final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); + if (bsqWalletChainHeight > 0) { + final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; + if (bsqBlockChainHeight != bsqWalletChainHeight) { + bsqSyncProgress.set(-1); + } else { + bsqSyncProgress.set(0); + } + + if (synced) { + bsqInfo.set(""); + } else { + bsqInfo.set(Res.get("mainView.footer.bsqInfo.synchronizing")); + } + } else { + bsqInfo.set(Res.get("mainView.footer.bsqInfo.synchronizing")); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + + } + + @Override + public void onParseBlockChainComplete() { + + } + + @Override + public void onParseTxsCompleteAfterBatchProcessing(Block block) { + onUpdateAnyChainHeight(); + } + + @Override + public void onParseTxsComplete(Block block) { + } public BooleanProperty getShowDaoUpdatesNotification() { @@ -34,5 +119,10 @@ public BooleanProperty getShowDaoUpdatesNotification() { public void setup() { if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) showNotification.set(preferences.showAgain(DAO_NEWS)); + + this.btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); + daoStateService.addBsqStateListener(this); + + onUpdateAnyChainHeight(); } } diff --git a/desktop/src/main/java/bisq/desktop/main/MarketPricePresentation.java b/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java similarity index 99% rename from desktop/src/main/java/bisq/desktop/main/MarketPricePresentation.java rename to desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java index 528923a3fd0..23408f99743 100644 --- a/desktop/src/main/java/bisq/desktop/main/MarketPricePresentation.java +++ b/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java @@ -15,10 +15,11 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main; +package bisq.desktop.main.presentation; import bisq.desktop.components.BalanceWithConfirmationTextField; import bisq.desktop.components.TxIdTextField; +import bisq.desktop.main.PriceFeedComboBoxItem; import bisq.desktop.util.GUIUtil; import bisq.core.btc.wallet.BtcWalletService;