refactored MessageBuilder

This commit is contained in:
fourtf
2018-08-07 01:35:24 +02:00
parent f71ff08e68
commit c26422aec1
29 changed files with 964 additions and 970 deletions
+511 -509
View File
File diff suppressed because it is too large Load Diff
+9 -6
View File
@@ -6,6 +6,7 @@
#include "controllers/ignores/IgnoreController.hpp" #include "controllers/ignores/IgnoreController.hpp"
#include "controllers/moderationactions/ModerationActions.hpp" #include "controllers/moderationactions/ModerationActions.hpp"
#include "controllers/taggedusers/TaggedUsersController.hpp" #include "controllers/taggedusers/TaggedUsersController.hpp"
#include "messages/MessageBuilder.hpp"
#include "providers/bttv/BttvEmotes.hpp" #include "providers/bttv/BttvEmotes.hpp"
#include "providers/ffz/FfzEmotes.hpp" #include "providers/ffz/FfzEmotes.hpp"
#include "providers/twitch/PubsubClient.hpp" #include "providers/twitch/PubsubClient.hpp"
@@ -130,7 +131,7 @@ void Application::initPubsub()
QString text = QString text =
QString("%1 cleared the chat").arg(action.source.name); QString("%1 cleared the chat").arg(action.source.name);
auto msg = Message::createSystemMessage(text); auto msg = makeSystemMessage(text);
postToThread([chan, msg] { chan->addMessage(msg); }); postToThread([chan, msg] { chan->addMessage(msg); });
}); });
@@ -154,7 +155,7 @@ void Application::initPubsub()
" seconds)"); " seconds)");
} }
auto msg = Message::createSystemMessage(text); auto msg = makeSystemMessage(text);
postToThread([chan, msg] { chan->addMessage(msg); }); postToThread([chan, msg] { chan->addMessage(msg); });
}); });
@@ -176,7 +177,7 @@ void Application::initPubsub()
.arg(action.source.name, action.target.name); .arg(action.source.name, action.target.name);
} }
auto msg = Message::createSystemMessage(text); auto msg = makeSystemMessage(text);
postToThread([chan, msg] { chan->addMessage(msg); }); postToThread([chan, msg] { chan->addMessage(msg); });
}); });
@@ -189,10 +190,12 @@ void Application::initPubsub()
return; return;
} }
auto msg = Message::createTimeoutMessage(action); MessageBuilder msg(action);
msg->flags |= Message::PubSub; msg->flags |= Message::PubSub;
postToThread([chan, msg] { chan->addOrReplaceTimeout(msg); }); postToThread([chan, msg = msg.release()] {
chan->addOrReplaceTimeout(msg);
});
}); });
this->twitch.pubsub->signals_.moderation.userUnbanned.connect( this->twitch.pubsub->signals_.moderation.userUnbanned.connect(
@@ -204,7 +207,7 @@ void Application::initPubsub()
return; return;
} }
auto msg = Message::createUntimeoutMessage(action); auto msg = MessageBuilder(action).release();
postToThread([chan, msg] { chan->addMessage(msg); }); postToThread([chan, msg] { chan->addMessage(msg); });
}); });
+16 -16
View File
@@ -47,29 +47,29 @@ public:
friend void test(); friend void test();
Settings *const settings = nullptr; Settings *const settings{};
Paths *const paths = nullptr; Paths *const paths{};
Resources2 *const resources; Resources2 *const resources;
Theme *const themes = nullptr; Theme *const themes{};
Fonts *const fonts = nullptr; Fonts *const fonts{};
Emotes *const emotes = nullptr; Emotes *const emotes{};
WindowManager *const windows = nullptr; WindowManager *const windows{};
AccountController *const accounts = nullptr; AccountController *const accounts{};
CommandController *const commands = nullptr; CommandController *const commands{};
HighlightController *const highlights = nullptr; HighlightController *const highlights{};
IgnoreController *const ignores = nullptr; IgnoreController *const ignores{};
TaggedUsersController *const taggedUsers = nullptr; TaggedUsersController *const taggedUsers{};
ModerationActions *const moderationActions = nullptr; ModerationActions *const moderationActions{};
TwitchServer *const twitch2 = nullptr; TwitchServer *const twitch2{};
[[deprecated]] Logging *const logging = nullptr; /*[[deprecated]]*/ Logging *const logging{};
/// Provider-specific /// Provider-specific
struct { struct {
[[deprecated("use twitch2 instead")]] TwitchServer *server = nullptr; /*[[deprecated("use twitch2 instead")]]*/ TwitchServer *server{};
[[deprecated("use twitch2->pubsub instead")]] PubSub *pubsub = nullptr; /*[[deprecated("use twitch2->pubsub instead")]]*/ PubSub *pubsub{};
} twitch; } twitch;
private: private:
+10 -7
View File
@@ -3,6 +3,7 @@
#include "Application.hpp" #include "Application.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "messages/Message.hpp" #include "messages/Message.hpp"
#include "messages/MessageBuilder.hpp"
#include "singletons/Emotes.hpp" #include "singletons/Emotes.hpp"
#include "singletons/Logging.hpp" #include "singletons/Logging.hpp"
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
@@ -124,15 +125,15 @@ void Channel::addOrReplaceTimeout(MessagePtr message)
int count = s->count + 1; int count = s->count + 1;
MessagePtr replacement(Message::createSystemMessage( MessageBuilder replacement(systemMessage,
message->searchText + QString(" (") + QString::number(count) + message->searchText + QString(" (") +
" times)")); QString::number(count) + " times)");
replacement->timeoutUser = message->timeoutUser; replacement->timeoutUser = message->timeoutUser;
replacement->count = count; replacement->count = count;
replacement->flags = message->flags; replacement->flags = message->flags;
this->replaceMessage(s, replacement); this->replaceMessage(s, replacement.release());
return; return;
} }
@@ -143,7 +144,8 @@ void Channel::addOrReplaceTimeout(MessagePtr message)
auto &s = snapshot[i]; auto &s = snapshot[i];
if ((s->flags & (Message::Timeout | Message::Untimeout)) == 0 && if ((s->flags & (Message::Timeout | Message::Untimeout)) == 0 &&
s->loginName == message->timeoutUser) { s->loginName == message->timeoutUser) {
s->flags.EnableFlag(Message::Disabled); // FOURTF: disabled for now
// s->flags.EnableFlag(Message::Disabled);
} }
} }
@@ -165,7 +167,8 @@ void Channel::disableAllMessages()
continue; continue;
} }
s->flags.EnableFlag(Message::Disabled); // FOURTF: disabled for now
// s->flags.EnableFlag(Message::Disabled);
} }
} }
@@ -188,7 +191,7 @@ void Channel::replaceMessage(MessagePtr message, MessagePtr replacement)
} }
} }
void Channel::addRecentChatter(const std::shared_ptr<Message> &message) void Channel::addRecentChatter(const MessagePtr &message)
{ {
// Do nothing by default // Do nothing by default
} }
+1 -1
View File
@@ -52,7 +52,7 @@ public:
void addOrReplaceTimeout(MessagePtr message); void addOrReplaceTimeout(MessagePtr message);
void disableAllMessages(); void disableAllMessages();
void replaceMessage(MessagePtr message, MessagePtr replacement); void replaceMessage(MessagePtr message, MessagePtr replacement);
virtual void addRecentChatter(const std::shared_ptr<Message> &message); virtual void addRecentChatter(const MessagePtr &message);
QStringList modList; QStringList modList;
+18
View File
@@ -54,6 +54,24 @@ public:
reinterpret_cast<Q &>(this->value) |= static_cast<Q>(flag); reinterpret_cast<Q &>(this->value) |= static_cast<Q>(flag);
} }
void set(T flag)
{
reinterpret_cast<Q &>(this->value) |= static_cast<Q>(flag);
}
void unset(T flag)
{
reinterpret_cast<Q &>(this->value) &= ~static_cast<Q>(flag);
}
void set(T flag, bool value)
{
if (value)
this->set(flag);
else
this->unset(flag);
}
bool HasFlag(Q flag) const bool HasFlag(Q flag) const
{ {
return (this->value & flag) == flag; return (this->value & flag) == flag;
+31 -30
View File
@@ -141,16 +141,17 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
} }
b.emplace<TextElement>(rest, MessageElement::Text); b.emplace<TextElement>(rest, MessageElement::Text);
b.getMessage()->flags |= Message::DoNotTriggerNotification; b.message().flags |= Message::DoNotTriggerNotification;
auto messagexD = b.release();
app->twitch.server->whispersChannel->addMessage(b.getMessage()); app->twitch.server->whispersChannel->addMessage(messagexD);
app->twitch.server->sendMessage("jtv", text); app->twitch.server->sendMessage("jtv", text);
if (getSettings()->inlineWhispers) { if (getSettings()->inlineWhispers) {
app->twitch.server->forEachChannel( app->twitch.server->forEachChannel(
[&b](ChannelPtr _channel) { [&messagexD](ChannelPtr _channel) {
_channel->addMessage(b.getMessage()); _channel->addMessage(messagexD);
}); });
} }
@@ -166,7 +167,7 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
if (commandName == "/debug-args") { if (commandName == "/debug-args") {
QString msg = QApplication::instance()->arguments().join(' '); QString msg = QApplication::instance()->arguments().join(' ');
channel->addMessage(Message::createSystemMessage(msg)); channel->addMessage(makeSystemMessage(msg));
return ""; return "";
} else if (commandName == "/uptime") { } else if (commandName == "/uptime") {
@@ -176,13 +177,13 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
? streamStatus->uptime ? streamStatus->uptime
: "Channel is not live."; : "Channel is not live.";
channel->addMessage(Message::createSystemMessage(messageText)); channel->addMessage(makeSystemMessage(messageText));
return ""; return "";
} else if (commandName == "/ignore") { } else if (commandName == "/ignore") {
if (words.size() < 2) { if (words.size() < 2) {
channel->addMessage( channel->addMessage(
Message::createSystemMessage("Usage: /ignore [user]")); makeSystemMessage("Usage: /ignore [user]"));
return ""; return "";
} }
auto app = getApp(); auto app = getApp();
@@ -191,21 +192,21 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
auto target = words.at(1); auto target = words.at(1);
if (user->isAnon()) { if (user->isAnon()) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"You must be logged in to ignore someone")); "You must be logged in to ignore someone"));
return ""; return "";
} }
user->ignore(target, [channel](auto resultCode, user->ignore(
const QString &message) { target, [channel](auto resultCode, const QString &message) {
channel->addMessage(Message::createSystemMessage(message)); channel->addMessage(makeSystemMessage(message));
}); });
return ""; return "";
} else if (commandName == "/unignore") { } else if (commandName == "/unignore") {
if (words.size() < 2) { if (words.size() < 2) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(
"Usage: /unignore [user]")); makeSystemMessage("Usage: /unignore [user]"));
return ""; return "";
} }
auto app = getApp(); auto app = getApp();
@@ -214,21 +215,21 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
auto target = words.at(1); auto target = words.at(1);
if (user->isAnon()) { if (user->isAnon()) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"You must be logged in to ignore someone")); "You must be logged in to ignore someone"));
return ""; return "";
} }
user->unignore(target, [channel](auto resultCode, user->unignore(
const QString &message) { target, [channel](auto resultCode, const QString &message) {
channel->addMessage(Message::createSystemMessage(message)); channel->addMessage(makeSystemMessage(message));
}); });
return ""; return "";
} else if (commandName == "/follow") { } else if (commandName == "/follow") {
if (words.size() < 2) { if (words.size() < 2) {
channel->addMessage( channel->addMessage(
Message::createSystemMessage("Usage: /follow [user]")); makeSystemMessage("Usage: /follow [user]"));
return ""; return "";
} }
auto app = getApp(); auto app = getApp();
@@ -237,7 +238,7 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
auto target = words.at(1); auto target = words.at(1);
if (user->isAnon()) { if (user->isAnon()) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"You must be logged in to follow someone")); "You must be logged in to follow someone"));
return ""; return "";
} }
@@ -245,12 +246,12 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
TwitchApi::findUserId( TwitchApi::findUserId(
target, [user, channel, target](QString userId) { target, [user, channel, target](QString userId) {
if (userId.isEmpty()) { if (userId.isEmpty()) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"User " + target + " could not be followed!")); "User " + target + " could not be followed!"));
return; return;
} }
user->followUser(userId, [channel, target]() { user->followUser(userId, [channel, target]() {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"You successfully followed " + target)); "You successfully followed " + target));
}); });
}); });
@@ -258,8 +259,8 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
return ""; return "";
} else if (commandName == "/unfollow") { } else if (commandName == "/unfollow") {
if (words.size() < 2) { if (words.size() < 2) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(
"Usage: /unfollow [user]")); makeSystemMessage("Usage: /unfollow [user]"));
return ""; return "";
} }
auto app = getApp(); auto app = getApp();
@@ -268,7 +269,7 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
auto target = words.at(1); auto target = words.at(1);
if (user->isAnon()) { if (user->isAnon()) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"You must be logged in to follow someone")); "You must be logged in to follow someone"));
return ""; return "";
} }
@@ -276,12 +277,12 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
TwitchApi::findUserId( TwitchApi::findUserId(
target, [user, channel, target](QString userId) { target, [user, channel, target](QString userId) {
if (userId.isEmpty()) { if (userId.isEmpty()) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"User " + target + " could not be followed!")); "User " + target + " could not be followed!"));
return; return;
} }
user->unfollowUser(userId, [channel, target]() { user->unfollowUser(userId, [channel, target]() {
channel->addMessage(Message::createSystemMessage( channel->addMessage(makeSystemMessage(
"You successfully unfollowed " + target)); "You successfully unfollowed " + target));
}); });
}); });
@@ -289,8 +290,8 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
return ""; return "";
} else if (commandName == "/logs") { } else if (commandName == "/logs") {
if (words.size() < 2) { if (words.size() < 2) {
channel->addMessage(Message::createSystemMessage( channel->addMessage(
"Usage: /logs [user] (channel)")); makeSystemMessage("Usage: /logs [user] (channel)"));
return ""; return "";
} }
auto app = getApp(); auto app = getApp();
+1
View File
@@ -6,6 +6,7 @@
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "singletons/Emotes.hpp" #include "singletons/Emotes.hpp"
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
#include "util/DebugCount.hpp"
#include "util/PostToThread.hpp" #include "util/PostToThread.hpp"
#include <QBuffer> #include <QBuffer>
+6 -191
View File
@@ -1,20 +1,22 @@
#include "messages/Message.hpp" #include "messages/Message.hpp"
#include "MessageElement.hpp" #include "MessageElement.hpp"
#include "providers/twitch/PubsubActions.hpp" #include "providers/twitch/PubsubActions.hpp"
#include "util/DebugCount.hpp"
#include "util/IrcHelpers.hpp" #include "util/IrcHelpers.hpp"
using SBHighlight = chatterino::ScrollbarHighlight; using SBHighlight = chatterino::ScrollbarHighlight;
namespace chatterino { namespace chatterino {
void Message::addElement(MessageElement *element) Message::Message()
: parseTime(QTime::currentTime())
{ {
this->elements_.push_back(std::unique_ptr<MessageElement>(element)); DebugCount::increase("messages");
} }
const std::vector<std::unique_ptr<MessageElement>> &Message::getElements() const Message::~Message()
{ {
return this->elements_; DebugCount::decrease("messages");
} }
SBHighlight Message::getScrollBarHighlight() const SBHighlight Message::getScrollBarHighlight() const
@@ -28,195 +30,8 @@ SBHighlight Message::getScrollBarHighlight() const
} }
// Static // Static
MessagePtr Message::createSystemMessage(const QString &text)
{
MessagePtr message(new Message);
message->addElement(new TimestampElement(QTime::currentTime()));
message->addElement(
new TextElement(text, MessageElement::Text, MessageColor::System));
message->flags |= MessageFlags::System;
message->flags |= MessageFlags::DoNotTriggerNotification;
message->searchText = text;
return message;
}
MessagePtr Message::createMessage(const QString &text)
{
MessagePtr message(new Message);
message->addElement(new TimestampElement(QTime::currentTime()));
message->addElement(
new TextElement(text, MessageElement::Text, MessageColor::Text));
message->searchText = text;
return message;
}
namespace { namespace {
void appendDuration(int count, QChar &&order, QString &outString)
{
outString.append(QString::number(count));
outString.append(order);
}
QString makeDuration(int timeoutSeconds)
{
QString res;
int seconds = timeoutSeconds % 60;
int timeoutMinutes = timeoutSeconds / 60;
int minutes = timeoutMinutes % 60;
int timeoutHours = timeoutMinutes / 60;
int hours = timeoutHours % 24;
int days = timeoutHours / 24;
if (days > 0) {
appendDuration(days, 'd', res);
}
if (hours > 0) {
if (!res.isEmpty()) {
res.append(" ");
}
appendDuration(hours, 'h', res);
}
if (minutes > 0) {
if (!res.isEmpty()) {
res.append(" ");
}
appendDuration(minutes, 'm', res);
}
if (seconds > 0) {
if (!res.isEmpty()) {
res.append(" ");
}
appendDuration(seconds, 's', res);
}
return res;
}
} // namespace } // namespace
MessagePtr Message::createTimeoutMessage(const QString &username,
const QString &durationInSeconds,
const QString &reason,
bool multipleTimes)
{
QString text;
text.append(username);
if (!durationInSeconds.isEmpty()) {
text.append(" has been timed out");
// TODO: Implement who timed the user out
text.append(" for ");
bool ok = true;
int timeoutSeconds = durationInSeconds.toInt(&ok);
if (ok) {
text.append(makeDuration(timeoutSeconds));
}
} else {
text.append(" has been permanently banned");
}
if (reason.length() > 0) {
text.append(": \"");
text.append(parseTagString(reason));
text.append("\"");
}
text.append(".");
if (multipleTimes) {
text.append(" (multiple times)");
}
MessagePtr message = Message::createSystemMessage(text);
message->flags.EnableFlag(MessageFlags::System);
message->flags.EnableFlag(MessageFlags::Timeout);
message->timeoutUser = username;
return message;
}
MessagePtr Message::createTimeoutMessage(const BanAction &action,
uint32_t count)
{
MessagePtr msg(new Message);
msg->addElement(new TimestampElement(QTime::currentTime()));
msg->flags.EnableFlag(MessageFlags::System);
msg->flags.EnableFlag(MessageFlags::Timeout);
msg->timeoutUser = action.target.name;
msg->count = count;
QString text;
if (action.isBan()) {
if (action.reason.isEmpty()) {
text = QString("%1 banned %2.") //
.arg(action.source.name)
.arg(action.target.name);
} else {
text = QString("%1 banned %2: \"%3\".") //
.arg(action.source.name)
.arg(action.target.name)
.arg(action.reason);
}
} else {
if (action.reason.isEmpty()) {
text = QString("%1 timed out %2 for %3.") //
.arg(action.source.name)
.arg(action.target.name)
.arg(makeDuration(action.duration));
} else {
text = QString("%1 timed out %2 for %3: \"%4\".") //
.arg(action.source.name)
.arg(action.target.name)
.arg(makeDuration(action.duration))
.arg(action.reason);
}
if (count > 1) {
text.append(QString(" (%1 times)").arg(count));
}
}
msg->addElement(
new TextElement(text, MessageElement::Text, MessageColor::System));
msg->searchText = text;
return msg;
}
MessagePtr Message::createUntimeoutMessage(const UnbanAction &action)
{
MessagePtr msg(new Message);
msg->addElement(new TimestampElement(QTime::currentTime()));
msg->flags.EnableFlag(MessageFlags::System);
msg->flags.EnableFlag(MessageFlags::Untimeout);
msg->timeoutUser = action.target.name;
QString text;
if (action.wasBan()) {
text = QString("%1 unbanned %2.") //
.arg(action.source.name)
.arg(action.target.name);
} else {
text = QString("%1 untimedout %2.") //
.arg(action.source.name)
.arg(action.target.name);
}
msg->addElement(
new TextElement(text, MessageElement::Text, MessageColor::System));
msg->searchText = text;
return msg;
}
} // namespace chatterino } // namespace chatterino
+6 -38
View File
@@ -6,27 +6,13 @@
#include "widgets/helper/ScrollbarHighlight.hpp" #include "widgets/helper/ScrollbarHighlight.hpp"
#include <QTime> #include <QTime>
#include <cinttypes> #include <cinttypes>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "util/DebugCount.hpp"
namespace chatterino { namespace chatterino {
struct Message { struct Message : boost::noncopyable {
Message()
: parseTime(QTime::currentTime())
{
DebugCount::increase("messages");
}
~Message()
{
DebugCount::decrease("messages");
}
enum MessageFlags : uint16_t { enum MessageFlags : uint16_t {
None = 0, None = 0,
System = (1 << 0), System = (1 << 0),
@@ -43,6 +29,9 @@ struct Message {
Subscription = (1 << 11), Subscription = (1 << 11),
}; };
Message();
~Message();
FlagsEnum<MessageFlags> flags; FlagsEnum<MessageFlags> flags;
QTime parseTime; QTime parseTime;
QString id; QString id;
@@ -51,33 +40,12 @@ struct Message {
QString displayName; QString displayName;
QString localizedName; QString localizedName;
QString timeoutUser; QString timeoutUser;
uint32_t count = 1; uint32_t count = 1;
std::vector<std::unique_ptr<MessageElement>> elements;
// Messages should not be added after the message is done initializing.
void addElement(MessageElement *element);
const std::vector<std::unique_ptr<MessageElement>> &getElements() const;
// Scrollbar
ScrollbarHighlight getScrollBarHighlight() const; ScrollbarHighlight getScrollBarHighlight() const;
private:
std::vector<std::unique_ptr<MessageElement>> elements_;
public:
static std::shared_ptr<Message> createSystemMessage(const QString &text);
static std::shared_ptr<Message> createMessage(const QString &text);
static std::shared_ptr<Message> createTimeoutMessage(
const QString &username, const QString &durationInSeconds,
const QString &reason, bool multipleTimes);
static std::shared_ptr<Message> createTimeoutMessage(
const BanAction &action, uint32_t count = 1);
static std::shared_ptr<Message> createUntimeoutMessage(
const UnbanAction &action);
}; };
using MessagePtr = std::shared_ptr<Message>; using MessagePtr = std::shared_ptr<const Message>;
} // namespace chatterino } // namespace chatterino
+143 -15
View File
@@ -4,43 +4,171 @@
#include "singletons/Emotes.hpp" #include "singletons/Emotes.hpp"
#include "singletons/Resources.hpp" #include "singletons/Resources.hpp"
#include "singletons/Theme.hpp" #include "singletons/Theme.hpp"
#include "util/FormatTime.hpp"
#include "util/IrcHelpers.hpp"
#include <QDateTime> #include <QDateTime>
namespace chatterino { namespace chatterino {
MessagePtr makeSystemMessage(const QString &text)
{
return MessageBuilder(systemMessage, text).release();
}
MessageBuilder::MessageBuilder() MessageBuilder::MessageBuilder()
: message_(new Message) : message_(std::make_unique<Message>())
{ {
} }
MessagePtr MessageBuilder::getMessage() MessageBuilder::MessageBuilder(const QString &text)
: MessageBuilder()
{ {
return this->message_; this->emplace<TimestampElement>();
this->emplace<TextElement>(text, MessageElement::Text,
MessageColor::System);
this->message().searchText = text;
} }
void MessageBuilder::append(MessageElement *element) MessageBuilder::MessageBuilder(SystemMessageTag, const QString &text)
: MessageBuilder()
{ {
this->message_->addElement(element); this->emplace<TimestampElement>();
this->emplace<TextElement>(text, MessageElement::Text,
MessageColor::System);
this->message().flags |= Message::System;
this->message().flags |= Message::DoNotTriggerNotification;
this->message().searchText = text;
} }
void MessageBuilder::appendTimestamp() MessageBuilder::MessageBuilder(TimeoutMessageTag, const QString &username,
const QString &durationInSeconds,
const QString &reason, bool multipleTimes)
: MessageBuilder()
{ {
this->appendTimestamp(QTime::currentTime()); QString text;
}
void MessageBuilder::setHighlight(bool value) text.append(username);
{ if (!durationInSeconds.isEmpty()) {
if (value) { text.append(" has been timed out");
this->message_->flags |= Message::Highlighted;
// TODO: Implement who timed the user out
text.append(" for ");
bool ok = true;
int timeoutSeconds = durationInSeconds.toInt(&ok);
if (ok) {
text.append(formatTime(timeoutSeconds));
}
} else { } else {
this->message_->flags &= ~Message::Highlighted; text.append(" has been permanently banned");
} }
if (reason.length() > 0) {
text.append(": \"");
text.append(parseTagString(reason));
text.append("\"");
}
text.append(".");
if (multipleTimes) {
text.append(" (multiple times)");
}
this->message().flags.EnableFlag(Message::System);
this->message().flags.EnableFlag(Message::Timeout);
this->message().flags.EnableFlag(Message::DoNotTriggerNotification);
this->message().timeoutUser = username;
} }
void MessageBuilder::appendTimestamp(const QTime &time) MessageBuilder::MessageBuilder(const BanAction &action, uint32_t count)
{ {
this->append(new TimestampElement(time)); this->emplace<TimestampElement>();
this->message().flags.EnableFlag(Message::System);
this->message().flags.EnableFlag(Message::Timeout);
this->message().timeoutUser = action.target.name;
this->message().count = count;
QString text;
if (action.isBan()) {
if (action.reason.isEmpty()) {
text = QString("%1 banned %2.") //
.arg(action.source.name)
.arg(action.target.name);
} else {
text = QString("%1 banned %2: \"%3\".") //
.arg(action.source.name)
.arg(action.target.name)
.arg(action.reason);
}
} else {
if (action.reason.isEmpty()) {
text = QString("%1 timed out %2 for %3.") //
.arg(action.source.name)
.arg(action.target.name)
.arg(formatTime(action.duration));
} else {
text = QString("%1 timed out %2 for %3: \"%4\".") //
.arg(action.source.name)
.arg(action.target.name)
.arg(formatTime(action.duration))
.arg(action.reason);
}
if (count > 1) {
text.append(QString(" (%1 times)").arg(count));
}
}
this->emplace<TextElement>(text, MessageElement::Text,
MessageColor::System);
this->message().searchText = text;
}
MessageBuilder::MessageBuilder(const UnbanAction &action)
{
this->emplace<TimestampElement>();
this->message().flags.EnableFlag(Message::System);
this->message().flags.EnableFlag(Message::Untimeout);
this->message().timeoutUser = action.target.name;
QString text;
if (action.wasBan()) {
text = QString("%1 unbanned %2.") //
.arg(action.source.name)
.arg(action.target.name);
} else {
text = QString("%1 untimedout %2.") //
.arg(action.source.name)
.arg(action.target.name);
}
this->emplace<TextElement>(text, MessageElement::Text,
MessageColor::System);
this->message().searchText = text;
}
Message *MessageBuilder::operator->()
{
return this->message_.get();
}
Message &MessageBuilder::message()
{
return *this->message_;
}
MessagePtr MessageBuilder::release()
{
return MessagePtr(this->message_.release());
}
void MessageBuilder::append(std::unique_ptr<MessageElement> element)
{
this->message().elements.push_back(std::move(element));
} }
QString MessageBuilder::matchLink(const QString &string) QString MessageBuilder::matchLink(const QString &string)
+28 -12
View File
@@ -3,21 +3,36 @@
#include "messages/Message.hpp" #include "messages/Message.hpp"
#include <QRegularExpression> #include <QRegularExpression>
#include <ctime> #include <ctime>
namespace chatterino { namespace chatterino {
struct MessageBuilder { struct SystemMessageTag {
};
struct TimeoutMessageTag {
};
const SystemMessageTag systemMessage{};
const TimeoutMessageTag timeoutMessage{};
MessagePtr makeSystemMessage(const QString &text);
class MessageBuilder
{
public: public:
MessageBuilder(); MessageBuilder();
MessageBuilder(const QString &text);
MessageBuilder(SystemMessageTag, const QString &text);
MessageBuilder(TimeoutMessageTag, const QString &username,
const QString &durationInSeconds, const QString &reason,
bool multipleTimes);
MessageBuilder(const BanAction &action, uint32_t count = 1);
MessageBuilder(const UnbanAction &action);
MessagePtr getMessage(); Message *operator->();
Message &message();
MessagePtr release();
void setHighlight(bool value); void append(std::unique_ptr<MessageElement> element);
void append(MessageElement *element);
void appendTimestamp();
void appendTimestamp(const QTime &time);
QString matchLink(const QString &string); QString matchLink(const QString &string);
template <typename T, typename... Args> template <typename T, typename... Args>
@@ -26,13 +41,14 @@ public:
static_assert(std::is_base_of<MessageElement, T>::value, static_assert(std::is_base_of<MessageElement, T>::value,
"T must extend MessageElement"); "T must extend MessageElement");
T *element = new T(std::forward<Args>(args)...); auto unique = std::make_unique<T>(std::forward<Args>(args)...);
this->append(element); auto pointer = unique.get();
return element; this->append(std::move(unique));
return pointer;
} }
protected: private:
MessagePtr message_; std::unique_ptr<Message> message_;
}; };
} // namespace chatterino } // namespace chatterino
+1
View File
@@ -7,6 +7,7 @@
#include "messages/layouts/MessageLayoutContainer.hpp" #include "messages/layouts/MessageLayoutContainer.hpp"
#include "messages/layouts/MessageLayoutElement.hpp" #include "messages/layouts/MessageLayoutElement.hpp"
#include "singletons/Settings.hpp" #include "singletons/Settings.hpp"
#include "util/DebugCount.hpp"
namespace chatterino { namespace chatterino {
+3 -3
View File
@@ -5,6 +5,7 @@
#include "singletons/Emotes.hpp" #include "singletons/Emotes.hpp"
#include "singletons/Settings.hpp" #include "singletons/Settings.hpp"
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
#include "util/DebugCount.hpp"
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
@@ -32,7 +33,7 @@ MessageLayout::~MessageLayout()
DebugCount::decrease("message layout"); DebugCount::decrease("message layout");
} }
Message *MessageLayout::getMessage() const Message *MessageLayout::getMessage()
{ {
return this->message_.get(); return this->message_.get();
} }
@@ -104,8 +105,7 @@ void MessageLayout::actuallyLayout(int width, MessageElement::Flags _flags)
this->container_.begin(width, this->scale_, messageFlags); this->container_.begin(width, this->scale_, messageFlags);
for (const std::unique_ptr<MessageElement> &element : for (const auto &element : this->message_->elements) {
this->message_->getElements()) {
element->addToContainer(this->container_, _flags); element->addToContainer(this->container_, _flags);
} }
+1 -1
View File
@@ -28,7 +28,7 @@ public:
MessageLayout(MessagePtr message_); MessageLayout(MessagePtr message_);
~MessageLayout(); ~MessageLayout();
Message *getMessage(); const Message *getMessage();
// Height // Height
int getHeight() const; int getHeight() const;
+10 -7
View File
@@ -3,6 +3,7 @@
#include "common/Common.hpp" #include "common/Common.hpp"
#include "messages/LimitedQueueSnapshot.hpp" #include "messages/LimitedQueueSnapshot.hpp"
#include "messages/Message.hpp" #include "messages/Message.hpp"
#include "messages/MessageBuilder.hpp"
#include <QCoreApplication> #include <QCoreApplication>
@@ -189,8 +190,8 @@ void AbstractIrcServer::onConnected()
{ {
std::lock_guard<std::mutex> lock(this->channelMutex); std::lock_guard<std::mutex> lock(this->channelMutex);
MessagePtr connMsg = Message::createSystemMessage("connected to chat"); auto connected = makeSystemMessage("connected to chat");
MessagePtr reconnMsg = Message::createSystemMessage("reconnected to chat"); auto reconnected = makeSystemMessage("reconnected to chat");
for (std::weak_ptr<Channel> &weak : this->channels.values()) { for (std::weak_ptr<Channel> &weak : this->channels.values()) {
std::shared_ptr<Channel> chan = weak.lock(); std::shared_ptr<Channel> chan = weak.lock();
@@ -205,11 +206,12 @@ void AbstractIrcServer::onConnected()
Message::DisconnectedMessage; Message::DisconnectedMessage;
if (replaceMessage) { if (replaceMessage) {
chan->replaceMessage(snapshot[snapshot.getLength() - 1], reconnMsg); chan->replaceMessage(snapshot[snapshot.getLength() - 1],
reconnected);
continue; continue;
} }
chan->addMessage(connMsg); chan->addMessage(connected);
} }
} }
@@ -217,8 +219,9 @@ void AbstractIrcServer::onDisconnected()
{ {
std::lock_guard<std::mutex> lock(this->channelMutex); std::lock_guard<std::mutex> lock(this->channelMutex);
MessagePtr msg = Message::createSystemMessage("disconnected from chat"); MessageBuilder b(systemMessage, "disconnected from chat");
msg->flags |= Message::DisconnectedMessage; b->flags |= Message::DisconnectedMessage;
auto disconnected = b.release();
for (std::weak_ptr<Channel> &weak : this->channels.values()) { for (std::weak_ptr<Channel> &weak : this->channels.values()) {
std::shared_ptr<Channel> chan = weak.lock(); std::shared_ptr<Channel> chan = weak.lock();
@@ -226,7 +229,7 @@ void AbstractIrcServer::onDisconnected()
continue; continue;
} }
chan->addMessage(msg); chan->addMessage(disconnected);
} }
} }
+22 -17
View File
@@ -60,13 +60,16 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *_message,
TwitchMessageBuilder builder(chan.get(), _message, args, content, isAction); TwitchMessageBuilder builder(chan.get(), _message, args, content, isAction);
if (isSub || !builder.isIgnored()) { if (isSub || !builder.isIgnored()) {
MessagePtr msg = builder.build();
if (isSub) { if (isSub) {
msg->flags |= Message::Subscription; builder->flags |= Message::Subscription;
msg->flags &= ~Message::Highlighted; builder->flags &= ~Message::Highlighted;
} else { }
if (msg->flags & Message::Highlighted) {
auto highlighted = bool(builder->flags & Message::Highlighted);
auto msg = builder.build();
if (!isSub) {
if (highlighted) {
server.mentionsChannel->addMessage(msg); server.mentionsChannel->addMessage(msg);
getApp()->highlights->addHighlight(msg); getApp()->highlights->addHighlight(msg);
} }
@@ -151,8 +154,8 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
// check if the chat has been cleared by a moderator // check if the chat has been cleared by a moderator
if (message->parameters().length() == 1) { if (message->parameters().length() == 1) {
chan->disableAllMessages(); chan->disableAllMessages();
chan->addMessage(Message::createSystemMessage( chan->addMessage(
"Chat has been cleared by a moderator.")); makeSystemMessage("Chat has been cleared by a moderator."));
return; return;
} }
@@ -170,8 +173,9 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
reason = v.toString(); reason = v.toString();
} }
auto timeoutMsg = Message::createTimeoutMessage(username, durationInSeconds, auto timeoutMsg = MessageBuilder(timeoutMessage, username,
reason, false); durationInSeconds, reason, false)
.release();
chan->addOrReplaceTimeout(timeoutMsg); chan->addOrReplaceTimeout(timeoutMsg);
// refresh all // refresh all
@@ -216,17 +220,17 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
false); false);
if (!builder.isIgnored()) { if (!builder.isIgnored()) {
app->twitch.server->lastUserThatWhisperedMe.set(builder.userName);
MessagePtr _message = builder.build(); MessagePtr _message = builder.build();
if (_message->flags & Message::Highlighted) { if (_message->flags & Message::Highlighted) {
app->twitch.server->mentionsChannel->addMessage(_message); app->twitch.server->mentionsChannel->addMessage(_message);
} }
app->twitch.server->lastUserThatWhisperedMe.set(builder.userName);
c->addMessage(_message); c->addMessage(_message);
_message->flags |= Message::DoNotTriggerNotification; // _message->flags |= Message::DoNotTriggerNotification;
if (app->settings->inlineWhispers) { if (app->settings->inlineWhispers) {
app->twitch.server->forEachChannel([_message](ChannelPtr channel) { app->twitch.server->forEachChannel([_message](ChannelPtr channel) {
@@ -262,10 +266,11 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
auto it = tags.find("system-msg"); auto it = tags.find("system-msg");
if (it != tags.end()) { if (it != tags.end()) {
auto newMessage = auto b = MessageBuilder(systemMessage,
Message::createSystemMessage(parseTagString(it.value().toString())); parseTagString(it.value().toString()));
newMessage->flags |= Message::Subscription; b->flags |= Message::Subscription;
auto newMessage = b.release();
QString channelName; QString channelName;
@@ -306,7 +311,7 @@ void IrcMessageHandler::handleModeMessage(Communi::IrcMessage *message)
void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message) void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
{ {
auto app = getApp(); auto app = getApp();
MessagePtr msg = Message::createSystemMessage(message->content()); MessagePtr msg = makeSystemMessage(message->content());
QString channelName; QString channelName;
if (!trimChannelName(message->target(), channelName)) { if (!trimChannelName(message->target(), channelName)) {
+13 -13
View File
@@ -68,7 +68,7 @@ TwitchChannel::TwitchChannel(const QString &name)
// debugging // debugging
#if 0 #if 0
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
this->addMessage(Message::createSystemMessage("asdf")); this->addMessage(makeSystemMessage("asdf"));
} }
#endif #endif
} }
@@ -104,9 +104,9 @@ void TwitchChannel::sendMessage(const QString &message)
if (!app->accounts->twitch.isLoggedIn()) { if (!app->accounts->twitch.isLoggedIn()) {
// XXX: It would be nice if we could add a link here somehow that opened // XXX: It would be nice if we could add a link here somehow that opened
// the "account manager" dialog // the "account manager" dialog
this->addMessage(Message::createSystemMessage( this->addMessage(
"You need to log in to send messages. You can " makeSystemMessage("You need to log in to send messages. You can "
"link your Twitch account in the settings.")); "link your Twitch account in the settings."));
return; return;
} }
@@ -159,7 +159,7 @@ bool TwitchChannel::isBroadcaster() const
return this->getName() == app->accounts->twitch.getCurrent()->getUserName(); return this->getName() == app->accounts->twitch.getCurrent()->getUserName();
} }
void TwitchChannel::addRecentChatter(const std::shared_ptr<Message> &message) void TwitchChannel::addRecentChatter(const MessagePtr &message)
{ {
assert(!message->loginName.isEmpty()); assert(!message->loginName.isEmpty());
@@ -183,11 +183,11 @@ void TwitchChannel::addJoinedUser(const QString &user)
QTimer::singleShot(500, &this->lifetimeGuard_, [this] { QTimer::singleShot(500, &this->lifetimeGuard_, [this] {
auto joinedUsers = this->joinedUsers_.access(); auto joinedUsers = this->joinedUsers_.access();
auto message = Message::createSystemMessage( MessageBuilder builder(systemMessage,
"Users joined: " + joinedUsers->join(", ")); "Users joined: " + joinedUsers->join(", "));
message->flags |= Message::Collapsed; builder->flags |= Message::Collapsed;
joinedUsers->clear(); joinedUsers->clear();
this->addMessage(message); this->addMessage(builder.release());
this->joinedUsersMergeQueued_ = false; this->joinedUsersMergeQueued_ = false;
}); });
} }
@@ -211,10 +211,10 @@ void TwitchChannel::addPartedUser(const QString &user)
QTimer::singleShot(500, &this->lifetimeGuard_, [this] { QTimer::singleShot(500, &this->lifetimeGuard_, [this] {
auto partedUsers = this->partedUsers_.access(); auto partedUsers = this->partedUsers_.access();
auto message = Message::createSystemMessage( MessageBuilder builder(systemMessage,
"Users parted: " + partedUsers->join(", ")); "Users parted: " + partedUsers->join(", "));
message->flags |= Message::Collapsed; builder->flags |= Message::Collapsed;
this->addMessage(message); this->addMessage(builder.release());
partedUsers->clear(); partedUsers->clear();
this->partedUsersMergeQueued_ = false; this->partedUsersMergeQueued_ = false;
+1 -1
View File
@@ -54,7 +54,7 @@ public:
virtual void sendMessage(const QString &message) override; virtual void sendMessage(const QString &message) override;
// Auto completion // Auto completion
void addRecentChatter(const std::shared_ptr<Message> &message) final; void addRecentChatter(const MessagePtr &message) final;
void addJoinedUser(const QString &user); void addJoinedUser(const QString &user);
void addPartedUser(const QString &user); void addPartedUser(const QString &user);
+10 -14
View File
@@ -98,7 +98,7 @@ MessagePtr TwitchMessageBuilder::build()
// MessageElement::Collapsed); // MessageElement::Collapsed);
// } // }
//#endif //#endif
this->message_->flags |= Message::Collapsed; this->message().flags |= Message::Collapsed;
// PARSING // PARSING
this->parseMessageID(); this->parseMessageID();
@@ -175,9 +175,9 @@ MessagePtr TwitchMessageBuilder::build()
this->addWords(splits, twitchEmotes); this->addWords(splits, twitchEmotes);
this->message_->searchText = this->userName + ": " + this->originalMessage_; this->message().searchText = this->userName + ": " + this->originalMessage_;
return this->getMessage(); return this->release();
} }
void TwitchMessageBuilder::addWords( void TwitchMessageBuilder::addWords(
@@ -376,7 +376,7 @@ void TwitchMessageBuilder::parseUsername()
// this->userName + ")"; // this->userName + ")";
// } // }
this->message_->loginName = this->userName; this->message().loginName = this->userName;
} }
void TwitchMessageBuilder::appendUsername() void TwitchMessageBuilder::appendUsername()
@@ -384,7 +384,7 @@ void TwitchMessageBuilder::appendUsername()
auto app = getApp(); auto app = getApp();
QString username = this->userName; QString username = this->userName;
this->message_->loginName = username; this->message().loginName = username;
QString localizedName; QString localizedName;
auto iterator = this->tags.find("display-name"); auto iterator = this->tags.find("display-name");
@@ -396,12 +396,12 @@ void TwitchMessageBuilder::appendUsername()
Qt::CaseInsensitive) == 0) { Qt::CaseInsensitive) == 0) {
username = displayName; username = displayName;
this->message_->displayName = displayName; this->message().displayName = displayName;
} else { } else {
localizedName = displayName; localizedName = displayName;
this->message_->displayName = username; this->message().displayName = username;
this->message_->localizedName = displayName; this->message().localizedName = displayName;
} }
} }
@@ -573,7 +573,7 @@ void TwitchMessageBuilder::parseHighlights(bool isPastMsg)
} }
} }
this->setHighlight(doHighlight); this->message().flags.set(Message::Highlighted, doHighlight);
if (!isPastMsg) { if (!isPastMsg) {
if (playSound && if (playSound &&
@@ -586,10 +586,6 @@ void TwitchMessageBuilder::parseHighlights(bool isPastMsg)
2500); 2500);
} }
} }
if (doHighlight) {
this->message_->flags |= Message::Highlighted;
}
} }
} }
@@ -662,7 +658,7 @@ Outcome TwitchMessageBuilder::tryAppendEmote(const EmoteName &name)
// fourtf: this is ugly // fourtf: this is ugly
// maybe put the individual badges into a map instead of this // maybe put the individual badges into a map instead of this
//mess // mess
void TwitchMessageBuilder::appendTwitchBadges() void TwitchMessageBuilder::appendTwitchBadges()
{ {
auto app = getApp(); auto app = getApp();
+2 -2
View File
@@ -217,7 +217,7 @@ void TwitchServer::onMessageSendRequested(TwitchChannel *channel,
lastMessage.back() + minMessageOffset > now) { lastMessage.back() + minMessageOffset > now) {
if (this->lastErrorTimeSpeed_ + 30s < now) { if (this->lastErrorTimeSpeed_ + 30s < now) {
auto errorMessage = auto errorMessage =
Message::createSystemMessage("sending messages too fast"); makeSystemMessage("sending messages too fast");
channel->addMessage(errorMessage); channel->addMessage(errorMessage);
@@ -235,7 +235,7 @@ void TwitchServer::onMessageSendRequested(TwitchChannel *channel,
if (lastMessage.size() >= maxMessageCount) { if (lastMessage.size() >= maxMessageCount) {
if (this->lastErrorTimeAmount_ + 30s < now) { if (this->lastErrorTimeAmount_ + 30s < now) {
auto errorMessage = auto errorMessage =
Message::createSystemMessage("sending too many messages"); makeSystemMessage("sending too many messages");
channel->addMessage(errorMessage); channel->addMessage(errorMessage);
+1 -1
View File
@@ -79,7 +79,7 @@ void LoggingChannel::openLogFile()
this->appendLine(this->generateOpeningString(now)); this->appendLine(this->generateOpeningString(now));
} }
void LoggingChannel::addMessage(std::shared_ptr<Message> message) void LoggingChannel::addMessage(MessagePtr message)
{ {
QDateTime now = QDateTime::currentDateTime(); QDateTime now = QDateTime::currentDateTime();
+1 -1
View File
@@ -19,7 +19,7 @@ class LoggingChannel : boost::noncopyable
public: public:
~LoggingChannel(); ~LoggingChannel();
void addMessage(std::shared_ptr<Message> message); void addMessage(MessagePtr message);
private: private:
void openLogFile(); void openLogFile();
+46
View File
@@ -0,0 +1,46 @@
#include "FormatTime.hpp"
namespace chatterino {
namespace {
void appendDuration(int count, QChar &&order, QString &outString)
{
outString.append(QString::number(count));
outString.append(order);
}
} // namespace
QString formatTime(int totalSeconds)
{
QString res;
int seconds = totalSeconds % 60;
int timeoutMinutes = totalSeconds / 60;
int minutes = timeoutMinutes % 60;
int timeoutHours = timeoutMinutes / 60;
int hours = timeoutHours % 24;
int days = timeoutHours / 24;
if (days > 0) {
appendDuration(days, 'd', res);
}
if (hours > 0) {
if (!res.isEmpty()) {
res.append(" ");
}
appendDuration(hours, 'h', res);
}
if (minutes > 0) {
if (!res.isEmpty()) {
res.append(" ");
}
appendDuration(minutes, 'm', res);
}
if (seconds > 0) {
if (!res.isEmpty()) {
res.append(" ");
}
appendDuration(seconds, 's', res);
}
return res;
}
} // namespace chatterino
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <QString>
namespace chatterino {
// format: 1h 23m 42s
QString formatTime(int totalSeconds);
} // namespace chatterino
+32 -31
View File
@@ -63,24 +63,24 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
// TITLE // TITLE
MessageBuilder builder1; MessageBuilder builder1;
builder1.append(new TextElement(title, MessageElement::Text)); builder1.emplace<TextElement>(title, MessageElement::Text);
builder1.getMessage()->flags |= Message::Centered; builder1->flags |= Message::Centered;
emoteChannel->addMessage(builder1.getMessage()); emoteChannel->addMessage(builder1.release());
// EMOTES // EMOTES
MessageBuilder builder2; MessageBuilder builder2;
builder2.getMessage()->flags |= Message::Centered; builder2->flags |= Message::Centered;
builder2.getMessage()->flags |= Message::DisableCompactEmotes; builder2->flags |= Message::DisableCompactEmotes;
for (auto emote : map) { for (auto emote : map) {
builder2.append( builder2
(new EmoteElement(emote.second, .emplace<EmoteElement>(emote.second,
MessageElement::Flags::AlwaysShow)) MessageElement::Flags::AlwaysShow)
->setLink(Link(Link::InsertText, emote.first.string))); ->setLink(Link(Link::InsertText, emote.first.string));
} }
emoteChannel->addMessage(builder2.getMessage()); emoteChannel->addMessage(builder2.release());
}; };
auto app = getApp(); auto app = getApp();
@@ -103,25 +103,25 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
setText = set->text; setText = set->text;
} }
builder1.append(new TextElement(setText, MessageElement::Text)); builder1.emplace<TextElement>(setText, MessageElement::Text);
builder1.getMessage()->flags |= Message::Centered; builder1->flags |= Message::Centered;
emoteChannel->addMessage(builder1.getMessage()); emoteChannel->addMessage(builder1.release());
// EMOTES // EMOTES
MessageBuilder builder2; MessageBuilder builder2;
builder2.getMessage()->flags |= Message::Centered; builder2->flags |= Message::Centered;
builder2.getMessage()->flags |= Message::DisableCompactEmotes; builder2->flags |= Message::DisableCompactEmotes;
for (const auto &emote : set->emotes) { for (const auto &emote : set->emotes) {
builder2.append( builder2
(new EmoteElement( .emplace<EmoteElement>(
app->emotes->twitch.getOrCreateEmote(emote.id, emote.name), app->emotes->twitch.getOrCreateEmote(emote.id, emote.name),
MessageElement::Flags::AlwaysShow)) MessageElement::Flags::AlwaysShow)
->setLink(Link(Link::InsertText, emote.name.string))); ->setLink(Link(Link::InsertText, emote.name.string));
} }
emoteChannel->addMessage(builder2.getMessage()); emoteChannel->addMessage(builder2.release());
} }
addEmotes(*app->emotes->bttv.accessGlobalEmotes(), addEmotes(*app->emotes->bttv.accessGlobalEmotes(),
@@ -146,22 +146,23 @@ void EmotePopup::loadEmojis()
// title // title
MessageBuilder builder1; MessageBuilder builder1;
builder1.append(new TextElement("emojis", MessageElement::Text)); builder1.emplace<TextElement>("emojis", MessageElement::Text);
builder1.getMessage()->flags |= Message::Centered; builder1->flags |= Message::Centered;
emojiChannel->addMessage(builder1.getMessage()); emojiChannel->addMessage(builder1.release());
// emojis // emojis
MessageBuilder builder; MessageBuilder builder;
builder.getMessage()->flags |= Message::Centered; builder->flags |= Message::Centered;
builder.getMessage()->flags |= Message::DisableCompactEmotes; builder->flags |= Message::DisableCompactEmotes;
emojis.each([&builder](const auto &key, const auto &value) { emojis.each([&builder](const auto &key, const auto &value) {
builder.append( builder
(new EmoteElement(value->emote, MessageElement::Flags::AlwaysShow)) .emplace<EmoteElement>(value->emote,
->setLink(Link(Link::Type::InsertText, MessageElement::Flags::AlwaysShow)
":" + value->shortCodes[0] + ":"))); ->setLink(
Link(Link::Type::InsertText, ":" + value->shortCodes[0] + ":"));
}); });
emojiChannel->addMessage(builder.getMessage()); emojiChannel->addMessage(builder.release());
this->viewEmojis_->setChannel(emojiChannel); this->viewEmojis_->setChannel(emojiChannel);
} }
+9 -9
View File
@@ -170,15 +170,15 @@ void LogsPopup::getOverrustleLogs()
singleMessage.value("timestamp").toInt()) singleMessage.value("timestamp").toInt())
.time(); .time();
MessagePtr message(new Message); MessageBuilder builder;
message->addElement(new TimestampElement(timeStamp)); builder.emplace<TimestampElement>(timeStamp);
message->addElement(new TextElement(this->userName_, builder.emplace<TextElement>(this->userName_,
MessageElement::Username, MessageElement::Username,
MessageColor::System)); MessageColor::System);
message->addElement( builder.emplace<TextElement>(
new TextElement(singleMessage.value("text").toString(), singleMessage.value("text").toString(),
MessageElement::Text, MessageColor::Text)); MessageElement::Text, MessageColor::Text);
messages.push_back(message); messages.push_back(builder.release());
} }
} }
this->setMessages(messages); this->setMessages(messages);
+22 -45
View File
@@ -1,6 +1,7 @@
#include "LookPage.hpp" #include "LookPage.hpp"
#include "Application.hpp" #include "Application.hpp"
#include "messages/MessageBuilder.hpp"
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
#include "util/LayoutCreator.hpp" #include "util/LayoutCreator.hpp"
#include "util/RemoveScrollAreaBackground.hpp" #include "util/RemoveScrollAreaBackground.hpp"
@@ -317,55 +318,31 @@ ChannelPtr LookPage::createPreviewChannel()
{ {
auto channel = ChannelPtr(new Channel("preview", Channel::Type::Misc)); auto channel = ChannelPtr(new Channel("preview", Channel::Type::Misc));
// clang-format off
{ {
auto message = MessagePtr(new Message()); MessageBuilder builder;
message->addElement(new TimestampElement(QTime(8, 13, 42))); builder.emplace<TimestampElement>(QTime(8, 13, 42));
message->addElement(new ImageElement( builder.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->twitch.moderator), MessageElement::BadgeChannelAuthority);
Image::fromNonOwningPixmap(&getApp()->resources->twitch.moderator), builder.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->twitch.subscriber), MessageElement::BadgeSubscription);
MessageElement::BadgeChannelAuthority)); builder.emplace<TextElement>("username1:", MessageElement::Username, QColor("#0094FF"), FontStyle::ChatMediumBold);
message->addElement(new ImageElement( builder.emplace<TextElement>("This is a preview message", MessageElement::Text);
Image::fromNonOwningPixmap(&getApp()->resources->twitch.subscriber), builder.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->pajaDank), MessageElement::Flags::AlwaysShow);
MessageElement::BadgeSubscription)); builder.emplace<TextElement>("@fourtf", TextElement::BoldUsername, MessageColor::Text, FontStyle::ChatMediumBold);
message->addElement( builder.emplace<TextElement>("@fourtf", TextElement::NonBoldUsername);
new TextElement("username1:", MessageElement::Username, channel->addMessage(builder.release());
QColor("#0094FF"), FontStyle::ChatMediumBold));
message->addElement(
new TextElement("This is a preview message", MessageElement::Text));
message->addElement(new ImageElement(
Image::fromNonOwningPixmap(&getApp()->resources->pajaDank),
MessageElement::Flags::AlwaysShow));
message->addElement(
new TextElement("@fourtf", TextElement::BoldUsername,
MessageColor::Text, FontStyle::ChatMediumBold));
message->addElement(
new TextElement("@fourtf", TextElement::NonBoldUsername));
channel->addMessage(message);
} }
{ {
auto message = MessagePtr(new Message()); MessageBuilder message;
message->addElement(new TimestampElement(QTime(8, 15, 21))); message.emplace<TimestampElement>(QTime(8, 15, 21));
message->addElement( message.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->twitch.broadcaster), MessageElement::BadgeChannelAuthority);
new ImageElement(Image::fromNonOwningPixmap( message.emplace<TextElement>("username2:", MessageElement::Username, QColor("#FF6A00"), FontStyle::ChatMediumBold);
&getApp()->resources->twitch.broadcaster), message.emplace<TextElement>("This is another one", MessageElement::Text);
MessageElement::BadgeChannelAuthority)); // message.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->ppHop), MessageElement::BttvEmote);
message->addElement( message.emplace<TextElement>("www.fourtf.com", MessageElement::LowercaseLink, MessageColor::Link)->setLink(Link(Link::Url, "https://www.fourtf.com"));
new TextElement("username2:", MessageElement::Username, message.emplace<TextElement>("wWw.FoUrTf.CoM", MessageElement::OriginalLink, MessageColor::Link)->setLink(Link(Link::Url, "https://www.fourtf.com"));
QColor("#FF6A00"), FontStyle::ChatMediumBold)); channel->addMessage(message.release());
message->addElement(
new TextElement("This is another one", MessageElement::Text));
// message->addElement(new ImageElement(
// Image::fromNonOwningPixmap(&getApp()->resources->ppHop),
// MessageElement::BttvEmote));
message->addElement(
(new TextElement("www.fourtf.com", MessageElement::LowercaseLink,
MessageColor::Link))
->setLink(Link(Link::Url, "https://www.fourtf.com")));
message->addElement(
(new TextElement("wWw.FoUrTf.CoM", MessageElement::OriginalLink,
MessageColor::Link))
->setLink(Link(Link::Url, "https://www.fourtf.com")));
channel->addMessage(message);
} }
// clang-format on
return channel; return channel;
} }
View File