Browse Source

chatgui: live NTP-corrected clock (HH:mm:ss) on Status page with per-second sync

topo_upd
Evgeny 2 months ago
parent
commit
1b21ee9d73
  1. 2
      tools/chatgui/src/mainwindow.cpp
  2. 5
      tools/chatgui/src/settingsdialog.cpp
  3. 3
      tools/chatgui/src/settingsdialog.h
  4. 55
      tools/chatgui/src/statuspage.cpp
  5. 16
      tools/chatgui/src/statuspage.h
  6. 12
      tools/chatgui/transport/utun_node.cpp
  7. 4
      tools/chatgui/transport/utun_node.h

2
tools/chatgui/src/mainwindow.cpp

@ -338,7 +338,7 @@ void MainWindow::showJoinDialog() {
}
void MainWindow::showSettings() {
SettingsDialog dlg(m_cfgPath, m_db, this);
SettingsDialog dlg(m_cfgPath, m_db, m_node, this);
dlg.exec();
}

5
tools/chatgui/src/settingsdialog.cpp

@ -8,6 +8,7 @@
#include "../transport/gui_bridge.h"
#include "../../lib/mem.h"
#include "../db/db_manager.h"
#include "../transport/utun_node.h"
extern "C" {
#include "../transport/chat_core.h"
}
@ -20,7 +21,7 @@ extern "C" {
#include <QFile>
#include <QTextStream>
SettingsDialog::SettingsDialog(const QString& configPath, DbManager* db, QWidget* parent)
SettingsDialog::SettingsDialog(const QString& configPath, DbManager* db, UtunNode* node, QWidget* parent)
: QDialog(parent)
, m_configPath(configPath)
{
@ -79,7 +80,7 @@ SettingsDialog::SettingsDialog(const QString& configPath, DbManager* db, QWidget
m_pages->addWidget(m_databasePage);
// Status page
m_statusPage = new StatusPage(m_pages);
m_statusPage = new StatusPage(node, m_pages);
m_pages->addWidget(m_statusPage);
// Nodes page

3
tools/chatgui/src/settingsdialog.h

@ -14,11 +14,12 @@ class StatusPage;
class NodesPage;
class SoundSettingsPage;
class DbManager;
class UtunNode;
class SettingsDialog : public QDialog {
Q_OBJECT
public:
explicit SettingsDialog(const QString& configPath, DbManager* db, QWidget* parent = nullptr);
explicit SettingsDialog(const QString& configPath, DbManager* db, UtunNode* node, QWidget* parent = nullptr);
private slots:
void onCategoryChanged(int row);

55
tools/chatgui/src/statuspage.cpp

@ -1,5 +1,6 @@
// statuspage.cpp — Status page (NTP + connections) in settings
#include "statuspage.h"
#include "../transport/utun_node.h"
extern "C" {
#include "../transport/gui_bridge.h"
@ -10,6 +11,8 @@ extern "C" {
#include <QHBoxLayout>
#include <QLabel>
#include <QFont>
#include <QTimer>
#include <QDateTime>
static StatusPage* g_activeStatusPage = nullptr;
@ -18,13 +21,35 @@ static void statusRefreshCallback(const char* text, int len) {
g_activeStatusPage->setText(QString::fromUtf8(text, len));
}
StatusPage::StatusPage(QWidget* parent)
StatusPage::StatusPage(UtunNode* node, QWidget* parent)
: QWidget(parent)
, m_node(node)
{
auto* layout = new QVBoxLayout(this);
layout->setSpacing(8);
layout->setContentsMargins(0, 0, 0, 0);
/* ── clock block ── */
m_clockFrame = new QFrame(this);
m_clockFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
m_clockFrame->setStyleSheet(
"QFrame { border: 1px solid palette(mid); border-radius: 6px;"
" padding: 10px; background: palette(alternate-base); }");
auto* clockLayout = new QVBoxLayout(m_clockFrame);
clockLayout->setContentsMargins(12, 8, 12, 8);
m_clockLabel = new QLabel("--:--:--", m_clockFrame);
QFont clockFont("monospace", 22);
clockFont.setBold(true);
m_clockLabel->setFont(clockFont);
m_clockLabel->setAlignment(Qt::AlignCenter);
m_clockLabel->setStyleSheet("border: none; color: palette(text);");
clockLayout->addWidget(m_clockLabel);
layout->addWidget(m_clockFrame);
/* ── System Status section ── */
auto* title = new QLabel("System Status", this);
title->setStyleSheet("font-weight: bold; font-size: 13px;");
layout->addWidget(title);
@ -50,15 +75,43 @@ StatusPage::StatusPage(QWidget* parent)
btnLayout->addWidget(m_refreshBtn);
layout->addLayout(btnLayout);
m_clockTimer = new QTimer(this);
m_clockTimer->setSingleShot(true);
m_clockTimer->setTimerType(Qt::PreciseTimer);
connect(m_clockTimer, &QTimer::timeout, this, &StatusPage::updateClock);
g_activeStatusPage = this;
gui_bridge_set_status_refresh_cb(statusRefreshCallback);
}
StatusPage::~StatusPage() {
m_clockTimer->stop();
if (g_activeStatusPage == this) g_activeStatusPage = nullptr;
}
void StatusPage::updateClock() {
if (!m_node) return;
qint64 nowMs = QDateTime::currentMSecsSinceEpoch();
int64_t offsetUs = m_node->ntpOffsetUs();
bool synced = m_node->ntpSynced();
qint64 correctedMs = nowMs - (offsetUs / 1000);
QDateTime corrected = QDateTime::fromMSecsSinceEpoch(correctedMs).toLocalTime();
QString t = corrected.toString("HH:mm:ss");
if (synced)
m_clockLabel->setText(QString("%1 [NTP ✓]").arg(t));
else
m_clockLabel->setText(QString("%1 [LOCAL]").arg(t));
int msToNext = 1000 - (corrected.time().msec());
m_clockTimer->start(msToNext);
}
void StatusPage::refreshStatus() {
updateClock();
m_textEdit->setPlainText("Loading...");
gui_bridge_post_uasync_fn(chat_core_collect_status_trampoline, NULL);
}

16
tools/chatgui/src/statuspage.h

@ -1,14 +1,19 @@
// statuspage.h — Status page (NTP + connections) in settings
// statuspage.h — Status page (NTP + connections + live clock) in settings
#pragma once
#include <QWidget>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QLabel>
#include <QFrame>
#include <QTimer>
class UtunNode;
class StatusPage : public QWidget {
Q_OBJECT
public:
explicit StatusPage(QWidget* parent = nullptr);
explicit StatusPage(UtunNode* node, QWidget* parent = nullptr);
~StatusPage() override;
void refreshStatus();
void setText(const QString& text) { m_textEdit->setPlainText(text); }
@ -17,6 +22,13 @@ private slots:
void onRefreshClicked();
private:
void updateClock();
QPlainTextEdit* m_textEdit;
QPushButton* m_refreshBtn;
QLabel* m_clockLabel;
QFrame* m_clockFrame;
QTimer* m_clockTimer;
UtunNode* m_node;
};

12
tools/chatgui/transport/utun_node.cpp

@ -103,6 +103,18 @@ QString UtunNode::pubKeyHex() const {
return QString::fromLatin1(m_instance->config->global.my_public_key_hex, 64);
}
int64_t UtunNode::ntpOffsetUs() const {
return m_instance ? m_instance->ntp.offset_us : 0;
}
bool UtunNode::ntpSynced() const {
return m_instance ? m_instance->ntp.synced : false;
}
bool UtunNode::ntpEnabled() const {
return m_instance ? m_instance->ntp.enabled : false;
}
QList<NodeAddr> UtunNode::getInviteAddresses(DbManager* db) {
(void)db;
QList<NodeAddr> addrs;

4
tools/chatgui/transport/utun_node.h

@ -7,6 +7,7 @@
#include <QString>
#include <QList>
#include <atomic>
#include <cstdint>
#include <thread>
struct UTUN_INSTANCE;
@ -33,6 +34,9 @@ public:
QString nodeIdHex() const;
QString pubKeyHex() const;
QList<NodeAddr> getInviteAddresses(DbManager* db);
int64_t ntpOffsetUs() const;
bool ntpSynced() const;
bool ntpEnabled() const;
signals:
void started();

Loading…
Cancel
Save