From: gg Date: Thu, 15 Jan 2026 05:45:28 +0000 (-0500) Subject: status/balance and HW backed wallet fixes X-Git-Url: https://git.nutra.tk/v2?a=commitdiff_plain;h=e868e5edc3af4ff067811ad1760a5b5b2573991e;p=gamesguru%2Ffeather.git status/balance and HW backed wallet fixes --- diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 4ea0a9a4..a1323e7e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -766,6 +766,16 @@ void MainWindow::onWalletOpened() { connect(m_wallet->coins(), &Coins::descriptionChanged, [this] { m_wallet->history()->refresh(); }); + + connect(m_wallet->coins(), &Coins::refreshStarted, [this]{ + m_coinsRefreshing = true; + this->updateNetStats(); + }); + + connect(m_wallet->coins(), &Coins::refreshFinished, [this]{ + m_coinsRefreshing = false; + this->updateNetStats(); + }); // Vice versa connect(m_wallet->transactionHistoryModel(), &TransactionHistoryModel::transactionDescriptionChanged, [this] { m_wallet->coins()->refresh(); @@ -854,6 +864,18 @@ void MainWindow::updateStatusToolTip() { if (m_wallet && m_wallet->lastSyncTime().isValid()) { toolTip += QString("\nWallet synced: %1").arg(Utils::timeAgo(m_wallet->lastSyncTime())); } + + if (m_wallet) { + qint64 nextRefresh = m_wallet->secondsUntilNextRefresh(); + if (nextRefresh > 0) { + toolTip += QString("\nNext sync attempt in: %1s").arg(nextRefresh); + } else if (nextRefresh == 0) { + toolTip += "\nSync attempt in progress..."; + } else if (nextRefresh == -2) { + toolTip += "\nHardware wallet disconnected"; + } + } + m_statusLabelBalance->setToolTip(toolTip); this->updateSyncStatusToolTip(); @@ -888,7 +910,9 @@ void MainWindow::updateSyncStatusToolTip() { if (lastSync.isValid()) { qint64 secsSinceSync = lastSync.secsTo(QDateTime::currentDateTime()); - blocksBehindEstimated = secsSinceSync / 120; // ~2 min per block + if (secsSinceSync > 0) { + blocksBehindEstimated = secsSinceSync / 120; // ~2 min per block + } } quint64 blocksBehind = std::max(blocksBehindActual, blocksBehindEstimated); @@ -1079,10 +1103,12 @@ void MainWindow::onConnectionStatusChanged(int status) // Estimate blocks behind based on time since last sync if (m_wallet && m_wallet->lastSyncTime().isValid()) { qint64 secsSinceLastSync = m_wallet->lastSyncTime().secsTo(QDateTime::currentDateTime()); - quint64 estimatedBlocksBehind = secsSinceLastSync / 120; // ~2 min per block - if (estimatedBlocksBehind > 0) { - statusStr = tr("~%1 blocks behind").arg(QLocale().toString(estimatedBlocksBehind)); - break; + if (secsSinceLastSync > 0) { + quint64 estimatedBlocksBehind = secsSinceLastSync / 120; // ~2 min per block + if (estimatedBlocksBehind > 0) { + statusStr = tr("~%1 blocks behind").arg(QLocale().toString(estimatedBlocksBehind)); + break; + } } } statusStr = "Disconnected"; @@ -1897,7 +1923,7 @@ void MainWindow::onWalletPassphraseNeeded(bool on_device) { void MainWindow::updateNetStats() { if (!m_wallet || m_wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected - || m_wallet->connectionStatus() == Wallet::ConnectionStatus_Synchronized) + || (m_wallet->connectionStatus() == Wallet::ConnectionStatus_Synchronized && !m_coinsRefreshing)) { m_statusLabelNetStats->hide(); return; diff --git a/src/MainWindow.h b/src/MainWindow.h index f161ff05..4df66991 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -263,6 +263,7 @@ private: QString m_statusText; int m_statusDots; + bool m_coinsRefreshing = false; bool m_constructingTransaction = false; bool m_statusOverrideActive = false; bool m_showDeviceError = false; diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index dd6bea50..fa25f1ac 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -178,6 +178,14 @@ void Settings::setupNetworkTab() { // Proxy connect(ui->proxyWidget, &NetworkProxyWidget::proxySettingsChanged, this, &Settings::onProxySettingsChanged); + // Offline mode + ui->checkBox_offlineMode->setChecked(conf()->get(Config::offlineMode).toBool()); + connect(ui->checkBox_offlineMode, &QCheckBox::toggled, [this](bool checked){ + conf()->set(Config::offlineMode, checked); + this->enableWebsocket(!checked && !conf()->get(Config::disableWebsocket).toBool()); + emit offlineMode(checked); + }); + // Websocket // [Obtain third-party data] ui->checkBox_enableWebsocket->setChecked(!conf()->get(Config::disableWebsocket).toBool()); diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 9dc59e5a..6a171476 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -55,6 +55,7 @@ Wallet::Wallet(Monero::Wallet *wallet, QObject *parent) , m_useSSL(true) , m_coins(new Coins(this, wallet->getWallet(), this)) , m_storeTimer(new QTimer(this)) + , m_lastRefreshTime(std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count()) { m_walletListener = new WalletListenerImpl(this); m_walletImpl->setListener(m_walletListener); @@ -541,6 +542,7 @@ void Wallet::startRefreshThread() qInfo() << "Calling m_walletImpl->refresh(). Wallet height:" << walletHeight << "Daemon height:" << daemonHeight << "Target:" << targetHeight; m_walletImpl->refresh(); } + m_lastRefreshTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); last = std::chrono::steady_clock::now(); } } @@ -586,6 +588,26 @@ quint64 Wallet::blockChainHeight() const { return m_wallet2->get_blockchain_current_height(); } +qint64 Wallet::secondsUntilNextRefresh() const { + if (m_syncPaused || !m_refreshEnabled) { + return -1; + } + + if (this->isHwBacked() && !this->isDeviceConnected()) { + return -2; + } + + auto now = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); + auto elapsed = std::chrono::microseconds(now - m_lastRefreshTime.load()); + auto interval = std::chrono::seconds(m_refreshInterval); + + if (elapsed >= interval) { + return 0; + } + + return std::chrono::duration_cast(interval - elapsed).count(); +} + quint64 Wallet::daemonBlockChainHeight() const { return m_daemonBlockChainHeight; } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index c37cc5d7..366dd885 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -15,6 +15,7 @@ #include "rows/TxBacklogEntry.h" #include +#include class WalletListenerImpl; @@ -140,6 +141,7 @@ public: QDateTime lastSyncTime() const; void setRefreshInterval(int seconds); + qint64 secondsUntilNextRefresh() const; //! return true if deterministic keys bool isDeterministic() const; @@ -520,7 +522,7 @@ private: Coins *m_coins; CoinsModel *m_coinsModel; - int m_refreshInterval = 10; + std::atomic m_refreshInterval{10}; QMutex m_asyncMutex; QString m_daemonUsername; @@ -542,6 +544,7 @@ private: std::atomic m_stopHeight{0}; std::atomic m_rangeSyncActive{false}; std::atomic m_syncPaused{false}; + std::atomic m_lastRefreshTime{0}; }; #endif // FEATHER_WALLET_H diff --git a/src/widgets/TickerWidget.cpp b/src/widgets/TickerWidget.cpp index 2276c1a4..11403b66 100644 --- a/src/widgets/TickerWidget.cpp +++ b/src/widgets/TickerWidget.cpp @@ -66,14 +66,16 @@ BalanceTickerWidget::BalanceTickerWidget(QWidget *parent, Wallet *wallet, bool t this->setPercentageVisible(false); connect(m_wallet, &Wallet::balanceUpdated, this, &BalanceTickerWidget::updateDisplay); + connect(m_wallet, &Wallet::connectionStatusChanged, this, &BalanceTickerWidget::updateDisplay); connect(&appData()->prices, &Prices::fiatPricesUpdated, this, &BalanceTickerWidget::updateDisplay); connect(&appData()->prices, &Prices::cryptoPricesUpdated, this, &BalanceTickerWidget::updateDisplay); } void BalanceTickerWidget::updateDisplay() { - double balance = (m_totalBalance ? m_wallet->balanceAll() : m_wallet->balance()) / constants::cdiv; + double balance = (m_totalBalance ? m_wallet->balanceAll() : m_wallet->balance()); + double balanceAmount = balance / constants::cdiv; QString fiatCurrency = conf()->get(Config::preferredFiatCurrency).toString(); - double balanceFiatAmount = appData()->prices.convert("XMR", fiatCurrency, balance); + double balanceFiatAmount = appData()->prices.convert("XMR", fiatCurrency, balanceAmount); bool isCacheValid = appData()->prices.lastUpdateTime.isValid(); bool isCacheFresh = isCacheValid && appData()->prices.lastUpdateTime.secsTo(QDateTime::currentDateTime()) < 3600; @@ -81,7 +83,7 @@ void BalanceTickerWidget::updateDisplay() { bool hasXmrPrice = appData()->prices.markets.contains("XMR"); bool hasFiatRate = fiatCurrency == "USD" || appData()->prices.rates.contains(fiatCurrency); - if (balanceFiatAmount == 0.0 || !isCacheValid) { + if (balance > 0 && (balanceFiatAmount == 0.0 || !isCacheValid)) { if (conf()->get(Config::offlineMode).toBool() || conf()->get(Config::disableWebsocket).toBool() || m_wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected) { this->setDisplayText("offline"); } else if (!hasXmrPrice || !hasFiatRate) {