diff --git a/src/application.cpp b/src/application.cpp index 53746ff23..5d1bb688e 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -182,8 +182,9 @@ void Application::initialize() } auto msg = messages::Message::createTimeoutMessage(action); + msg->flags |= messages::Message::PubSub; - util::postToThread([chan, msg] { chan->addMessage(msg); }); + util::postToThread([chan, msg] { chan->addOrReplaceTimeout(msg); }); }); this->twitch.pubsub->sig.moderation.userUnbanned.connect([&](const auto &action) { diff --git a/src/channel.cpp b/src/channel.cpp index 2b7187970..2e340665b 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -60,57 +60,14 @@ void Channel::addMessage(MessagePtr message) auto app = getApp(); MessagePtr deleted; - bool isTimeout = (message->flags & Message::Timeout) != 0; - - if (!isTimeout) { - const QString &username = message->loginName; - if (!username.isEmpty()) { - // TODO: Add recent chatters display name. This should maybe be a setting - this->addRecentChatter(message); - } + const QString &username = message->loginName; + if (!username.isEmpty()) { + // TODO: Add recent chatters display name. This should maybe be a setting + this->addRecentChatter(message); } app->logging->addMessage(this->name, message); - if (isTimeout) { - LimitedQueueSnapshot snapshot = this->getMessageSnapshot(); - bool addMessage = true; - int snapshotLength = snapshot.getLength(); - - int end = std::max(0, snapshotLength - 20); - - for (int i = snapshotLength - 1; i >= end; --i) { - auto &s = snapshot[i]; - if (s->flags.HasFlag(Message::Untimeout) && s->timeoutUser == message->timeoutUser) { - break; - } - - if (s->flags.HasFlag(Message::Timeout) && s->timeoutUser == message->timeoutUser) { - assert(message->banAction != nullptr); - MessagePtr replacement( - Message::createTimeoutMessage(*(message->banAction), s->count + 1)); - this->replaceMessage(s, replacement); - addMessage = false; - } - } - - // disable the messages from the user - for (int i = 0; i < snapshotLength; i++) { - auto &s = snapshot[i]; - if ((s->flags & (Message::Timeout | Message::Untimeout)) == 0 && - s->loginName == message->timeoutUser) { - s->flags.EnableFlag(Message::Disabled); - } - } - - // XXX: Might need the following line - // WindowManager::getInstance().repaintVisibleChatWidgets(this); - - if (!addMessage) { - return; - } - } - if (this->messages.pushBack(message, deleted)) { this->messageRemovedFromStart.invoke(deleted); } @@ -118,6 +75,73 @@ void Channel::addMessage(MessagePtr message) this->messageAppended.invoke(message); } +void Channel::addOrReplaceTimeout(messages::MessagePtr message) +{ + LimitedQueueSnapshot snapshot = this->getMessageSnapshot(); + int snapshotLength = snapshot.getLength(); + + int end = std::max(0, snapshotLength - 20); + + bool addMessage = true; + + QTime minimumTime = QTime::currentTime().addSecs(-5); + + for (int i = snapshotLength - 1; i >= end; --i) { + auto &s = snapshot[i]; + + qDebug() << s->parseTime << minimumTime; + + if (s->parseTime < minimumTime) { + break; + } + + if (s->flags.HasFlag(Message::Untimeout) && s->timeoutUser == message->timeoutUser) { + break; + } + + if (s->flags.HasFlag(Message::Timeout) && s->timeoutUser == message->timeoutUser) { + if (message->flags.HasFlag(Message::PubSub) && !s->flags.HasFlag(Message::PubSub)) { + this->replaceMessage(s, message); + addMessage = false; + break; + } + if (!message->flags.HasFlag(Message::PubSub) && s->flags.HasFlag(Message::PubSub)) { + addMessage = false; + break; + } + + int count = s->count + 1; + + messages::MessagePtr replacement(Message::createSystemMessage( + message->searchText + QString("(") + QString::number(count) + " times)")); + + replacement->timeoutUser = message->timeoutUser; + replacement->count = count; + replacement->flags = message->flags; + + this->replaceMessage(s, replacement); + + return; + } + } + + // disable the messages from the user + for (int i = 0; i < snapshotLength; i++) { + auto &s = snapshot[i]; + if ((s->flags & (Message::Timeout | Message::Untimeout)) == 0 && + s->loginName == message->timeoutUser) { + s->flags.EnableFlag(Message::Disabled); + } + } + + if (addMessage) { + this->addMessage(message); + } + + // XXX: Might need the following line + // WindowManager::getInstance().repaintVisibleChatWidgets(this); +} + void Channel::addMessagesAtStart(std::vector &_messages) { std::vector addedMessages = this->messages.pushFront(_messages); diff --git a/src/channel.hpp b/src/channel.hpp index 6a2433f6a..91d2ad4fe 100644 --- a/src/channel.hpp +++ b/src/channel.hpp @@ -48,6 +48,7 @@ public: void addMessage(messages::MessagePtr message); void addMessagesAtStart(std::vector &messages); + void addOrReplaceTimeout(messages::MessagePtr message); void replaceMessage(messages::MessagePtr message, messages::MessagePtr replacement); virtual void addRecentChatter(const std::shared_ptr &message); diff --git a/src/messages/message.cpp b/src/messages/message.cpp index 38ea08376..4b0e9f3cc 100644 --- a/src/messages/message.cpp +++ b/src/messages/message.cpp @@ -89,7 +89,6 @@ MessagePtr Message::createTimeoutMessage(const providers::twitch::BanAction &act msg->timeoutUser = action.target.name; msg->count = count; - msg->banAction.reset(new providers::twitch::BanAction(action)); QString text; diff --git a/src/messages/message.hpp b/src/messages/message.hpp index d3f813677..5465ac960 100644 --- a/src/messages/message.hpp +++ b/src/messages/message.hpp @@ -18,6 +18,7 @@ namespace messages { struct Message { Message() + : parseTime(QTime::currentTime()) { util::DebugCount::increase("messages"); } @@ -39,6 +40,7 @@ struct Message { Collapsed = (1 << 7), DisconnectedMessage = (1 << 8), Untimeout = (1 << 9), + PubSub = (1 << 10), }; util::FlagsEnum flags; @@ -50,7 +52,6 @@ struct Message { QString localizedName; QString timeoutUser; - std::unique_ptr banAction; uint32_t count = 1; // Messages should not be added after the message is done initializing. diff --git a/src/providers/twitch/ircmessagehandler.cpp b/src/providers/twitch/ircmessagehandler.cpp index 7111a0f59..3d199e979 100644 --- a/src/providers/twitch/ircmessagehandler.cpp +++ b/src/providers/twitch/ircmessagehandler.cpp @@ -60,80 +60,52 @@ void IrcMessageHandler::handleRoomStateMessage(Communi::IrcMessage *message) void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message) { - return; - // // check parameter count - // if (message->parameters().length() < 1) { - // return; - // } + // check parameter count + if (message->parameters().length() < 1) { + return; + } - // QString chanName; - // if (!TrimChannelName(message->parameter(0), chanName)) { - // return; - // } + QString chanName; + if (!TrimChannelName(message->parameter(0), chanName)) { + return; + } - // auto app = getApp(); + auto app = getApp(); - // // get channel - // auto chan = app->twitch.server->getChannelOrEmpty(chanName); + // get channel + auto chan = app->twitch.server->getChannelOrEmpty(chanName); - // if (chan->isEmpty()) { - // debug::Log("[IrcMessageHandler:handleClearChatMessage] Twitch channel {} not found", - // chanName); - // return; - // } + if (chan->isEmpty()) { + debug::Log("[IrcMessageHandler:handleClearChatMessage] Twitch channel {} not found", + chanName); + return; + } - // // check if the chat has been cleared by a moderator - // if (message->parameters().length() == 1) { - // chan->addMessage(Message::createSystemMessage("Chat has been cleared by a - // moderator.")); + // check if the chat has been cleared by a moderator + if (message->parameters().length() == 1) { + chan->addMessage(Message::createSystemMessage("Chat has been cleared by a moderator.")); - // return; - // } + return; + } - // // get username, duration and message of the timed out user - // QString username = message->parameter(1); - // QString durationInSeconds, reason; - // QVariant v = message->tag("ban-duration"); - // if (v.isValid()) { - // durationInSeconds = v.toString(); - // } + // get username, duration and message of the timed out user + QString username = message->parameter(1); + QString durationInSeconds, reason; + QVariant v = message->tag("ban-duration"); + if (v.isValid()) { + durationInSeconds = v.toString(); + } - // v = message->tag("ban-reason"); - // if (v.isValid()) { - // reason = v.toString(); - // } + v = message->tag("ban-reason"); + if (v.isValid()) { + reason = v.toString(); + } - // // add the notice that the user has been timed out - // LimitedQueueSnapshot snapshot = chan->getMessageSnapshot(); - // bool addMessage = true; - // int snapshotLength = snapshot.getLength(); + auto timeoutMsg = Message::createTimeoutMessage(username, durationInSeconds, reason, false); + chan->addOrReplaceTimeout(timeoutMsg); - // for (int i = std::max(0, snapshotLength - 20); i < snapshotLength; i++) { - // auto &s = snapshot[i]; - // if (s->flags.HasFlag(Message::Timeout) && s->timeoutUser == username) { - // MessagePtr replacement( - // Message::createTimeoutMessage(username, durationInSeconds, reason, true)); - // chan->replaceMessage(s, replacement); - // addMessage = false; - // break; - // } - // } - - // if (addMessage) { - // chan->addMessage(Message::createTimeoutMessage(username, durationInSeconds, reason, - // false)); - // } - - // // disable the messages from the user - // for (int i = 0; i < snapshotLength; i++) { - // auto &s = snapshot[i]; - // if (!(s->flags & Message::Timeout) && s->loginName == username) { - // s->flags.EnableFlag(Message::Disabled); - // } - // } - - // // refresh all - // app->windows->repaintVisibleChatWidgets(chan.get()); + // refresh all + app->windows->repaintVisibleChatWidgets(chan.get()); } void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message)