diff --git a/src/messages/message.cpp b/src/messages/message.cpp index 9c9b60d0..ab53455c 100644 --- a/src/messages/message.cpp +++ b/src/messages/message.cpp @@ -1,12 +1,12 @@ #include "messages/message.hpp" #include "channel.hpp" -#include "singletons/thememanager.hpp" #include "emojis.hpp" +#include "messages/link.hpp" #include "singletons/emotemanager.hpp" #include "singletons/fontmanager.hpp" #include "singletons/ircmanager.hpp" -#include "messages/link.hpp" #include "singletons/resourcemanager.hpp" +#include "singletons/thememanager.hpp" #include "util/irchelpers.hpp" #include @@ -56,6 +56,11 @@ bool Message::isDisabled() const return this->disabled; } +void Message::setDisabled(bool value) +{ + this->disabled = value; +} + const QString &Message::getId() const { return this->id; @@ -83,15 +88,15 @@ void AddCurrentTimestamp(Message *message) strftime(timeStampBuffer, 69, "%H:%M", localtime(&t)); QString timestampNoSeconds(timeStampBuffer); message->getWords().push_back(Word(timestampNoSeconds, Word::TimestampNoSeconds, - MessageColor(MessageColor::System), singletons::FontManager::Medium, - QString(), QString())); + MessageColor(MessageColor::System), + singletons::FontManager::Medium, QString(), QString())); // Add word for timestamp with seconds strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&t)); QString timestampWithSeconds(timeStampBuffer); message->getWords().push_back(Word(timestampWithSeconds, Word::TimestampWithSeconds, - MessageColor(MessageColor::System), singletons::FontManager::Medium, - QString(), QString())); + MessageColor(MessageColor::System), + singletons::FontManager::Medium, QString(), QString())); } } // namespace @@ -117,10 +122,6 @@ Message *Message::createSystemMessage(const QString &text) Message *Message::createTimeoutMessage(const QString &username, const QString &durationInSeconds, const QString &reason) { - Message *message = new Message; - - AddCurrentTimestamp(message); - QString text; text.append(username); @@ -148,12 +149,7 @@ Message *Message::createTimeoutMessage(const QString &username, const QString &d } text.append("."); - Word word(text, Word::Flags::Default, MessageColor(MessageColor::Type::System), - singletons::FontManager::Medium, text, QString()); - - message->getWords().push_back(word); - - return message; + return Message::createSystemMessage(text); } } // namespace messages diff --git a/src/messages/message.hpp b/src/messages/message.hpp index d551df3e..2774fd54 100644 --- a/src/messages/message.hpp +++ b/src/messages/message.hpp @@ -26,6 +26,7 @@ public: const std::chrono::time_point &getParseTime() const; std::vector &getWords(); bool isDisabled() const; + void setDisabled(bool value); const QString &getId() const; bool getCollapsedDefault() const; void setCollapsedDefault(bool value); @@ -33,6 +34,7 @@ public: QString loginName; QString displayName; QString localizedName; + QString timeoutUser; const QString text; bool centered = false; @@ -56,7 +58,6 @@ private: // what is highlightTab? bool highlightTab = false; - QString timeoutUser = ""; int timeoutCount = 0; bool disabled = false; diff --git a/src/messages/messageref.cpp b/src/messages/messageref.cpp index 932bed15..82774b1c 100644 --- a/src/messages/messageref.cpp +++ b/src/messages/messageref.cpp @@ -50,7 +50,8 @@ bool MessageRef::layout(int width, float scale) this->emoteGeneration = emoteManager.getGeneration(); // check if text changed - bool textChanged = this->fontGeneration != singletons::FontManager::getInstance().getGeneration(); + bool textChanged = + this->fontGeneration != singletons::FontManager::getInstance().getGeneration(); layoutRequired |= textChanged; this->fontGeneration = singletons::FontManager::getInstance().getGeneration(); @@ -436,5 +437,10 @@ int MessageRef::getCollapsedHeight() const { return this->collapsedHeight; } + +bool MessageRef::isDisabled() const +{ + return this->message->isDisabled(); +} } // namespace messages } // namespace chatterino diff --git a/src/messages/messageref.hpp b/src/messages/messageref.hpp index d8ff8e90..7d165f88 100644 --- a/src/messages/messageref.hpp +++ b/src/messages/messageref.hpp @@ -38,6 +38,8 @@ public: int getCollapsedHeight() const; int getCollapsedLineCount() const; + bool isDisabled() const; + private: // variables SharedMessage message; diff --git a/src/singletons/ircmanager.cpp b/src/singletons/ircmanager.cpp index 07ffa921..bc5aedf4 100644 --- a/src/singletons/ircmanager.cpp +++ b/src/singletons/ircmanager.cpp @@ -325,6 +325,7 @@ void IrcManager::handleClearChatMessage(Communi::IrcMessage *message) return; } + // check if the chat has been cleared by a moderator if (message->parameters().length() == 1) { std::shared_ptr msg( Message::createSystemMessage("Chat has been cleared by a moderator.")); @@ -336,6 +337,7 @@ void IrcManager::handleClearChatMessage(Communi::IrcMessage *message) assert(message->parameters().length() >= 2); + // get username, duration and message of the timed out user QString username = message->parameter(1); QString durationInSeconds, reason; QVariant v = message->tag("ban-duration"); @@ -348,10 +350,21 @@ void IrcManager::handleClearChatMessage(Communi::IrcMessage *message) reason = v.toString(); } - std::shared_ptr msg( - Message::createTimeoutMessage(username, durationInSeconds, reason)); + // add the notice that the user has been timed out + SharedMessage msg(Message::createTimeoutMessage(username, durationInSeconds, reason)); c->addMessage(msg); + + // disable the messages from the user + LimitedQueueSnapshot snapshot = c->getMessageSnapshot(); + for (int i = 0; i < snapshot.getLength(); i++) { + if (snapshot[i]->getTimeoutUser() == username) { + snapshot[i]->setDisabled(true); + } + } + + // refresh all + WindowManager::getInstance().layoutVisibleChatWidgets(c.get()); } void IrcManager::handleUserStateMessage(Communi::IrcMessage *message) diff --git a/src/singletons/thememanager.cpp b/src/singletons/thememanager.cpp index a296b4c5..3919014a 100644 --- a/src/singletons/thememanager.cpp +++ b/src/singletons/thememanager.cpp @@ -100,6 +100,7 @@ void ThemeManager::actuallyUpdate(double hue, double multiplier) bool flat = lightTheme; ChatBackground = getColor(0, sat, 1); + DisabledMessageOverlay = getColor(0, sat, 1, 0.6); ChatBackgroundHighlighted = blendColors(TabSelectedBackground, ChatBackground, 0.8); ChatHeaderBackground = getColor(0, sat, flat ? 1 : 0.9); ChatHeaderBorder = getColor(0, sat, flat ? 1 : 0.85); diff --git a/src/singletons/thememanager.hpp b/src/singletons/thememanager.hpp index 85e84aac..fa57e84b 100644 --- a/src/singletons/thememanager.hpp +++ b/src/singletons/thememanager.hpp @@ -36,6 +36,7 @@ public: QColor ChatBackgroundHighlighted; QColor ChatBackgroundResub; QColor ChatBackgroundWhisper; + QColor DisabledMessageOverlay; QColor ChatHeaderBorder; QColor ChatHeaderBackground; diff --git a/src/singletons/windowmanager.cpp b/src/singletons/windowmanager.cpp index 5faf956d..103ed6d6 100644 --- a/src/singletons/windowmanager.cpp +++ b/src/singletons/windowmanager.cpp @@ -35,7 +35,7 @@ static const std::string &getSettingsPath() void WindowManager::layoutVisibleChatWidgets(Channel *channel) { - this->layout(); + this->layout(channel); } void WindowManager::repaintVisibleChatWidgets(Channel *channel) diff --git a/src/singletons/windowmanager.hpp b/src/singletons/windowmanager.hpp index 936f57db..675a05a3 100644 --- a/src/singletons/windowmanager.hpp +++ b/src/singletons/windowmanager.hpp @@ -30,7 +30,7 @@ public: void save(); boost::signals2::signal repaintGifs; - boost::signals2::signal layout; + boost::signals2::signal layout; private: ThemeManager &themeManager; diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp index 11864a19..d9054284 100644 --- a/src/twitch/twitchmessagebuilder.cpp +++ b/src/twitch/twitchmessagebuilder.cpp @@ -305,6 +305,7 @@ void TwitchMessageBuilder::parseUsername() } this->message->loginName = this->userName; + this->message->timeoutUser = this->userName; } void TwitchMessageBuilder::appendUsername() diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index abe66fd7..29755d35 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -56,7 +56,11 @@ ChannelView::ChannelView(BaseWidget *parent) this->repaintGifsConnection = windowManager.repaintGifs.connect([&] { this->updateGifEmotes(); }); - this->layoutConnection = windowManager.layout.connect([&] { this->layoutMessages(); }); + this->layoutConnection = windowManager.layout.connect([&](Channel *channel) { + if (channel == nullptr || this->channel.get() == channel) { + this->layoutMessages(); + } + }); this->goToBottom = new RippleEffectLabel(this, 0); this->goToBottom->setStyleSheet("background-color: rgba(0,0,0,0.5); color: #FFF;"); @@ -482,20 +486,24 @@ void ChannelView::paintEvent(QPaintEvent * /*event*/) painter.fillRect(rect(), this->themeManager.ChatBackground); // draw messages - this->drawMessages(painter); + this->drawMessages(painter, false); painter.setRenderHint(QPainter::SmoothPixmapTransform); // draw gif emotes for (GifEmoteData &item : this->gifEmotes) { - // painter.fillRect(item.rect, this->themeManager.ChatBackground); - painter.drawPixmap(item.rect, *item.image->getPixmap()); } + + // draw the overlays of the messages (such as disabled message blur-out) + this->drawMessages(painter, true); + // MARK(timer); } -void ChannelView::drawMessages(QPainter &painter) +// if overlays is false then it draws the message, if true then it draws things such as the grey +// overlay when a message is disabled +void ChannelView::drawMessages(QPainter &painter, bool overlays) { auto messagesSnapshot = this->getMessagesSnapshot(); @@ -513,46 +521,53 @@ void ChannelView::drawMessages(QPainter &painter) for (size_t i = start; i < messagesSnapshot.getLength(); ++i) { messages::MessageRef *messageRef = messagesSnapshot[i].get(); - std::shared_ptr buffer = messageRef->buffer; + if (overlays) { + if (messageRef->isDisabled()) { + painter.fillRect(0, y, this->width(), messageRef->getHeight(), + this->themeManager.DisabledMessageOverlay); + } + } else { + std::shared_ptr buffer = messageRef->buffer; - // bool updateBuffer = messageRef->updateBuffer; - bool updateBuffer = false; + // bool updateBuffer = messageRef->updateBuffer; + bool updateBuffer = false; - if (!buffer) { - buffer = std::shared_ptr(new QPixmap(width(), messageRef->getHeight())); - updateBuffer = true; - } + if (!buffer) { + buffer = std::shared_ptr(new QPixmap(width(), messageRef->getHeight())); + updateBuffer = true; + } - updateBuffer |= this->selecting; + updateBuffer |= this->selecting; - // update messages that have been changed - if (updateBuffer) { - this->updateMessageBuffer(messageRef, buffer.get(), i); - // qDebug() << "updating buffer xD"; - } + // update messages that have been changed + if (updateBuffer) { + this->updateMessageBuffer(messageRef, buffer.get(), i); + // qDebug() << "updating buffer xD"; + } - // get gif emotes - for (messages::WordPart const &wordPart : messageRef->getWordParts()) { - if (wordPart.getWord().isImage()) { - messages::LazyLoadedImage &lli = wordPart.getWord().getImage(); + // get gif emotes + for (messages::WordPart const &wordPart : messageRef->getWordParts()) { + if (wordPart.getWord().isImage()) { + messages::LazyLoadedImage &lli = wordPart.getWord().getImage(); - if (lli.getAnimated()) { - GifEmoteData gifEmoteData; - gifEmoteData.image = &lli; - QRect rect(wordPart.getX(), wordPart.getY() + y, wordPart.getWidth(), - wordPart.getHeight()); + if (lli.getAnimated()) { + GifEmoteData gifEmoteData; + gifEmoteData.image = &lli; + QRect rect(wordPart.getX(), wordPart.getY() + y, wordPart.getWidth(), + wordPart.getHeight()); - gifEmoteData.rect = rect; + gifEmoteData.rect = rect; - this->gifEmotes.push_back(gifEmoteData); + this->gifEmotes.push_back(gifEmoteData); + } } } - } - messageRef->buffer = buffer; + messageRef->buffer = buffer; - if (buffer) { - painter.drawPixmap(0, y, *buffer.get()); + if (buffer) { + painter.drawPixmap(0, y, *buffer.get()); + } } y += messageRef->getHeight(); diff --git a/src/widgets/helper/channelview.hpp b/src/widgets/helper/channelview.hpp index 8f3a40ce..7910836e 100644 --- a/src/widgets/helper/channelview.hpp +++ b/src/widgets/helper/channelview.hpp @@ -133,7 +133,7 @@ private: void detachChannel(); void actuallyLayoutMessages(); - void drawMessages(QPainter &painter); + void drawMessages(QPainter &painter, bool overlays); void updateMessageBuffer(messages::MessageRef *messageRef, QPixmap *buffer, int messageIndex); void drawMessageSelection(QPainter &painter, messages::MessageRef *messageRef, int messageIndex, int bufferHeight);