mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
refactored MessageBuilder
This commit is contained in:
parent
f71ff08e68
commit
c26422aec1
1020
chatterino.pro
1020
chatterino.pro
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,7 @@
|
|||
#include "controllers/ignores/IgnoreController.hpp"
|
||||
#include "controllers/moderationactions/ModerationActions.hpp"
|
||||
#include "controllers/taggedusers/TaggedUsersController.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
#include "providers/bttv/BttvEmotes.hpp"
|
||||
#include "providers/ffz/FfzEmotes.hpp"
|
||||
#include "providers/twitch/PubsubClient.hpp"
|
||||
|
@ -130,7 +131,7 @@ void Application::initPubsub()
|
|||
QString text =
|
||||
QString("%1 cleared the chat").arg(action.source.name);
|
||||
|
||||
auto msg = Message::createSystemMessage(text);
|
||||
auto msg = makeSystemMessage(text);
|
||||
postToThread([chan, msg] { chan->addMessage(msg); });
|
||||
});
|
||||
|
||||
|
@ -154,7 +155,7 @@ void Application::initPubsub()
|
|||
" seconds)");
|
||||
}
|
||||
|
||||
auto msg = Message::createSystemMessage(text);
|
||||
auto msg = makeSystemMessage(text);
|
||||
postToThread([chan, msg] { chan->addMessage(msg); });
|
||||
});
|
||||
|
||||
|
@ -176,7 +177,7 @@ void Application::initPubsub()
|
|||
.arg(action.source.name, action.target.name);
|
||||
}
|
||||
|
||||
auto msg = Message::createSystemMessage(text);
|
||||
auto msg = makeSystemMessage(text);
|
||||
postToThread([chan, msg] { chan->addMessage(msg); });
|
||||
});
|
||||
|
||||
|
@ -189,10 +190,12 @@ void Application::initPubsub()
|
|||
return;
|
||||
}
|
||||
|
||||
auto msg = Message::createTimeoutMessage(action);
|
||||
MessageBuilder msg(action);
|
||||
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(
|
||||
|
@ -204,7 +207,7 @@ void Application::initPubsub()
|
|||
return;
|
||||
}
|
||||
|
||||
auto msg = Message::createUntimeoutMessage(action);
|
||||
auto msg = MessageBuilder(action).release();
|
||||
|
||||
postToThread([chan, msg] { chan->addMessage(msg); });
|
||||
});
|
||||
|
|
|
@ -47,29 +47,29 @@ public:
|
|||
|
||||
friend void test();
|
||||
|
||||
Settings *const settings = nullptr;
|
||||
Paths *const paths = nullptr;
|
||||
Settings *const settings{};
|
||||
Paths *const paths{};
|
||||
Resources2 *const resources;
|
||||
|
||||
Theme *const themes = nullptr;
|
||||
Fonts *const fonts = nullptr;
|
||||
Emotes *const emotes = nullptr;
|
||||
WindowManager *const windows = nullptr;
|
||||
Theme *const themes{};
|
||||
Fonts *const fonts{};
|
||||
Emotes *const emotes{};
|
||||
WindowManager *const windows{};
|
||||
|
||||
AccountController *const accounts = nullptr;
|
||||
CommandController *const commands = nullptr;
|
||||
HighlightController *const highlights = nullptr;
|
||||
IgnoreController *const ignores = nullptr;
|
||||
TaggedUsersController *const taggedUsers = nullptr;
|
||||
ModerationActions *const moderationActions = nullptr;
|
||||
TwitchServer *const twitch2 = nullptr;
|
||||
AccountController *const accounts{};
|
||||
CommandController *const commands{};
|
||||
HighlightController *const highlights{};
|
||||
IgnoreController *const ignores{};
|
||||
TaggedUsersController *const taggedUsers{};
|
||||
ModerationActions *const moderationActions{};
|
||||
TwitchServer *const twitch2{};
|
||||
|
||||
[[deprecated]] Logging *const logging = nullptr;
|
||||
/*[[deprecated]]*/ Logging *const logging{};
|
||||
|
||||
/// Provider-specific
|
||||
struct {
|
||||
[[deprecated("use twitch2 instead")]] TwitchServer *server = nullptr;
|
||||
[[deprecated("use twitch2->pubsub instead")]] PubSub *pubsub = nullptr;
|
||||
/*[[deprecated("use twitch2 instead")]]*/ TwitchServer *server{};
|
||||
/*[[deprecated("use twitch2->pubsub instead")]]*/ PubSub *pubsub{};
|
||||
} twitch;
|
||||
|
||||
private:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Application.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
#include "singletons/Emotes.hpp"
|
||||
#include "singletons/Logging.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
|
@ -124,15 +125,15 @@ void Channel::addOrReplaceTimeout(MessagePtr message)
|
|||
|
||||
int count = s->count + 1;
|
||||
|
||||
MessagePtr replacement(Message::createSystemMessage(
|
||||
message->searchText + QString(" (") + QString::number(count) +
|
||||
" times)"));
|
||||
MessageBuilder replacement(systemMessage,
|
||||
message->searchText + QString(" (") +
|
||||
QString::number(count) + " times)");
|
||||
|
||||
replacement->timeoutUser = message->timeoutUser;
|
||||
replacement->count = count;
|
||||
replacement->flags = message->flags;
|
||||
|
||||
this->replaceMessage(s, replacement);
|
||||
this->replaceMessage(s, replacement.release());
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -143,7 +144,8 @@ void Channel::addOrReplaceTimeout(MessagePtr message)
|
|||
auto &s = snapshot[i];
|
||||
if ((s->flags & (Message::Timeout | Message::Untimeout)) == 0 &&
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
void addOrReplaceTimeout(MessagePtr message);
|
||||
void disableAllMessages();
|
||||
void replaceMessage(MessagePtr message, MessagePtr replacement);
|
||||
virtual void addRecentChatter(const std::shared_ptr<Message> &message);
|
||||
virtual void addRecentChatter(const MessagePtr &message);
|
||||
|
||||
QStringList modList;
|
||||
|
||||
|
|
|
@ -54,6 +54,24 @@ public:
|
|||
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
|
||||
{
|
||||
return (this->value & flag) == flag;
|
||||
|
|
|
@ -141,16 +141,17 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
if (getSettings()->inlineWhispers) {
|
||||
app->twitch.server->forEachChannel(
|
||||
[&b](ChannelPtr _channel) {
|
||||
_channel->addMessage(b.getMessage());
|
||||
[&messagexD](ChannelPtr _channel) {
|
||||
_channel->addMessage(messagexD);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -166,7 +167,7 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
if (commandName == "/debug-args") {
|
||||
QString msg = QApplication::instance()->arguments().join(' ');
|
||||
|
||||
channel->addMessage(Message::createSystemMessage(msg));
|
||||
channel->addMessage(makeSystemMessage(msg));
|
||||
|
||||
return "";
|
||||
} else if (commandName == "/uptime") {
|
||||
|
@ -176,13 +177,13 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
? streamStatus->uptime
|
||||
: "Channel is not live.";
|
||||
|
||||
channel->addMessage(Message::createSystemMessage(messageText));
|
||||
channel->addMessage(makeSystemMessage(messageText));
|
||||
|
||||
return "";
|
||||
} else if (commandName == "/ignore") {
|
||||
if (words.size() < 2) {
|
||||
channel->addMessage(
|
||||
Message::createSystemMessage("Usage: /ignore [user]"));
|
||||
makeSystemMessage("Usage: /ignore [user]"));
|
||||
return "";
|
||||
}
|
||||
auto app = getApp();
|
||||
|
@ -191,21 +192,21 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
auto target = words.at(1);
|
||||
|
||||
if (user->isAnon()) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"You must be logged in to ignore someone"));
|
||||
return "";
|
||||
}
|
||||
|
||||
user->ignore(target, [channel](auto resultCode,
|
||||
const QString &message) {
|
||||
channel->addMessage(Message::createSystemMessage(message));
|
||||
});
|
||||
user->ignore(
|
||||
target, [channel](auto resultCode, const QString &message) {
|
||||
channel->addMessage(makeSystemMessage(message));
|
||||
});
|
||||
|
||||
return "";
|
||||
} else if (commandName == "/unignore") {
|
||||
if (words.size() < 2) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
"Usage: /unignore [user]"));
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Usage: /unignore [user]"));
|
||||
return "";
|
||||
}
|
||||
auto app = getApp();
|
||||
|
@ -214,21 +215,21 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
auto target = words.at(1);
|
||||
|
||||
if (user->isAnon()) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"You must be logged in to ignore someone"));
|
||||
return "";
|
||||
}
|
||||
|
||||
user->unignore(target, [channel](auto resultCode,
|
||||
const QString &message) {
|
||||
channel->addMessage(Message::createSystemMessage(message));
|
||||
});
|
||||
user->unignore(
|
||||
target, [channel](auto resultCode, const QString &message) {
|
||||
channel->addMessage(makeSystemMessage(message));
|
||||
});
|
||||
|
||||
return "";
|
||||
} else if (commandName == "/follow") {
|
||||
if (words.size() < 2) {
|
||||
channel->addMessage(
|
||||
Message::createSystemMessage("Usage: /follow [user]"));
|
||||
makeSystemMessage("Usage: /follow [user]"));
|
||||
return "";
|
||||
}
|
||||
auto app = getApp();
|
||||
|
@ -237,7 +238,7 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
auto target = words.at(1);
|
||||
|
||||
if (user->isAnon()) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"You must be logged in to follow someone"));
|
||||
return "";
|
||||
}
|
||||
|
@ -245,12 +246,12 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
TwitchApi::findUserId(
|
||||
target, [user, channel, target](QString userId) {
|
||||
if (userId.isEmpty()) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"User " + target + " could not be followed!"));
|
||||
return;
|
||||
}
|
||||
user->followUser(userId, [channel, target]() {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"You successfully followed " + target));
|
||||
});
|
||||
});
|
||||
|
@ -258,8 +259,8 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
return "";
|
||||
} else if (commandName == "/unfollow") {
|
||||
if (words.size() < 2) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
"Usage: /unfollow [user]"));
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Usage: /unfollow [user]"));
|
||||
return "";
|
||||
}
|
||||
auto app = getApp();
|
||||
|
@ -268,7 +269,7 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
auto target = words.at(1);
|
||||
|
||||
if (user->isAnon()) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"You must be logged in to follow someone"));
|
||||
return "";
|
||||
}
|
||||
|
@ -276,12 +277,12 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
TwitchApi::findUserId(
|
||||
target, [user, channel, target](QString userId) {
|
||||
if (userId.isEmpty()) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"User " + target + " could not be followed!"));
|
||||
return;
|
||||
}
|
||||
user->unfollowUser(userId, [channel, target]() {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"You successfully unfollowed " + target));
|
||||
});
|
||||
});
|
||||
|
@ -289,8 +290,8 @@ QString CommandController::execCommand(const QString &text, ChannelPtr channel,
|
|||
return "";
|
||||
} else if (commandName == "/logs") {
|
||||
if (words.size() < 2) {
|
||||
channel->addMessage(Message::createSystemMessage(
|
||||
"Usage: /logs [user] (channel)"));
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Usage: /logs [user] (channel)"));
|
||||
return "";
|
||||
}
|
||||
auto app = getApp();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "common/Common.hpp"
|
||||
#include "messages/LimitedQueueSnapshot.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
|
@ -189,8 +190,8 @@ void AbstractIrcServer::onConnected()
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||
|
||||
MessagePtr connMsg = Message::createSystemMessage("connected to chat");
|
||||
MessagePtr reconnMsg = Message::createSystemMessage("reconnected to chat");
|
||||
auto connected = makeSystemMessage("connected to chat");
|
||||
auto reconnected = makeSystemMessage("reconnected to chat");
|
||||
|
||||
for (std::weak_ptr<Channel> &weak : this->channels.values()) {
|
||||
std::shared_ptr<Channel> chan = weak.lock();
|
||||
|
@ -205,11 +206,12 @@ void AbstractIrcServer::onConnected()
|
|||
Message::DisconnectedMessage;
|
||||
|
||||
if (replaceMessage) {
|
||||
chan->replaceMessage(snapshot[snapshot.getLength() - 1], reconnMsg);
|
||||
chan->replaceMessage(snapshot[snapshot.getLength() - 1],
|
||||
reconnected);
|
||||
continue;
|
||||
}
|
||||
|
||||
chan->addMessage(connMsg);
|
||||
chan->addMessage(connected);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,8 +219,9 @@ void AbstractIrcServer::onDisconnected()
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||
|
||||
MessagePtr msg = Message::createSystemMessage("disconnected from chat");
|
||||
msg->flags |= Message::DisconnectedMessage;
|
||||
MessageBuilder b(systemMessage, "disconnected from chat");
|
||||
b->flags |= Message::DisconnectedMessage;
|
||||
auto disconnected = b.release();
|
||||
|
||||
for (std::weak_ptr<Channel> &weak : this->channels.values()) {
|
||||
std::shared_ptr<Channel> chan = weak.lock();
|
||||
|
@ -226,7 +229,7 @@ void AbstractIrcServer::onDisconnected()
|
|||
continue;
|
||||
}
|
||||
|
||||
chan->addMessage(msg);
|
||||
chan->addMessage(disconnected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,13 +60,16 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *_message,
|
|||
TwitchMessageBuilder builder(chan.get(), _message, args, content, isAction);
|
||||
|
||||
if (isSub || !builder.isIgnored()) {
|
||||
MessagePtr msg = builder.build();
|
||||
|
||||
if (isSub) {
|
||||
msg->flags |= Message::Subscription;
|
||||
msg->flags &= ~Message::Highlighted;
|
||||
} else {
|
||||
if (msg->flags & Message::Highlighted) {
|
||||
builder->flags |= Message::Subscription;
|
||||
builder->flags &= ~Message::Highlighted;
|
||||
}
|
||||
|
||||
auto highlighted = bool(builder->flags & Message::Highlighted);
|
||||
auto msg = builder.build();
|
||||
|
||||
if (!isSub) {
|
||||
if (highlighted) {
|
||||
server.mentionsChannel->addMessage(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
|
||||
if (message->parameters().length() == 1) {
|
||||
chan->disableAllMessages();
|
||||
chan->addMessage(Message::createSystemMessage(
|
||||
"Chat has been cleared by a moderator."));
|
||||
chan->addMessage(
|
||||
makeSystemMessage("Chat has been cleared by a moderator."));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -170,8 +173,9 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
|||
reason = v.toString();
|
||||
}
|
||||
|
||||
auto timeoutMsg = Message::createTimeoutMessage(username, durationInSeconds,
|
||||
reason, false);
|
||||
auto timeoutMsg = MessageBuilder(timeoutMessage, username,
|
||||
durationInSeconds, reason, false)
|
||||
.release();
|
||||
chan->addOrReplaceTimeout(timeoutMsg);
|
||||
|
||||
// refresh all
|
||||
|
@ -216,17 +220,17 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
|
|||
false);
|
||||
|
||||
if (!builder.isIgnored()) {
|
||||
app->twitch.server->lastUserThatWhisperedMe.set(builder.userName);
|
||||
|
||||
MessagePtr _message = builder.build();
|
||||
|
||||
if (_message->flags & Message::Highlighted) {
|
||||
app->twitch.server->mentionsChannel->addMessage(_message);
|
||||
}
|
||||
|
||||
app->twitch.server->lastUserThatWhisperedMe.set(builder.userName);
|
||||
|
||||
c->addMessage(_message);
|
||||
|
||||
_message->flags |= Message::DoNotTriggerNotification;
|
||||
// _message->flags |= Message::DoNotTriggerNotification;
|
||||
|
||||
if (app->settings->inlineWhispers) {
|
||||
app->twitch.server->forEachChannel([_message](ChannelPtr channel) {
|
||||
|
@ -262,10 +266,11 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
|||
auto it = tags.find("system-msg");
|
||||
|
||||
if (it != tags.end()) {
|
||||
auto newMessage =
|
||||
Message::createSystemMessage(parseTagString(it.value().toString()));
|
||||
auto b = MessageBuilder(systemMessage,
|
||||
parseTagString(it.value().toString()));
|
||||
|
||||
newMessage->flags |= Message::Subscription;
|
||||
b->flags |= Message::Subscription;
|
||||
auto newMessage = b.release();
|
||||
|
||||
QString channelName;
|
||||
|
||||
|
@ -306,7 +311,7 @@ void IrcMessageHandler::handleModeMessage(Communi::IrcMessage *message)
|
|||
void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||
{
|
||||
auto app = getApp();
|
||||
MessagePtr msg = Message::createSystemMessage(message->content());
|
||||
MessagePtr msg = makeSystemMessage(message->content());
|
||||
|
||||
QString channelName;
|
||||
if (!trimChannelName(message->target(), channelName)) {
|
||||
|
|
|
@ -68,7 +68,7 @@ TwitchChannel::TwitchChannel(const QString &name)
|
|||
// debugging
|
||||
#if 0
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
this->addMessage(Message::createSystemMessage("asdf"));
|
||||
this->addMessage(makeSystemMessage("asdf"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ void TwitchChannel::sendMessage(const QString &message)
|
|||
if (!app->accounts->twitch.isLoggedIn()) {
|
||||
// XXX: It would be nice if we could add a link here somehow that opened
|
||||
// the "account manager" dialog
|
||||
this->addMessage(Message::createSystemMessage(
|
||||
"You need to log in to send messages. You can "
|
||||
"link your Twitch account in the settings."));
|
||||
this->addMessage(
|
||||
makeSystemMessage("You need to log in to send messages. You can "
|
||||
"link your Twitch account in the settings."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ bool TwitchChannel::isBroadcaster() const
|
|||
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());
|
||||
|
||||
|
@ -183,11 +183,11 @@ void TwitchChannel::addJoinedUser(const QString &user)
|
|||
QTimer::singleShot(500, &this->lifetimeGuard_, [this] {
|
||||
auto joinedUsers = this->joinedUsers_.access();
|
||||
|
||||
auto message = Message::createSystemMessage(
|
||||
"Users joined: " + joinedUsers->join(", "));
|
||||
message->flags |= Message::Collapsed;
|
||||
MessageBuilder builder(systemMessage,
|
||||
"Users joined: " + joinedUsers->join(", "));
|
||||
builder->flags |= Message::Collapsed;
|
||||
joinedUsers->clear();
|
||||
this->addMessage(message);
|
||||
this->addMessage(builder.release());
|
||||
this->joinedUsersMergeQueued_ = false;
|
||||
});
|
||||
}
|
||||
|
@ -211,10 +211,10 @@ void TwitchChannel::addPartedUser(const QString &user)
|
|||
QTimer::singleShot(500, &this->lifetimeGuard_, [this] {
|
||||
auto partedUsers = this->partedUsers_.access();
|
||||
|
||||
auto message = Message::createSystemMessage(
|
||||
"Users parted: " + partedUsers->join(", "));
|
||||
message->flags |= Message::Collapsed;
|
||||
this->addMessage(message);
|
||||
MessageBuilder builder(systemMessage,
|
||||
"Users parted: " + partedUsers->join(", "));
|
||||
builder->flags |= Message::Collapsed;
|
||||
this->addMessage(builder.release());
|
||||
partedUsers->clear();
|
||||
|
||||
this->partedUsersMergeQueued_ = false;
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
virtual void sendMessage(const QString &message) override;
|
||||
|
||||
// Auto completion
|
||||
void addRecentChatter(const std::shared_ptr<Message> &message) final;
|
||||
void addRecentChatter(const MessagePtr &message) final;
|
||||
void addJoinedUser(const QString &user);
|
||||
void addPartedUser(const QString &user);
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ MessagePtr TwitchMessageBuilder::build()
|
|||
// MessageElement::Collapsed);
|
||||
// }
|
||||
//#endif
|
||||
this->message_->flags |= Message::Collapsed;
|
||||
this->message().flags |= Message::Collapsed;
|
||||
|
||||
// PARSING
|
||||
this->parseMessageID();
|
||||
|
@ -175,9 +175,9 @@ MessagePtr TwitchMessageBuilder::build()
|
|||
|
||||
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(
|
||||
|
@ -376,7 +376,7 @@ void TwitchMessageBuilder::parseUsername()
|
|||
// this->userName + ")";
|
||||
// }
|
||||
|
||||
this->message_->loginName = this->userName;
|
||||
this->message().loginName = this->userName;
|
||||
}
|
||||
|
||||
void TwitchMessageBuilder::appendUsername()
|
||||
|
@ -384,7 +384,7 @@ void TwitchMessageBuilder::appendUsername()
|
|||
auto app = getApp();
|
||||
|
||||
QString username = this->userName;
|
||||
this->message_->loginName = username;
|
||||
this->message().loginName = username;
|
||||
QString localizedName;
|
||||
|
||||
auto iterator = this->tags.find("display-name");
|
||||
|
@ -396,12 +396,12 @@ void TwitchMessageBuilder::appendUsername()
|
|||
Qt::CaseInsensitive) == 0) {
|
||||
username = displayName;
|
||||
|
||||
this->message_->displayName = displayName;
|
||||
this->message().displayName = displayName;
|
||||
} else {
|
||||
localizedName = displayName;
|
||||
|
||||
this->message_->displayName = username;
|
||||
this->message_->localizedName = displayName;
|
||||
this->message().displayName = username;
|
||||
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 (playSound &&
|
||||
|
@ -586,10 +586,6 @@ void TwitchMessageBuilder::parseHighlights(bool isPastMsg)
|
|||
2500);
|
||||
}
|
||||
}
|
||||
|
||||
if (doHighlight) {
|
||||
this->message_->flags |= Message::Highlighted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,7 +658,7 @@ Outcome TwitchMessageBuilder::tryAppendEmote(const EmoteName &name)
|
|||
|
||||
// fourtf: this is ugly
|
||||
// maybe put the individual badges into a map instead of this
|
||||
//mess
|
||||
// mess
|
||||
void TwitchMessageBuilder::appendTwitchBadges()
|
||||
{
|
||||
auto app = getApp();
|
||||
|
|
|
@ -217,7 +217,7 @@ void TwitchServer::onMessageSendRequested(TwitchChannel *channel,
|
|||
lastMessage.back() + minMessageOffset > now) {
|
||||
if (this->lastErrorTimeSpeed_ + 30s < now) {
|
||||
auto errorMessage =
|
||||
Message::createSystemMessage("sending messages too fast");
|
||||
makeSystemMessage("sending messages too fast");
|
||||
|
||||
channel->addMessage(errorMessage);
|
||||
|
||||
|
@ -235,7 +235,7 @@ void TwitchServer::onMessageSendRequested(TwitchChannel *channel,
|
|||
if (lastMessage.size() >= maxMessageCount) {
|
||||
if (this->lastErrorTimeAmount_ + 30s < now) {
|
||||
auto errorMessage =
|
||||
Message::createSystemMessage("sending too many messages");
|
||||
makeSystemMessage("sending too many messages");
|
||||
|
||||
channel->addMessage(errorMessage);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ void LoggingChannel::openLogFile()
|
|||
this->appendLine(this->generateOpeningString(now));
|
||||
}
|
||||
|
||||
void LoggingChannel::addMessage(std::shared_ptr<Message> message)
|
||||
void LoggingChannel::addMessage(MessagePtr message)
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class LoggingChannel : boost::noncopyable
|
|||
|
||||
public:
|
||||
~LoggingChannel();
|
||||
void addMessage(std::shared_ptr<Message> message);
|
||||
void addMessage(MessagePtr message);
|
||||
|
||||
private:
|
||||
void openLogFile();
|
||||
|
|
46
src/util/FormatTime.cpp
Normal file
46
src/util/FormatTime.cpp
Normal 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
src/util/FormatTime.hpp
Normal file
10
src/util/FormatTime.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
// format: 1h 23m 42s
|
||||
QString formatTime(int totalSeconds);
|
||||
|
||||
} // namespace chatterino
|
|
@ -63,24 +63,24 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
|
|||
// TITLE
|
||||
MessageBuilder builder1;
|
||||
|
||||
builder1.append(new TextElement(title, MessageElement::Text));
|
||||
builder1.emplace<TextElement>(title, MessageElement::Text);
|
||||
|
||||
builder1.getMessage()->flags |= Message::Centered;
|
||||
emoteChannel->addMessage(builder1.getMessage());
|
||||
builder1->flags |= Message::Centered;
|
||||
emoteChannel->addMessage(builder1.release());
|
||||
|
||||
// EMOTES
|
||||
MessageBuilder builder2;
|
||||
builder2.getMessage()->flags |= Message::Centered;
|
||||
builder2.getMessage()->flags |= Message::DisableCompactEmotes;
|
||||
builder2->flags |= Message::Centered;
|
||||
builder2->flags |= Message::DisableCompactEmotes;
|
||||
|
||||
for (auto emote : map) {
|
||||
builder2.append(
|
||||
(new EmoteElement(emote.second,
|
||||
MessageElement::Flags::AlwaysShow))
|
||||
->setLink(Link(Link::InsertText, emote.first.string)));
|
||||
builder2
|
||||
.emplace<EmoteElement>(emote.second,
|
||||
MessageElement::Flags::AlwaysShow)
|
||||
->setLink(Link(Link::InsertText, emote.first.string));
|
||||
}
|
||||
|
||||
emoteChannel->addMessage(builder2.getMessage());
|
||||
emoteChannel->addMessage(builder2.release());
|
||||
};
|
||||
|
||||
auto app = getApp();
|
||||
|
@ -103,25 +103,25 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
|
|||
setText = set->text;
|
||||
}
|
||||
|
||||
builder1.append(new TextElement(setText, MessageElement::Text));
|
||||
builder1.emplace<TextElement>(setText, MessageElement::Text);
|
||||
|
||||
builder1.getMessage()->flags |= Message::Centered;
|
||||
emoteChannel->addMessage(builder1.getMessage());
|
||||
builder1->flags |= Message::Centered;
|
||||
emoteChannel->addMessage(builder1.release());
|
||||
|
||||
// EMOTES
|
||||
MessageBuilder builder2;
|
||||
builder2.getMessage()->flags |= Message::Centered;
|
||||
builder2.getMessage()->flags |= Message::DisableCompactEmotes;
|
||||
builder2->flags |= Message::Centered;
|
||||
builder2->flags |= Message::DisableCompactEmotes;
|
||||
|
||||
for (const auto &emote : set->emotes) {
|
||||
builder2.append(
|
||||
(new EmoteElement(
|
||||
app->emotes->twitch.getOrCreateEmote(emote.id, emote.name),
|
||||
MessageElement::Flags::AlwaysShow))
|
||||
->setLink(Link(Link::InsertText, emote.name.string)));
|
||||
builder2
|
||||
.emplace<EmoteElement>(
|
||||
app->emotes->twitch.getOrCreateEmote(emote.id, emote.name),
|
||||
MessageElement::Flags::AlwaysShow)
|
||||
->setLink(Link(Link::InsertText, emote.name.string));
|
||||
}
|
||||
|
||||
emoteChannel->addMessage(builder2.getMessage());
|
||||
emoteChannel->addMessage(builder2.release());
|
||||
}
|
||||
|
||||
addEmotes(*app->emotes->bttv.accessGlobalEmotes(),
|
||||
|
@ -146,22 +146,23 @@ void EmotePopup::loadEmojis()
|
|||
// title
|
||||
MessageBuilder builder1;
|
||||
|
||||
builder1.append(new TextElement("emojis", MessageElement::Text));
|
||||
builder1.getMessage()->flags |= Message::Centered;
|
||||
emojiChannel->addMessage(builder1.getMessage());
|
||||
builder1.emplace<TextElement>("emojis", MessageElement::Text);
|
||||
builder1->flags |= Message::Centered;
|
||||
emojiChannel->addMessage(builder1.release());
|
||||
|
||||
// emojis
|
||||
MessageBuilder builder;
|
||||
builder.getMessage()->flags |= Message::Centered;
|
||||
builder.getMessage()->flags |= Message::DisableCompactEmotes;
|
||||
builder->flags |= Message::Centered;
|
||||
builder->flags |= Message::DisableCompactEmotes;
|
||||
|
||||
emojis.each([&builder](const auto &key, const auto &value) {
|
||||
builder.append(
|
||||
(new EmoteElement(value->emote, MessageElement::Flags::AlwaysShow))
|
||||
->setLink(Link(Link::Type::InsertText,
|
||||
":" + value->shortCodes[0] + ":")));
|
||||
builder
|
||||
.emplace<EmoteElement>(value->emote,
|
||||
MessageElement::Flags::AlwaysShow)
|
||||
->setLink(
|
||||
Link(Link::Type::InsertText, ":" + value->shortCodes[0] + ":"));
|
||||
});
|
||||
emojiChannel->addMessage(builder.getMessage());
|
||||
emojiChannel->addMessage(builder.release());
|
||||
|
||||
this->viewEmojis_->setChannel(emojiChannel);
|
||||
}
|
||||
|
|
|
@ -170,15 +170,15 @@ void LogsPopup::getOverrustleLogs()
|
|||
singleMessage.value("timestamp").toInt())
|
||||
.time();
|
||||
|
||||
MessagePtr message(new Message);
|
||||
message->addElement(new TimestampElement(timeStamp));
|
||||
message->addElement(new TextElement(this->userName_,
|
||||
MessageElement::Username,
|
||||
MessageColor::System));
|
||||
message->addElement(
|
||||
new TextElement(singleMessage.value("text").toString(),
|
||||
MessageElement::Text, MessageColor::Text));
|
||||
messages.push_back(message);
|
||||
MessageBuilder builder;
|
||||
builder.emplace<TimestampElement>(timeStamp);
|
||||
builder.emplace<TextElement>(this->userName_,
|
||||
MessageElement::Username,
|
||||
MessageColor::System);
|
||||
builder.emplace<TextElement>(
|
||||
singleMessage.value("text").toString(),
|
||||
MessageElement::Text, MessageColor::Text);
|
||||
messages.push_back(builder.release());
|
||||
}
|
||||
}
|
||||
this->setMessages(messages);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "LookPage.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "util/RemoveScrollAreaBackground.hpp"
|
||||
|
@ -317,55 +318,31 @@ ChannelPtr LookPage::createPreviewChannel()
|
|||
{
|
||||
auto channel = ChannelPtr(new Channel("preview", Channel::Type::Misc));
|
||||
|
||||
// clang-format off
|
||||
{
|
||||
auto message = MessagePtr(new Message());
|
||||
message->addElement(new TimestampElement(QTime(8, 13, 42)));
|
||||
message->addElement(new ImageElement(
|
||||
Image::fromNonOwningPixmap(&getApp()->resources->twitch.moderator),
|
||||
MessageElement::BadgeChannelAuthority));
|
||||
message->addElement(new ImageElement(
|
||||
Image::fromNonOwningPixmap(&getApp()->resources->twitch.subscriber),
|
||||
MessageElement::BadgeSubscription));
|
||||
message->addElement(
|
||||
new TextElement("username1:", MessageElement::Username,
|
||||
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);
|
||||
MessageBuilder builder;
|
||||
builder.emplace<TimestampElement>(QTime(8, 13, 42));
|
||||
builder.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->twitch.moderator), MessageElement::BadgeChannelAuthority);
|
||||
builder.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->twitch.subscriber), MessageElement::BadgeSubscription);
|
||||
builder.emplace<TextElement>("username1:", MessageElement::Username, QColor("#0094FF"), FontStyle::ChatMediumBold);
|
||||
builder.emplace<TextElement>("This is a preview message", MessageElement::Text);
|
||||
builder.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->pajaDank), MessageElement::Flags::AlwaysShow);
|
||||
builder.emplace<TextElement>("@fourtf", TextElement::BoldUsername, MessageColor::Text, FontStyle::ChatMediumBold);
|
||||
builder.emplace<TextElement>("@fourtf", TextElement::NonBoldUsername);
|
||||
channel->addMessage(builder.release());
|
||||
}
|
||||
{
|
||||
auto message = MessagePtr(new Message());
|
||||
message->addElement(new TimestampElement(QTime(8, 15, 21)));
|
||||
message->addElement(
|
||||
new ImageElement(Image::fromNonOwningPixmap(
|
||||
&getApp()->resources->twitch.broadcaster),
|
||||
MessageElement::BadgeChannelAuthority));
|
||||
message->addElement(
|
||||
new TextElement("username2:", MessageElement::Username,
|
||||
QColor("#FF6A00"), FontStyle::ChatMediumBold));
|
||||
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);
|
||||
MessageBuilder message;
|
||||
message.emplace<TimestampElement>(QTime(8, 15, 21));
|
||||
message.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->twitch.broadcaster), MessageElement::BadgeChannelAuthority);
|
||||
message.emplace<TextElement>("username2:", MessageElement::Username, QColor("#FF6A00"), FontStyle::ChatMediumBold);
|
||||
message.emplace<TextElement>("This is another one", MessageElement::Text);
|
||||
// message.emplace<ImageElement>(Image::fromNonOwningPixmap(&getApp()->resources->ppHop), MessageElement::BttvEmote);
|
||||
message.emplace<TextElement>("www.fourtf.com", MessageElement::LowercaseLink, MessageColor::Link)->setLink(Link(Link::Url, "https://www.fourtf.com"));
|
||||
message.emplace<TextElement>("wWw.FoUrTf.CoM", MessageElement::OriginalLink, MessageColor::Link)->setLink(Link(Link::Url, "https://www.fourtf.com"));
|
||||
channel->addMessage(message.release());
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue