diff --git a/CHANGELOG.md b/CHANGELOG.md index e3feaa607..ce5d9b761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,3 +14,4 @@ - Bugfix: Fixed message menu crashing if the message you right-clicked goes out of scope before you select an action (#1783) (#1787) - Settings open faster - Dev: Fully remove Twitch Chatroom support +- Dev: Handle conversion of historical CLEARCHAT messages to NOTICE messages in Chatterino instead of relying on the Recent Messages API to handle it for us. (#1804) diff --git a/docs/ENV.md b/docs/ENV.md index f95c74286..1ac52ea81 100644 --- a/docs/ENV.md +++ b/docs/ENV.md @@ -3,7 +3,7 @@ Below I have tried to list all environment variables that can be used to modify ### CHATTERINO2_RECENT_MESSAGES_URL Used to change the URL that Chatterino2 uses when trying to load historic Twitch chat messages (if the setting is enabled). -Default value: `https://recent-messages.robotty.de/api/v2/recent-messages/%1?clearchatToNotice=true` (an [open-source service](https://github.com/robotty/recent-messages) written and currently run by [@RAnders00](https://github.com/RAnders00)) +Default value: `https://recent-messages.robotty.de/api/v2/recent-messages/%1` (an [open-source service](https://github.com/robotty/recent-messages) written and currently run by [@RAnders00](https://github.com/RAnders00)) Arguments: - `%1` = Name of the Twitch channel diff --git a/src/common/Env.cpp b/src/common/Env.cpp index 1fa819c3d..724c8d92a 100644 --- a/src/common/Env.cpp +++ b/src/common/Env.cpp @@ -50,7 +50,7 @@ Env::Env() : recentMessagesApiUrl( readStringEnv("CHATTERINO2_RECENT_MESSAGES_URL", "https://recent-messages.robotty.de/api/v2/" - "recent-messages/%1?clearchatToNotice=true")) + "recent-messages/%1")) , linkResolverUrl(readStringEnv( "CHATTERINO2_LINK_RESOLVER_URL", "https://braize.pajlada.com/chatterino/link_resolver/%1")) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 8a9a42aba..6fe5b5acd 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -20,6 +20,7 @@ #include "singletons/Settings.hpp" #include "singletons/Toasts.hpp" #include "singletons/WindowManager.hpp" +#include "util/FormatTime.hpp" #include "util/PostToThread.hpp" #include "widgets/Window.hpp" @@ -36,6 +37,47 @@ namespace { constexpr int TITLE_REFRESH_PERIOD = 10; constexpr char MAGIC_MESSAGE_SUFFIX[] = u8" \U000E0000"; + // convertClearchatToNotice takes a Communi::IrcMessage that is a CLEARCHAT command and converts it to a readable NOTICE message + // This has historically been done in the Recent Messages API, but this functionality is being moved to Chatterino instead + auto convertClearchatToNotice(Communi::IrcMessage *message) + { + auto channelName = message->parameter(0); + QString noticeMessage{}; + if (message->tags().contains("target-user-id")) + { + auto target = message->parameter(1); + + if (message->tags().contains("ban-duration")) + { + // User was timed out + noticeMessage = + QString("%1 has been timed out for %2.") + .arg(target) + .arg(formatTime( + message->tag("ban-duration").toString())); + } + else + { + // User was permanently banned + noticeMessage = + QString("%1 has been permanently banned.").arg(target); + } + } + else + { + // Chat was cleared + noticeMessage = "Chat has been cleared by a moderator."; + } + + // rebuild the raw irc message so we can convert it back to an ircmessage again! + // this could probably be done in a smarter way + auto s = QString(":tmi.twitch.tv NOTICE %1 :%2") + .arg(channelName) + .arg(noticeMessage); + + return Communi::IrcMessage::fromData(s.toUtf8(), nullptr); + } + // parseRecentMessages takes a json object and returns a vector of // Communi IrcMessages auto parseRecentMessages(const QJsonObject &jsonRoot, ChannelPtr channel) @@ -49,8 +91,15 @@ namespace { for (const auto jsonMessage : jsonMessages) { auto content = jsonMessage.toString().toUtf8(); - messages.emplace_back( - Communi::IrcMessage::fromData(content, nullptr)); + + auto message = Communi::IrcMessage::fromData(content, nullptr); + + if (message->command() == "CLEARCHAT") + { + message = convertClearchatToNotice(message); + } + + messages.emplace_back(std::move(message)); } return messages; diff --git a/src/util/FormatTime.cpp b/src/util/FormatTime.cpp index 3f2b4f753..ba66031ba 100644 --- a/src/util/FormatTime.cpp +++ b/src/util/FormatTime.cpp @@ -50,4 +50,16 @@ QString formatTime(int totalSeconds) return res; } +QString formatTime(QString totalSecondsString) +{ + bool ok = true; + int totalSeconds(totalSecondsString.toInt(&ok)); + if (ok) + { + return formatTime(totalSeconds); + } + + return "n/a"; +} + } // namespace chatterino diff --git a/src/util/FormatTime.hpp b/src/util/FormatTime.hpp index fd5a2d582..0e4eb2725 100644 --- a/src/util/FormatTime.hpp +++ b/src/util/FormatTime.hpp @@ -6,5 +6,6 @@ namespace chatterino { // format: 1h 23m 42s QString formatTime(int totalSeconds); +QString formatTime(QString totalSecondsString); } // namespace chatterino