From 8597bf7c31293d101331f7e5834b266f7fc4d527 Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 6 Feb 2026 14:38:52 -0800 Subject: [PATCH] feat: implement ping and particle data size in statusbar --- src/MainWindow.cpp | 66 +++++++++++++++++++++++++----------------- src/MainWindow.h | 1 - src/networkmanager.cpp | 31 ++++++++++++++++++++ src/networkmanager.h | 4 +++ 4 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index c38b24e..3746ed3 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -7,6 +7,7 @@ #include "authmanager.h" #include "createstreamdialog.h" #include "memberpickerdialog.h" +#include "networkmanager.h" #include "settingsdialog.h" #include "textinputdialog.h" #include "ui_mainwindow.h" @@ -18,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -81,11 +82,21 @@ MainWindow::MainWindow(QWidget *parent) m_storageLabel->setStyleSheet(statusBarLabelStyle); ui->statusbar->addPermanentWidget(m_storageLabel); - // Setup ping timer to oscillate every 500ms + // Setup ping timer for periodic server connectivity check m_pingTimer = new QTimer(this); - connect(m_pingTimer, &QTimer::timeout, this, &MainWindow::updatePingIndicator); - m_pingTimer->start(500); - updatePingIndicator(); + connect(m_pingTimer, &QTimer::timeout, this, []() { + NetworkManager::instance().ping(); + }); + connect(&NetworkManager::instance(), &NetworkManager::pingResult, this, [this](int ms) { + m_pingLabel->setText("connected " + QString::number(ms) + "ms"); + m_pingLabel->setStyleSheet("QLabel { color: #00AA00; }"); + }); + connect(&NetworkManager::instance(), &NetworkManager::pingFailed, this, [this]() { + m_pingLabel->setText("disconnected"); + m_pingLabel->setStyleSheet("QLabel { color: #AA0000; }"); + }); + m_pingTimer->start(10000); + NetworkManager::instance().ping(); ui->splitter->setStretchFactor(0, 1); ui->splitter->setStretchFactor(1, 4); @@ -417,10 +428,30 @@ void MainWindow::updateStatusBar() m_positionLabel->setText(""); } - // Update storage indicator with pseudo-random size based on stream ID - uint hash = qHash(m_selectedStreamId); - int sizeKB = 50 + (hash % 950); // Random size between 50-1000 kB - m_storageLabel->setText(QString::number(sizeKB) + " kB"); + // Update data size indicator for selected particle + if (!m_selectedParticleId.isEmpty()) + { + const Particle *particle = m_store->particleById(m_selectedParticleId); + if (particle) + { + QJsonObject dataObj; + for (auto it = particle->data.constBegin(); it != particle->data.constEnd(); ++it) + dataObj.insert(it.key(), QJsonValue::fromVariant(it.value())); + int bytes = QJsonDocument(dataObj).toJson(QJsonDocument::Compact).size(); + if (bytes < 1024) + m_storageLabel->setText(QString::number(bytes) + " B"); + else + m_storageLabel->setText(QString::number(bytes / 1024) + " kB"); + } + else + { + m_storageLabel->setText(""); + } + } + else + { + m_storageLabel->setText(""); + } } else { @@ -429,23 +460,6 @@ void MainWindow::updateStatusBar() } } -void MainWindow::updatePingIndicator() -{ - // Oscillate ping between 15-35ms - static int basePing = 23; - int variation = (QRandomGenerator::global()->bounded(21)) - 10; // -10 to +10 - int currentPing = basePing + variation; - if (currentPing < 15) - { - currentPing = 15; - } - if (currentPing > 35) - { - currentPing = 35; - } - - m_pingLabel->setText("connected " + QString::number(currentPing) + "ms"); -} void MainWindow::showTextInputDialog() { diff --git a/src/MainWindow.h b/src/MainWindow.h index 4dff0d6..7e0f506 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -73,7 +73,6 @@ private: void showTextInputDialog(); void updateStatusBar(); - void updatePingIndicator(); QString m_selectedParticleId; QString m_selectedNetworkName; QString m_selectedStreamId; diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp index 7924ce3..a7245da 100644 --- a/src/networkmanager.cpp +++ b/src/networkmanager.cpp @@ -1,4 +1,5 @@ #include "networkmanager.h" +#include #include #include #include @@ -107,3 +108,33 @@ void NetworkManager::setSessionToken(const QString &newToken) { m_sessionToken = newToken; } + +class PingTimer : public QObject +{ +public: + QElapsedTimer timer; + explicit PingTimer(QObject *parent = nullptr) : QObject(parent) { timer.start(); } +}; + +void NetworkManager::ping() +{ + auto *pingTimer = new PingTimer(this); + + QNetworkRequest request(getFullUrl("")); + QNetworkReply *reply = m_qnam->get(request); + + connect(reply, &QNetworkReply::finished, pingTimer, [this, pingTimer, reply]() { + int elapsed = static_cast(pingTimer->timer.elapsed()); + pingTimer->deleteLater(); + + int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if (statusCode > 0) + { + emit pingResult(elapsed); + } + else + { + emit pingFailed(); + } + }); +} diff --git a/src/networkmanager.h b/src/networkmanager.h index 40b622c..b80ce82 100644 --- a/src/networkmanager.h +++ b/src/networkmanager.h @@ -32,12 +32,16 @@ public slots: QNetworkReply *del(const QString &path); QNetworkReply *del(const QString &path, const QJsonDocument &data); + void ping(); + /// @brief sets session token which will is injected into every request's headers void setSessionToken(const QString &token); signals: /// @brief Emitted when a request is made and fails required authentication. void unauthorizedDetected(); + void pingResult(int ms); + void pingFailed(); private: NetworkManager();