From 1423f548a7e9ea870c644f2a31e736c2b9199c6f Mon Sep 17 00:00:00 2001 From: droidicus Date: Sun, 27 Jul 2025 06:11:13 -0400 Subject: [PATCH] Add option to use server timestamp from the message instead of the local clock time for logging. (#6346) --- CHANGELOG.md | 1 + src/singletons/Settings.hpp | 4 ++++ src/singletons/helper/LoggingChannel.cpp | 15 ++++++++++++--- src/widgets/settingspages/ModerationPage.cpp | 13 +++++++++++++ src/widgets/settingspages/SettingWidget.cpp | 11 +++++++++++ src/widgets/settingspages/SettingWidget.hpp | 4 ++++ 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f63c2bf..95f4f6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Minor: Add a setting to change the emote and badge thumbnail size. (#6126) - Minor: Add an import and export button to image uploader settings. (#6284) - Minor: Add a setting under Moderation -> Logs to customize the timestamp used for chat logs. (#6338) +- Minor: Add a setting under Moderation -> Logs to use server timestamp from the message instead of the local clock time for logging. (#6346) - Bugfix: Commands are no longer tab-completable in the middle of messages. (#6273) - Bugfix: Automatic streamer mode detection now works from Flatpak. (#6250) - Bugfix: Don't create native messaging manifest file if browser directory doesn't exist. (#6116) diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index eddd4981..79f39596 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -571,6 +571,10 @@ public: "/logging/logTimestampFormat", "hh:mm:ss", }; + BoolSetting tryUseTwitchTimestamps = { + "/logging/tryUseTwitchTimestamps", + false, + }; QStringSetting logPath = {"/logging/path", ""}; QStringSetting pathHighlightSound = {"/highlighting/highlightSoundPath", diff --git a/src/singletons/helper/LoggingChannel.cpp b/src/singletons/helper/LoggingChannel.cpp index eb012361..58ecf686 100644 --- a/src/singletons/helper/LoggingChannel.cpp +++ b/src/singletons/helper/LoggingChannel.cpp @@ -166,9 +166,18 @@ void LoggingChannel::openStreamLogFile(const QString &streamID) void LoggingChannel::addMessage(const MessagePtr &message, const QString &streamID) { - QDateTime now = QDateTime::currentDateTime(); + QDateTime messageTimestamp; + if (getSettings()->tryUseTwitchTimestamps && + !message->serverReceivedTime.isNull()) + { + messageTimestamp = message->serverReceivedTime; + } + else + { + messageTimestamp = QDateTime::currentDateTime(); + } - QString messageDateString = generateDateString(now); + QString messageDateString = generateDateString(messageTimestamp); if (messageDateString != this->dateString) { this->dateString = messageDateString; @@ -186,7 +195,7 @@ void LoggingChannel::addMessage(const MessagePtr &message, if (logTimestampFormat != "Disable") { str.append('['); - str.append(now.toString(logTimestampFormat)); + str.append(messageTimestamp.toString(logTimestampFormat)); str.append("] "); } diff --git a/src/widgets/settingspages/ModerationPage.cpp b/src/widgets/settingspages/ModerationPage.cpp index 4f5482a2..cd57fb4d 100644 --- a/src/widgets/settingspages/ModerationPage.cpp +++ b/src/widgets/settingspages/ModerationPage.cpp @@ -13,6 +13,7 @@ #include "util/PostToThread.hpp" #include "widgets/helper/EditableModelView.hpp" #include "widgets/helper/IconDelegate.hpp" +#include "widgets/settingspages/SettingWidget.hpp" #include #include @@ -165,6 +166,18 @@ ModerationPage::ModerationPage() logTimestampFormat->setToolTip("a = am/pm, zzz = milliseconds"); logsTimestampFormatLayout.append(logTimestampFormat); + SettingWidget::checkbox("Use Twitch's timestamps", + getSettings()->tryUseTwitchTimestamps) + ->setTooltip( + "Try to use Twitch's timestamp (the time when the message was " + "received by Twitch's chat server), rather than your " + "computer's local timestamp.\nNote that using this setting can " + "result in out-of-order timestamps in the log files, and that " + "if Twitch's timestamp was unavailable for a message, it will " + "fall back to your computer's local timestamp.") + ->conditionallyEnabledBy(getSettings()->enableLogging) + ->addToLayout(logs->layout()); + QCheckBox *onlyLogListedChannels = this->createCheckBox("Only log channels listed below", getSettings()->onlyLogListedChannels); diff --git a/src/widgets/settingspages/SettingWidget.cpp b/src/widgets/settingspages/SettingWidget.cpp index 451fd165..320a410b 100644 --- a/src/widgets/settingspages/SettingWidget.cpp +++ b/src/widgets/settingspages/SettingWidget.cpp @@ -590,6 +590,17 @@ void SettingWidget::addTo(GeneralPageView &view, QFormLayout *formLayout) formLayout->addRow(this->label, this->actionWidget); } +void SettingWidget::addToLayout(QLayout *layout) +{ + if (this->label == this->actionWidget) + { + layout->addWidget(this->actionWidget); + return; + } + + assert(false && "unimplemented"); +} + void SettingWidget::registerWidget(GeneralPageView &view) { if (this->label != nullptr) diff --git a/src/widgets/settingspages/SettingWidget.hpp b/src/widgets/settingspages/SettingWidget.hpp index 67196dbe..6ad165e1 100644 --- a/src/widgets/settingspages/SettingWidget.hpp +++ b/src/widgets/settingspages/SettingWidget.hpp @@ -20,6 +20,7 @@ #include class QFormLayout; +class QLayout; namespace chatterino { @@ -121,6 +122,9 @@ public: void addTo(GeneralPageView &view); void addTo(GeneralPageView &view, QFormLayout *formLayout); + /// For settings pages without a page view + void addToLayout(QLayout *layout); + private: /// Registers this widget & its optional label to the given page view void registerWidget(GeneralPageView &view);