simplified message.cpp

This commit is contained in:
fourtf 2018-01-28 03:29:42 +01:00
parent fc758846f6
commit 591ab4d8da
20 changed files with 123 additions and 155 deletions

View file

@ -266,7 +266,8 @@ HEADERS += \
src/widgets/streamview.hpp \ src/widgets/streamview.hpp \
src/util/networkrequest.hpp \ src/util/networkrequest.hpp \
src/util/networkworker.hpp \ src/util/networkworker.hpp \
src/util/networkrequester.hpp src/util/networkrequester.hpp \
src/util/flagsenum.h
RESOURCES += \ RESOURCES += \
resources/resources.qrc resources/resources.qrc

View file

@ -16,7 +16,7 @@
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
class Message; struct Message;
} }
class Channel : public std::enable_shared_from_this<Channel> class Channel : public std::enable_shared_from_this<Channel>

View file

@ -39,7 +39,7 @@ void Channel::append(std::shared_ptr<messages::Message> message)
str.append("] "); str.append("] ");
str.append(message->loginName); str.append(message->loginName);
str.append(": "); str.append(": ");
str.append(message->getSearchText()); str.append(message->searchText);
str.append('\n'); str.append('\n');
this->appendLine(str); this->appendLine(str);
} }

View file

@ -22,7 +22,7 @@ MessageLayout::MessageLayout(MessagePtr _message)
: message(_message) : message(_message)
, buffer(nullptr) , buffer(nullptr)
{ {
if (_message->hasFlags(Message::Collapsed)) { if (_message->flags & Message::Collapsed) {
this->addFlags(MessageLayout::Collapsed); this->addFlags(MessageLayout::Collapsed);
} }
} }
@ -167,7 +167,7 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
painter.drawPixmap(0, y, this->container.width, this->container.getHeight(), *pixmap); painter.drawPixmap(0, y, this->container.width, this->container.getHeight(), *pixmap);
// draw disabled // draw disabled
if (this->message->hasFlags(Message::Disabled)) { if (this->message->flags & Message::Disabled) {
painter.fillRect(0, y, pixmap->width(), pixmap->height(), themeManager.messages.disabled); painter.fillRect(0, y, pixmap->width(), pixmap->height(), themeManager.messages.disabled);
} }
@ -186,7 +186,7 @@ void MessageLayout::updateBuffer(QPixmap *buffer, int messageIndex, Selection &s
painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.setRenderHint(QPainter::SmoothPixmapTransform);
// draw background // draw background
painter.fillRect(buffer->rect(), this->message->hasFlags(Message::Highlighted) painter.fillRect(buffer->rect(), this->message->flags & Message::Highlighted
? themeManager.messages.backgrounds.highlighted ? themeManager.messages.backgrounds.highlighted
: themeManager.messages.backgrounds.regular); : themeManager.messages.backgrounds.regular);

View file

@ -15,11 +15,11 @@ namespace chatterino {
namespace messages { namespace messages {
namespace layouts { namespace layouts {
class MessageLayout; struct MessageLayout;
typedef std::shared_ptr<MessageLayout> MessageLayoutPtr; typedef std::shared_ptr<MessageLayout> MessageLayoutPtr;
typedef uint8_t MessageLayoutFlagsType; typedef uint8_t MessageLayoutFlagsType;
class MessageLayout : boost::noncopyable struct MessageLayout : boost::noncopyable
{ {
public: public:
enum Flags : MessageLayoutFlagsType { Collapsed, RequiresBufferUpdate, RequiresLayout }; enum Flags : MessageLayoutFlagsType { Collapsed, RequiresBufferUpdate, RequiresLayout };

View file

@ -14,7 +14,7 @@ namespace chatterino {
namespace messages { namespace messages {
namespace layouts { namespace layouts {
class MessageLayoutElement; struct MessageLayoutElement;
struct Margin { struct Margin {
int top; int top;
@ -41,7 +41,7 @@ struct Margin {
} }
}; };
class MessageLayoutContainer struct MessageLayoutContainer
{ {
public: public:
MessageLayoutContainer(); MessageLayoutContainer();

View file

@ -15,12 +15,12 @@ class QPainter;
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
class MessageElement; struct MessageElement;
class Image; class Image;
namespace layouts { namespace layouts {
class MessageLayoutElement : boost::noncopyable struct MessageLayoutElement : boost::noncopyable
{ {
public: public:
MessageLayoutElement(MessageElement &creator, const QSize &size); MessageLayoutElement(MessageElement &creator, const QSize &size);

View file

@ -6,8 +6,6 @@ typedef chatterino::widgets::ScrollbarHighlight SBHighlight;
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
// elements
void Message::addElement(MessageElement *element) void Message::addElement(MessageElement *element)
{ {
this->elements.push_back(std::unique_ptr<MessageElement>(element)); this->elements.push_back(std::unique_ptr<MessageElement>(element));
@ -18,64 +16,9 @@ const std::vector<std::unique_ptr<MessageElement>> &Message::getElements() const
return this->elements; return this->elements;
} }
// Flags
Message::MessageFlags Message::getFlags() const
{
return this->flags;
}
bool Message::hasFlags(MessageFlags _flags) const
{
return this->flags & _flags;
}
// void Message::setFlags(MessageFlags _flags)
//{
// this->flags = flags;
//}
void Message::addFlags(MessageFlags _flags)
{
this->flags = (MessageFlags)((MessageFlagsType)this->flags | (MessageFlagsType)_flags);
}
void Message::removeFlags(MessageFlags _flags)
{
this->flags = (MessageFlags)((MessageFlagsType)this->flags & ~((MessageFlagsType)_flags));
}
// Parse Time
const QTime &Message::getParseTime() const
{
return this->parseTime;
}
// Id
const QString &Message::getId() const
{
return this->id;
}
void Message::setId(const QString &_id)
{
this->id = _id;
}
// Search
const QString &Message::getSearchText() const
{
return this->searchText;
}
void Message::setSearchText(const QString &value)
{
this->searchText = value;
}
// Highlight
SBHighlight Message::getScrollBarHighlight() const SBHighlight Message::getScrollBarHighlight() const
{ {
if (this->hasFlags(Message::Highlighted)) { if (this->flags & Message::Highlighted) {
return SBHighlight(SBHighlight::Highlight); return SBHighlight(SBHighlight::Highlight);
} }
return SBHighlight(); return SBHighlight();
@ -88,8 +31,8 @@ MessagePtr Message::createSystemMessage(const QString &text)
message->addElement(new TimestampElement(QTime::currentTime())); message->addElement(new TimestampElement(QTime::currentTime()));
message->addElement(new TextElement(text, MessageElement::Text, MessageColor::System)); message->addElement(new TextElement(text, MessageElement::Text, MessageColor::System));
message->addFlags(Message::System); message->flags &= Message::System;
message->setSearchText(text); message->searchText = text;
return MessagePtr(message); return MessagePtr(message);
} }
@ -129,7 +72,7 @@ MessagePtr Message::createTimeoutMessage(const QString &username, const QString
} }
MessagePtr message = Message::createSystemMessage(text); MessagePtr message = Message::createSystemMessage(text);
message->addFlags(Message::Timeout); message->flags &= Message::Timeout;
message->timeoutUser = username; message->timeoutUser = username;
return message; return message;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "messages/messageelement.hpp" #include "messages/messageelement.hpp"
#include "util/flagsenum.h"
#include "widgets/helper/scrollbarhighlight.hpp" #include "widgets/helper/scrollbarhighlight.hpp"
#include <cinttypes> #include <cinttypes>
@ -11,15 +12,8 @@
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
class Message; struct Message {
enum MessageFlags : uint16_t {
typedef std::shared_ptr<Message> MessagePtr;
typedef uint16_t MessageFlagsType;
class Message
{
public:
enum MessageFlags : MessageFlagsType {
None = 0, None = 0,
System = (1 << 0), System = (1 << 0),
Timeout = (1 << 1), Timeout = (1 << 1),
@ -32,60 +26,33 @@ public:
DisconnectedMessage = (1 << 8), DisconnectedMessage = (1 << 8),
}; };
// Elements util::FlagsEnum<MessageFlags> flags;
QTime parseTime;
QString id;
QString searchText;
QString loginName;
QString displayName;
QString localizedName;
QString timeoutUser;
// Messages should not be added after the message is done initializing. // Messages should not be added after the message is done initializing.
void addElement(MessageElement *element); void addElement(MessageElement *element);
const std::vector<std::unique_ptr<MessageElement>> &getElements() const; const std::vector<std::unique_ptr<MessageElement>> &getElements() const;
// Message flags
MessageFlags getFlags() const;
bool hasFlags(MessageFlags flags) const;
// void setFlags(MessageFlags flags);
void addFlags(MessageFlags flags);
void removeFlags(MessageFlags flags);
// Parse Time
const QTime &getParseTime() const;
// Id
const QString &getId() const;
void setId(const QString &id);
// Searching
const QString &getSearchText() const;
void setSearchText(const QString &value);
// Scrollbar // Scrollbar
widgets::ScrollbarHighlight getScrollBarHighlight() const; widgets::ScrollbarHighlight getScrollBarHighlight() const;
// Usernames
QString loginName;
QString displayName;
QString localizedName;
// Timeouts
const QString &getTimeoutUser(const QString &value) const;
void setTimeoutUser();
// Static
static MessagePtr createSystemMessage(const QString &text);
static MessagePtr createTimeoutMessage(const QString &username,
const QString &durationInSeconds, const QString &reason,
bool multipleTimes);
private: private:
static QRegularExpression *cheerRegex;
MessageFlags flags = MessageFlags::None;
QString timeoutUser;
bool collapsedDefault = false;
QTime parseTime;
mutable QString searchText;
QString id = "";
std::vector<std::unique_ptr<MessageElement>> elements; std::vector<std::unique_ptr<MessageElement>> elements;
public:
static std::shared_ptr<Message> createSystemMessage(const QString &text);
static std::shared_ptr<Message> createTimeoutMessage(const QString &username,
const QString &durationInSeconds,
const QString &reason, bool multipleTimes);
}; };
typedef std::shared_ptr<Message> MessagePtr;
} // namespace messages } // namespace messages
} // namespace chatterino } // namespace chatterino

View file

@ -31,9 +31,9 @@ void MessageBuilder::appendTimestamp()
void MessageBuilder::setHighlight(bool value) void MessageBuilder::setHighlight(bool value)
{ {
if (value) { if (value) {
this->message->addFlags(Message::Highlighted); this->message->flags |= Message::Highlighted;
} else { } else {
this->message->removeFlags(Message::Highlighted); this->message->flags &= ~Message::Highlighted;
} }
} }

View file

@ -9,7 +9,7 @@
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
class MessageBuilder struct MessageBuilder
{ {
public: public:
MessageBuilder(); MessageBuilder();

View file

@ -7,7 +7,7 @@
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
class MessageColor struct MessageColor
{ {
public: public:
enum Type { Custom, Text, Link, System }; enum Type { Custom, Text, Link, System };

View file

@ -20,12 +20,12 @@ struct EmoteData;
} }
namespace messages { namespace messages {
namespace layouts { namespace layouts {
class MessageLayoutContainer; struct MessageLayoutContainer;
} }
using namespace chatterino::messages::layouts; using namespace chatterino::messages::layouts;
class MessageElement : boost::noncopyable struct MessageElement : boost::noncopyable
{ {
public: public:
enum Flags : uint32_t { enum Flags : uint32_t {

View file

@ -97,7 +97,7 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
int snapshotLength = snapshot.getLength(); int snapshotLength = snapshot.getLength();
for (int i = std::max(0, snapshotLength - 20); i < snapshotLength; i++) { for (int i = std::max(0, snapshotLength - 20); i < snapshotLength; i++) {
if (snapshot[i]->hasFlags(Message::Timeout) && snapshot[i]->loginName == username) { if (snapshot[i]->flags & Message::Timeout && snapshot[i]->loginName == username) {
MessagePtr replacement( MessagePtr replacement(
Message::createTimeoutMessage(username, durationInSeconds, reason, true)); Message::createTimeoutMessage(username, durationInSeconds, reason, true));
c->replaceMessage(snapshot[i], replacement); c->replaceMessage(snapshot[i], replacement);
@ -112,8 +112,8 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
// disable the messages from the user // disable the messages from the user
for (int i = 0; i < snapshotLength; i++) { for (int i = 0; i < snapshotLength; i++) {
if (!snapshot[i]->hasFlags(Message::Timeout) && snapshot[i]->loginName == username) { if (!(snapshot[i]->flags & Message::Timeout) && snapshot[i]->loginName == username) {
snapshot[i]->addFlags(Message::Disabled); snapshot[i]->flags &= Message::Disabled;
} }
} }

View file

@ -381,29 +381,31 @@ void IrcManager::removeIgnoredUser(QString const &username)
void IrcManager::onConnected() void IrcManager::onConnected()
{ {
MessagePtr msg = Message::createSystemMessage("connected to chat"); MessagePtr connMsg = Message::createSystemMessage("connected to chat");
MessagePtr remsg = Message::createSystemMessage("reconnected to chat"); MessagePtr reconnMsg = Message::createSystemMessage("reconnected to chat");
this->channelManager.doOnAll([msg, remsg](SharedChannel channel) { this->channelManager.doOnAll([connMsg, reconnMsg](SharedChannel channel) {
assert(channel); assert(channel);
LimitedQueueSnapshot<MessagePtr> snapshot = channel->getMessageSnapshot(); LimitedQueueSnapshot<MessagePtr> snapshot = channel->getMessageSnapshot();
if (snapshot.getLength() > 0 && bool replaceMessage =
snapshot[snapshot.getLength() - 1]->hasFlags(Message::DisconnectedMessage)) // snapshot.getLength() > 0 &&
{ snapshot[snapshot.getLength() - 1]->flags & Message::DisconnectedMessage;
channel->replaceMessage(snapshot[snapshot.getLength() - 1], remsg);
if (replaceMessage) {
channel->replaceMessage(snapshot[snapshot.getLength() - 1], reconnMsg);
return; return;
} }
channel->addMessage(msg); channel->addMessage(connMsg);
}); });
} }
void IrcManager::onDisconnected() void IrcManager::onDisconnected()
{ {
MessagePtr msg = Message::createSystemMessage("disconnected from chat"); MessagePtr msg = Message::createSystemMessage("disconnected from chat");
msg->addFlags(Message::DisconnectedMessage); msg->flags &= Message::DisconnectedMessage;
this->channelManager.doOnAll([msg](SharedChannel channel) { this->channelManager.doOnAll([msg](SharedChannel channel) {
assert(channel); assert(channel);

View file

@ -188,7 +188,7 @@ MessagePtr TwitchMessageBuilder::parse()
i++; i++;
} }
this->message->setSearchText(this->userName + ": " + this->originalMessage); this->message->searchText = this->userName + ": " + this->originalMessage;
return this->getMessage(); return this->getMessage();
} }
@ -400,7 +400,7 @@ void TwitchMessageBuilder::parseHighlights()
} }
if (doHighlight) { if (doHighlight) {
this->message->addFlags(Message::Highlighted); this->message->flags &= Message::Highlighted;
} }
} }
} }

55
src/util/flagsenum.h Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#include <type_traits>
namespace chatterino {
namespace util {
template <typename T, typename _ = std::enable_if<std::is_enum<T>::value>::type,
typename Q = std::underlying_type<T>::type>
class FlagsEnum
{
public:
FlagsEnum()
: value((T)0)
{
}
FlagsEnum(T _value)
: value(_value)
{
}
inline T operator~() const
{
return (T) ~(Q)this->value;
}
inline T operator|(Q a) const
{
return (T)((Q)a | (Q)this->value);
}
inline T operator&(Q a) const
{
return (T)((Q)a & (Q)this->value);
}
inline T operator^(Q a) const
{
return (T)((Q)a ^ (Q)this->value);
}
inline T &operator|=(const Q &a)
{
return (T &)((Q &)a |= (Q)this->value);
}
inline T &operator&=(const Q &a)
{
return (T &)((Q &)a &= (Q)this->value);
}
inline T &operator^=(const Q &a)
{
return (T &)((Q &)a ^= (Q)this->value);
}
T value;
};
} // namespace util
} // namespace chatterino

View file

@ -48,13 +48,13 @@ void EmotePopup::loadChannel(SharedChannel _channel)
builder1.appendElement(new TextElement(title, MessageElement::Text)); builder1.appendElement(new TextElement(title, MessageElement::Text));
builder1.getMessage()->addFlags(Message::Centered); builder1.getMessage()->flags &= Message::Centered;
emoteChannel->addMessage(builder1.getMessage()); emoteChannel->addMessage(builder1.getMessage());
// EMOTES // EMOTES
messages::MessageBuilder builder2; messages::MessageBuilder builder2;
builder2.getMessage()->addFlags(Message::Centered); builder2.getMessage()->flags &= Message::Centered;
builder2.getMessage()->addFlags(Message::DisableCompactEmotes); builder2.getMessage()->flags &= Message::DisableCompactEmotes;
map.each([&](const QString &key, const util::EmoteData &value) { map.each([&](const QString &key, const util::EmoteData &value) {
builder2.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) // builder2.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) //
@ -87,13 +87,13 @@ void EmotePopup::loadEmojis()
messages::MessageBuilder builder1; messages::MessageBuilder builder1;
builder1.appendElement(new TextElement("emojis", MessageElement::Text)); builder1.appendElement(new TextElement("emojis", MessageElement::Text));
builder1.getMessage()->addFlags(Message::Centered); builder1.getMessage()->flags &= Message::Centered;
emojiChannel->addMessage(builder1.getMessage()); emojiChannel->addMessage(builder1.getMessage());
// emojis // emojis
messages::MessageBuilder builder; messages::MessageBuilder builder;
builder.getMessage()->addFlags(Message::Centered); builder.getMessage()->flags &= Message::Centered;
builder.getMessage()->addFlags(Message::DisableCompactEmotes); builder.getMessage()->flags &= Message::DisableCompactEmotes;
emojis.each([this, &builder](const QString &key, const util::EmoteData &value) { emojis.each([this, &builder](const QString &key, const util::EmoteData &value) {
builder.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) // builder.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) //

View file

@ -314,7 +314,7 @@ void ChannelView::setChannel(SharedChannel newChannel)
} }
} }
if (!message->hasFlags(Message::DoNotTriggerNotification)) { if (message->flags & ~Message::DoNotTriggerNotification) {
this->highlightedMessageReceived.invoke(); this->highlightedMessageReceived.invoke();
} }

View file

@ -75,8 +75,8 @@ void SearchPopup::performSearch()
for (size_t i = 0; i < this->snapshot.getLength(); i++) { for (size_t i = 0; i < this->snapshot.getLength(); i++) {
messages::MessagePtr message = this->snapshot[i]; messages::MessagePtr message = this->snapshot[i];
if (text.isEmpty() || message->getSearchText().indexOf(this->searchInput->text(), 0, if (text.isEmpty() ||
Qt::CaseInsensitive) != -1) { message->searchText.indexOf(this->searchInput->text(), 0, Qt::CaseInsensitive) != -1) {
channel->addMessage(message); channel->addMessage(message);
} }
} }