refactored MessageBuilder
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "debug/Log.hpp"
|
||||
#include "singletons/Emotes.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/DebugCount.hpp"
|
||||
#include "util/PostToThread.hpp"
|
||||
|
||||
#include <QBuffer>
|
||||
|
||||
+6
-191
@@ -1,20 +1,22 @@
|
||||
#include "messages/Message.hpp"
|
||||
#include "MessageElement.hpp"
|
||||
#include "providers/twitch/PubsubActions.hpp"
|
||||
#include "util/DebugCount.hpp"
|
||||
#include "util/IrcHelpers.hpp"
|
||||
|
||||
using SBHighlight = chatterino::ScrollbarHighlight;
|
||||
|
||||
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
|
||||
@@ -28,195 +30,8 @@ SBHighlight Message::getScrollBarHighlight() const
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -6,27 +6,13 @@
|
||||
#include "widgets/helper/ScrollbarHighlight.hpp"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "util/DebugCount.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
struct Message {
|
||||
Message()
|
||||
: parseTime(QTime::currentTime())
|
||||
{
|
||||
DebugCount::increase("messages");
|
||||
}
|
||||
|
||||
~Message()
|
||||
{
|
||||
DebugCount::decrease("messages");
|
||||
}
|
||||
|
||||
struct Message : boost::noncopyable {
|
||||
enum MessageFlags : uint16_t {
|
||||
None = 0,
|
||||
System = (1 << 0),
|
||||
@@ -43,6 +29,9 @@ struct Message {
|
||||
Subscription = (1 << 11),
|
||||
};
|
||||
|
||||
Message();
|
||||
~Message();
|
||||
|
||||
FlagsEnum<MessageFlags> flags;
|
||||
QTime parseTime;
|
||||
QString id;
|
||||
@@ -51,33 +40,12 @@ struct Message {
|
||||
QString displayName;
|
||||
QString localizedName;
|
||||
QString timeoutUser;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
||||
+143
-15
@@ -4,43 +4,171 @@
|
||||
#include "singletons/Emotes.hpp"
|
||||
#include "singletons/Resources.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "util/FormatTime.hpp"
|
||||
#include "util/IrcHelpers.hpp"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
MessagePtr makeSystemMessage(const QString &text)
|
||||
{
|
||||
return MessageBuilder(systemMessage, text).release();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (value) {
|
||||
this->message_->flags |= Message::Highlighted;
|
||||
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(formatTime(timeoutSeconds));
|
||||
}
|
||||
} 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)
|
||||
|
||||
@@ -3,21 +3,36 @@
|
||||
#include "messages/Message.hpp"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
struct MessageBuilder {
|
||||
struct SystemMessageTag {
|
||||
};
|
||||
struct TimeoutMessageTag {
|
||||
};
|
||||
const SystemMessageTag systemMessage{};
|
||||
const TimeoutMessageTag timeoutMessage{};
|
||||
|
||||
MessagePtr makeSystemMessage(const QString &text);
|
||||
|
||||
class MessageBuilder
|
||||
{
|
||||
public:
|
||||
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(MessageElement *element);
|
||||
void appendTimestamp();
|
||||
void appendTimestamp(const QTime &time);
|
||||
void append(std::unique_ptr<MessageElement> element);
|
||||
QString matchLink(const QString &string);
|
||||
|
||||
template <typename T, typename... Args>
|
||||
@@ -26,13 +41,14 @@ public:
|
||||
static_assert(std::is_base_of<MessageElement, T>::value,
|
||||
"T must extend MessageElement");
|
||||
|
||||
T *element = new T(std::forward<Args>(args)...);
|
||||
this->append(element);
|
||||
return element;
|
||||
auto unique = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
auto pointer = unique.get();
|
||||
this->append(std::move(unique));
|
||||
return pointer;
|
||||
}
|
||||
|
||||
protected:
|
||||
MessagePtr message_;
|
||||
private:
|
||||
std::unique_ptr<Message> message_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "messages/layouts/MessageLayoutContainer.hpp"
|
||||
#include "messages/layouts/MessageLayoutElement.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "util/DebugCount.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "singletons/Emotes.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/DebugCount.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
@@ -32,7 +33,7 @@ MessageLayout::~MessageLayout()
|
||||
DebugCount::decrease("message layout");
|
||||
}
|
||||
|
||||
Message *MessageLayout::getMessage()
|
||||
const Message *MessageLayout::getMessage()
|
||||
{
|
||||
return this->message_.get();
|
||||
}
|
||||
@@ -104,8 +105,7 @@ void MessageLayout::actuallyLayout(int width, MessageElement::Flags _flags)
|
||||
|
||||
this->container_.begin(width, this->scale_, messageFlags);
|
||||
|
||||
for (const std::unique_ptr<MessageElement> &element :
|
||||
this->message_->getElements()) {
|
||||
for (const auto &element : this->message_->elements) {
|
||||
element->addToContainer(this->container_, _flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
MessageLayout(MessagePtr message_);
|
||||
~MessageLayout();
|
||||
|
||||
Message *getMessage();
|
||||
const Message *getMessage();
|
||||
|
||||
// Height
|
||||
int getHeight() const;
|
||||
|
||||
Reference in New Issue
Block a user