From: gg Date: Tue, 13 Jan 2026 08:21:40 +0000 (-0500) Subject: wip X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=07f405a3d4ccdaaf0ac237f5b794b605e3622b6b;p=gamesguru%2Ffeather.git wip --- diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index af5a9834..7fbddf40 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -97,4 +97,4 @@ jobs: run: cmake --build build - name: Validate Version - run: ./build/bin/feather --version + run: ./build/bin/feather --version | grep "Feather Wallet" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9031e144..1dcfc990 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -369,6 +369,14 @@ else() if (UNIX AND NOT APPLE) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/feather.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/32x32.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/48x48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/64x64.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/64x64/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/96x96.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/96x96/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/128x128.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/256x256.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/512x512.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/512x512/apps RENAME "feather.png") + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/32x32.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME "FeatherWallet.png") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/48x48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME "FeatherWallet.png") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/images/appicons/64x64.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/64x64/apps RENAME "FeatherWallet.png") diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 1b5a0d89..ee26762f 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -157,17 +158,24 @@ void MainWindow::initStatusBar() { m_statusUpdateAvailable->hide(); this->statusBar()->addPermanentWidget(m_statusUpdateAvailable); + QWidget *balanceContainer = new QWidget(this); + QHBoxLayout *balanceLayout = new QHBoxLayout(balanceContainer); + balanceLayout->setContentsMargins(0, 0, 0, 0); + balanceLayout->setSpacing(0); + QLabel *balancePrefix = new QLabel("Balance:", this); - this->statusBar()->addPermanentWidget(balancePrefix); + balanceLayout->addWidget(balancePrefix); m_statusLabelBalance = new QLabel(this); m_statusLabelBalance->setText("0"); m_statusLabelBalance->setTextInteractionFlags(Qt::TextSelectableByMouse); m_statusLabelBalance->setContextMenuPolicy(Qt::ActionsContextMenu); - this->statusBar()->addPermanentWidget(m_statusLabelBalance); + balanceLayout->addWidget(m_statusLabelBalance); m_statusLabelBalanceSuffix = new QLabel("XMR", this); - this->statusBar()->addPermanentWidget(m_statusLabelBalanceSuffix); + balanceLayout->addWidget(m_statusLabelBalanceSuffix); + + this->statusBar()->addPermanentWidget(balanceContainer); QAction *copyBalanceAction = new QAction(tr("Copy"), this); connect(copyBalanceAction, &QAction::triggered, this, [this](){ @@ -910,10 +918,10 @@ void MainWindow::onBalanceUpdated(quint64 balance, quint64 spendable) { if (conf()->get(Config::balanceShowFiat).toBool() && !hide) { QString fiatCurrency = conf()->get(Config::preferredFiatCurrency).toString(); double balanceFiatAmount = appData()->prices.convert("XMR", fiatCurrency, balance / constants::cdiv); - bool isCacheFresh = appData()->prices.lastUpdateTime.isValid() && - appData()->prices.lastUpdateTime.secsTo(QDateTime::currentDateTime()) < 3600; + bool isCacheValid = appData()->prices.lastUpdateTime.isValid(); + bool isCacheFresh = isCacheValid && appData()->prices.lastUpdateTime.secsTo(QDateTime::currentDateTime()) < 3; // TODO: 3600 - if (balance > 0 && (balanceFiatAmount == 0.0 || !isCacheFresh)) { + if (balance > 0 && (balanceFiatAmount == 0.0 || !isCacheValid)) { if (conf()->get(Config::offlineMode).toBool() || m_wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected) { suffixStr += " (offline)"; } else if (!appData()->prices.markets.contains("XMR")) { @@ -922,12 +930,18 @@ void MainWindow::onBalanceUpdated(quint64 balance, quint64 spendable) { suffixStr += " (unknown)"; } } else { - suffixStr += QString(" (%1)").arg(Utils::amountToCurrencyString(balanceFiatAmount, fiatCurrency)); + QString approx = isCacheFresh ? "" : "~ "; + suffixStr += QString(" (%1%2)").arg(approx, Utils::amountToCurrencyString(balanceFiatAmount, fiatCurrency)); } } - m_statusLabelBalance->setToolTip("Click for details"); + QString toolTip = "Click for details"; + if (appData()->prices.lastUpdateTime.isValid()) { + toolTip += QString("\nLast updated: %1").arg(Utils::timeAgo(appData()->prices.lastUpdateTime)); + } + m_statusLabelBalance->setToolTip(toolTip); m_statusLabelBalance->setText(valueStr); + m_statusLabelBalanceSuffix->setToolTip(toolTip); m_statusLabelBalanceSuffix->setText(suffixStr); } diff --git a/src/WindowManager.cpp b/src/WindowManager.cpp index b15cd315..2417e61f 100644 --- a/src/WindowManager.cpp +++ b/src/WindowManager.cpp @@ -51,7 +51,7 @@ WindowManager::WindowManager(QObject *parent) if (reason == QSystemTrayIcon::Trigger) { if (conf()->get(Config::trayLeftClickTogglesFocus).toBool()) { for (const auto &window : m_windows) { - if (window->isVisible()) { + if (window->isVisible() && window->isActiveWindow()) { window->hide(); } else { window->show(); @@ -737,7 +737,7 @@ void WindowManager::onProxySettingsChanged() { getNetworkSocks5()->setProxy(proxy); } - qInfo() << "Proxy: " << proxy.hostName() << " " << proxy.port(); + qDebug() << "Proxy: " << proxy.hostName() << " " << proxy.port(); // Switch websocket to new proxy and update URL websocketNotifier()->websocketClient->stop(); diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index 323c4dda..12f05c5a 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -619,6 +619,32 @@ QFont relativeFont(int delta) { return font; } +QString timeAgo(const QDateTime &dt) { + qint64 diff = dt.secsTo(QDateTime::currentDateTime()); + + if (diff < 0) return "in the future"; + if (diff < 60) return QString("%1 second%2 ago").arg(diff).arg(diff == 1 ? "" : "s"); + + diff /= 60; // minutes + if (diff < 60) return QString("%1 minute%2 ago").arg(diff).arg(diff == 1 ? "" : "s"); + + qint64 minutes = diff % 60; + diff /= 60; // hours + if (diff < 24) { + if (minutes > 0) + return QString("%1 hour%2 %3 minute%4 ago").arg(diff).arg(diff == 1 ? "" : "s").arg(minutes).arg(minutes == 1 ? "" : "s"); + return QString("%1 hour%2 ago").arg(diff).arg(diff == 1 ? "" : "s"); + } + + diff /= 24; // days + if (diff < 30) return QString("%1 day%2 ago").arg(diff).arg(diff == 1 ? "" : "s"); + + diff /= 30; // months (approx) + if (diff < 12) return QString("%1 month%2 ago").arg(diff).arg(diff == 1 ? "" : "s"); + + return QString("%1 year%2 ago").arg(diff / 12).arg((diff / 12) == 1 ? "" : "s"); +} + bool isLocalUrl(const QUrl &url) { QRegularExpression localNetwork(R"((^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.))"); return (localNetwork.match(url.host()).hasMatch() || url.host() == "localhost"); diff --git a/src/utils/Utils.h b/src/utils/Utils.h index 3a750aa9..ae2467df 100644 --- a/src/utils/Utils.h +++ b/src/utils/Utils.h @@ -98,6 +98,7 @@ namespace Utils QFont getMonospaceFont(); QFont relativeFont(int delta); + QString timeAgo(const QDateTime &dt); void applicationLogHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); QString barrayToString(const QByteArray &data); diff --git a/src/widgets/TickerWidget.cpp b/src/widgets/TickerWidget.cpp index 75b5cfe6..f6f525ab 100644 --- a/src/widgets/TickerWidget.cpp +++ b/src/widgets/TickerWidget.cpp @@ -74,9 +74,22 @@ void BalanceTickerWidget::updateDisplay() { double balance = (m_totalBalance ? m_wallet->balanceAll() : m_wallet->balance()) / constants::cdiv; QString fiatCurrency = conf()->get(Config::preferredFiatCurrency).toString(); double balanceFiatAmount = appData()->prices.convert("XMR", fiatCurrency, balance); - if (balanceFiatAmount < 0) - return; - this->setFiatText(balanceFiatAmount, fiatCurrency); + + bool isCacheValid = appData()->prices.lastUpdateTime.isValid(); + bool isCacheFresh = isCacheValid && appData()->prices.lastUpdateTime.secsTo(QDateTime::currentDateTime()) < 3600; + + if (balanceFiatAmount == 0.0 || !isCacheValid) { + if (conf()->get(Config::offlineMode).toBool() || m_wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected) { + this->setDisplayText("offline"); + } else if (!appData()->prices.markets.contains("XMR")) { + this->setDisplayText("connecting"); + } else { + this->setDisplayText("unknown"); + } + } else { + QString approx = isCacheFresh ? "" : "~ "; + this->setDisplayText(approx + Utils::amountToCurrencyString(balanceFiatAmount, fiatCurrency)); + } } // PriceTickerWidget