diff --git a/LeftPanel.qml b/LeftPanel.qml index f7f119ec..18c19d56 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -667,7 +667,7 @@ Rectangle { anchors.bottom: daemonProgressBar.top height: 48 syncType: qsTr("Wallet") + translationManager.emptyString - visible: networkStatus.connected + visible: !appWindow.disconnected } MoneroComponents.ProgressBar { @@ -676,7 +676,7 @@ Rectangle { anchors.right: parent.right anchors.bottom: parent.bottom syncType: qsTr("Daemon") + translationManager.emptyString - visible: networkStatus.connected + visible: !appWindow.disconnected height: 62 } } diff --git a/components/NetworkStatusItem.qml b/components/NetworkStatusItem.qml index 3e8496bf..eeb85d61 100644 --- a/components/NetworkStatusItem.qml +++ b/components/NetworkStatusItem.qml @@ -39,23 +39,25 @@ Rectangle { property var connected: Wallet.ConnectionStatus_Disconnected function getConnectionStatusString(status) { - if (status == Wallet.ConnectionStatus_Connected) { - if(!appWindow.daemonSynced) - return qsTr("Synchronizing") - if(persistentSettings.useRemoteNode) - return qsTr("Remote node") - return appWindow.isMining ? qsTr("Connected") + " + " + qsTr("Mining"): qsTr("Connected") + switch (status) { + case Wallet.ConnectionStatus_Connected: + if (!appWindow.daemonSynced) + return qsTr("Synchronizing"); + if (persistentSettings.useRemoteNode) + return qsTr("Remote node"); + return appWindow.isMining ? qsTr("Connected") + " + " + qsTr("Mining"): qsTr("Connected"); + case Wallet.ConnectionStatus_WrongVersion: + return qsTr("Wrong version"); + case Wallet.ConnectionStatus_Disconnected: + if (appWindow.walletMode <= 1) { + return qsTr("Searching node") + translationManager.emptyString; + } + return qsTr("Disconnected"); + case Wallet.ConnectionStatus_Connecting: + return qsTr("Connecting"); + default: + return qsTr("Invalid connection status"); } - if (status == Wallet.ConnectionStatus_WrongVersion) - return qsTr("Wrong version") - if (status == Wallet.ConnectionStatus_Disconnected){ - if(appWindow.walletMode <= 1){ - return qsTr("Searching node") + translationManager.emptyString; - } - return qsTr("Disconnected") - } - - return qsTr("Invalid connection status") } RowLayout { @@ -159,7 +161,7 @@ Rectangle { opacity: iconItem.opacity * (refreshMouseArea.visible ? 1 : 0.5) text: FontAwesome.random visible: ( - item.connected != Wallet.ConnectionStatus_Disconnected && + !appWindow.disconnected && !persistentSettings.useRemoteNode && persistentSettings.bootstrapNodeAddress == "auto" ) diff --git a/main.qml b/main.qml index efe8b740..d09bd8d0 100644 --- a/main.qml +++ b/main.qml @@ -57,6 +57,7 @@ ApplicationWindow { property bool ctrlPressed: false property alias persistentSettings : persistentSettings property var currentWallet; + property bool disconnected: currentWallet ? currentWallet.disconnected : false property var transaction; property var transactionDescription; property var walletPassword @@ -64,7 +65,7 @@ ApplicationWindow { property bool daemonSynced: false property bool walletSynced: false property int maxWindowHeight: (isAndroid || isIOS)? screenHeight : (screenHeight < 900)? 720 : 800; - property bool daemonRunning: false + property bool daemonRunning: !persistentSettings.useRemoteNode && !disconnected property alias toolTip: toolTip property string walletName property bool viewOnly: false @@ -474,19 +475,11 @@ ApplicationWindow { middlePanel.updateStatus(); leftPanel.networkStatus.connected = status - // update local daemon status. - const isDisconnected = status === Wallet.ConnectionStatus_Disconnected; - if (!persistentSettings.useRemoteNode) { - daemonRunning = !isDisconnected; - } else { - daemonRunning = false; - } - // Update fee multiplier dropdown on transfer page middlePanel.transferView.updatePriorityDropdown(); // If wallet isnt connected, advanced wallet mode and no daemon is running - Ask - if (appWindow.walletMode >= 2 && !persistentSettings.useRemoteNode && !walletInitialized && isDisconnected) { + if (appWindow.walletMode >= 2 && !persistentSettings.useRemoteNode && !walletInitialized && disconnected) { daemonManager.runningAsync(persistentSettings.nettype, function(running) { if (!running) { daemonManagerDialog.open(); @@ -642,7 +635,7 @@ ApplicationWindow { } // Update wallet sync progress - leftPanel.isSyncing = (currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced + leftPanel.isSyncing = !disconnected && !daemonSynced; // Update transfer page status middlePanel.updateStatus(); @@ -692,7 +685,6 @@ ApplicationWindow { function onDaemonStarted(){ console.log("daemon started"); - daemonRunning = true; hideProcessingSplash(); currentWallet.connected(true); // resume refresh @@ -704,7 +696,6 @@ ApplicationWindow { function onDaemonStopped(){ console.log("daemon stopped"); hideProcessingSplash(); - daemonRunning = false; currentWallet.connected(true); } @@ -713,7 +704,6 @@ ApplicationWindow { hideProcessingSplash(); // resume refresh currentWallet.startRefresh(); - daemonRunning = false; informationPopup.title = qsTr("Daemon failed to start") + translationManager.emptyString; informationPopup.text = qsTr("Please check your wallet and daemon log for errors. You can also try to start %1 manually.").arg((isWindows)? "monerod.exe" : "monerod") informationPopup.icon = StandardIcon.Critical @@ -1867,11 +1857,10 @@ ApplicationWindow { const disconnectedTimeoutSec = 30; const firstCheckDelaySec = 2; - const connected = leftPanel.networkStatus.connected !== Wallet.ConnectionStatus_Disconnected; const firstRun = appWindow.disconnectedEpoch == 0; if (firstRun) { appWindow.disconnectedEpoch = Utils.epoch() + firstCheckDelaySec - disconnectedTimeoutSec; - } else if (connected) { + } else if (!disconnected) { appWindow.disconnectedEpoch = Utils.epoch(); } diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 2d31430d..950a0e3f 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -717,6 +717,7 @@ Rectangle { //pageRoot.enabled = false; switch (currentWallet.connected()) { + case Wallet.ConnectionStatus_Connecting: case Wallet.ConnectionStatus_Disconnected: root.warningContent = messageNotConnected; break diff --git a/pages/merchant/Merchant.qml b/pages/merchant/Merchant.qml index aa17d9f3..da4a59b0 100644 --- a/pages/merchant/Merchant.qml +++ b/pages/merchant/Merchant.qml @@ -582,7 +582,7 @@ Item { return } - if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) { + if (appWindow.disconnected) { root.trackingError = qsTr("WARNING: no connection to daemon"); trackingModel.clear(); return diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index c32026f8..89707b5a 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -153,12 +153,14 @@ NetworkType::Type Wallet::nettype() const void Wallet::updateConnectionStatusAsync() { m_scheduler.run([this] { + if (m_connectionStatus == Wallet::ConnectionStatus_Disconnected) + { + setConnectionStatus(ConnectionStatus_Connecting); + } ConnectionStatus newStatus = static_cast(m_walletImpl->connected()); if (newStatus != m_connectionStatus || !m_initialized) { m_initialized = true; - m_connectionStatus = newStatus; - qDebug() << "NEW STATUS " << newStatus; - emit connectionStatusChanged(newStatus); + setConnectionStatus(newStatus); } // Release lock m_connectionStatusRunning = false; @@ -178,6 +180,31 @@ Wallet::ConnectionStatus Wallet::connected(bool forceCheck) return m_connectionStatus; } +bool Wallet::disconnected() const +{ + return m_disconnected; +} + +void Wallet::setConnectionStatus(ConnectionStatus value) +{ + if (m_connectionStatus == value) + { + return; + } + + m_connectionStatus = value; + emit connectionStatusChanged(m_connectionStatus); + + bool disconnected = m_connectionStatus == Wallet::ConnectionStatus_Connecting || + m_connectionStatus == Wallet::ConnectionStatus_Disconnected; + + if (m_disconnected != disconnected) + { + m_disconnected = disconnected; + emit disconnectedChanged(); + } +} + bool Wallet::synchronized() const { return m_walletImpl->synchronized(); @@ -237,13 +264,7 @@ void Wallet::setDaemonLogin(const QString &daemonUsername, const QString &daemon void Wallet::initAsync(const QString &daemonAddress, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight) { qDebug() << "initAsync: " + daemonAddress; - // Change status to disconnected if connected - if(m_connectionStatus != Wallet::ConnectionStatus_Disconnected) { - m_connectionStatus = Wallet::ConnectionStatus_Disconnected; - emit connectionStatusChanged(m_connectionStatus); - } - - m_scheduler.run([this, daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight] { + const auto future = m_scheduler.run([this, daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight] { bool success = init(daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight); if (success) { @@ -253,6 +274,10 @@ void Wallet::initAsync(const QString &daemonAddress, bool trustedDaemon, quint64 m_walletImpl->startRefresh(); } }); + if (future.first) + { + setConnectionStatus(Wallet::ConnectionStatus_Connecting); + } } bool Wallet::isHwBacked() const @@ -985,7 +1010,9 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent) , m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS) , m_daemonBlockChainTargetHeight(0) , m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS) + , m_connectionStatus(Wallet::ConnectionStatus_Disconnected) , m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS) + , m_disconnected(true) , m_currentSubaddressAccount(0) , m_subaddress(nullptr) , m_subaddressModel(nullptr) @@ -999,7 +1026,6 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent) m_subaddressAccount = new SubaddressAccount(m_walletImpl->subaddressAccount(), this); m_walletListener = new WalletListenerImpl(this); m_walletImpl->setListener(m_walletListener); - m_connectionStatus = Wallet::ConnectionStatus_Disconnected; m_currentSubaddressAccount = getCacheAttribute(ATTRIBUTE_SUBADDRESS_ACCOUNT).toUInt(); // start cache timers m_connectionStatusTime.restart(); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index a6add1da..2646da30 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -60,6 +60,7 @@ class SubaddressAccountModel; class Wallet : public QObject { Q_OBJECT + Q_PROPERTY(bool disconnected READ disconnected NOTIFY disconnectedChanged) Q_PROPERTY(QString seed READ getSeed) Q_PROPERTY(QString seedLanguage READ getSeedLanguage) Q_PROPERTY(Status status READ status) @@ -100,7 +101,8 @@ public: enum ConnectionStatus { ConnectionStatus_Connected = Monero::Wallet::ConnectionStatus_Connected, ConnectionStatus_Disconnected = Monero::Wallet::ConnectionStatus_Disconnected, - ConnectionStatus_WrongVersion = Monero::Wallet::ConnectionStatus_WrongVersion + ConnectionStatus_WrongVersion = Monero::Wallet::ConnectionStatus_WrongVersion, + ConnectionStatus_Connecting }; Q_ENUM(ConnectionStatus) @@ -368,6 +370,7 @@ signals: void connectionStatusChanged(int status) const; void currentSubaddressAccountChanged() const; + void disconnectedChanged() const; private: Wallet(QObject * parent = nullptr); @@ -387,6 +390,9 @@ private: //! initializes wallet bool init(const QString &daemonAddress, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight); + bool disconnected() const; + void setConnectionStatus(ConnectionStatus value); + private: friend class WalletManager; friend class WalletListenerImpl; @@ -409,6 +415,7 @@ private: mutable ConnectionStatus m_connectionStatus; int m_connectionStatusTtl; mutable QTime m_connectionStatusTime; + bool m_disconnected; mutable bool m_initialized; uint32_t m_currentSubaddressAccount; Subaddress * m_subaddress;