mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Add Basic Elevated Message support (#4016)
This commit is contained in:
parent
9554b83c1a
commit
0ab59d44f0
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- Major: Added support for Twitch's Chat Replies. [Wiki Page](https://wiki.chatterino.com/Features/#message-replies) (#3722, #3989)
|
- Major: Added support for Twitch's Chat Replies. [Wiki Page](https://wiki.chatterino.com/Features/#message-replies) (#3722, #3989)
|
||||||
- Major: Added multi-channel searching to search dialog via keyboard shortcut. (Ctrl+Shift+F by default) (#3694, #3875)
|
- Major: Added multi-channel searching to search dialog via keyboard shortcut. (Ctrl+Shift+F by default) (#3694, #3875)
|
||||||
|
- Minor: Added highlights for `Elevated Messages`. (#4016)
|
||||||
- Minor: Removed total views from the usercard, as Twitch no longer updates the number. (#3792)
|
- Minor: Removed total views from the usercard, as Twitch no longer updates the number. (#3792)
|
||||||
- Minor: Load missing messages from Recent Messages API upon reconnecting (#3878, #3932)
|
- Minor: Load missing messages from Recent Messages API upon reconnecting (#3878, #3932)
|
||||||
- Minor: Reduced image memory usage when running Chatterino for a long time. (#3915)
|
- Minor: Reduced image memory usage when running Chatterino for a long time. (#3915)
|
||||||
|
|
|
@ -181,6 +181,38 @@ void HighlightModel::afterInit()
|
||||||
|
|
||||||
this->insertCustomRow(firstMessageRow,
|
this->insertCustomRow(firstMessageRow,
|
||||||
HighlightRowIndexes::FirstMessageRow);
|
HighlightRowIndexes::FirstMessageRow);
|
||||||
|
|
||||||
|
// Highlight settings for elevated messages
|
||||||
|
std::vector<QStandardItem *> elevatedMessageRow = this->createRow();
|
||||||
|
setBoolItem(elevatedMessageRow[Column::Pattern],
|
||||||
|
getSettings()->enableElevatedMessageHighlight.getValue(), true,
|
||||||
|
false);
|
||||||
|
elevatedMessageRow[Column::Pattern]->setData("Elevated Messages",
|
||||||
|
Qt::DisplayRole);
|
||||||
|
elevatedMessageRow[Column::ShowInMentions]->setFlags({});
|
||||||
|
// setBoolItem(elevatedMessageRow[Column::FlashTaskbar],
|
||||||
|
// getSettings()->enableElevatedMessageHighlightTaskbar.getValue(),
|
||||||
|
// true, false);
|
||||||
|
// setBoolItem(elevatedMessageRow[Column::PlaySound],
|
||||||
|
// getSettings()->enableElevatedMessageHighlightSound.getValue(),
|
||||||
|
// true, false);
|
||||||
|
elevatedMessageRow[Column::FlashTaskbar]->setFlags({});
|
||||||
|
elevatedMessageRow[Column::PlaySound]->setFlags({});
|
||||||
|
elevatedMessageRow[Column::UseRegex]->setFlags({});
|
||||||
|
elevatedMessageRow[Column::CaseSensitive]->setFlags({});
|
||||||
|
|
||||||
|
QUrl elevatedMessageSound =
|
||||||
|
QUrl(getSettings()->elevatedMessageHighlightSoundUrl.getValue());
|
||||||
|
setFilePathItem(elevatedMessageRow[Column::SoundPath], elevatedMessageSound,
|
||||||
|
false);
|
||||||
|
|
||||||
|
auto elevatedMessageColor =
|
||||||
|
ColorProvider::instance().color(ColorType::ElevatedMessageHighlight);
|
||||||
|
setColorItem(elevatedMessageRow[Column::Color], *elevatedMessageColor,
|
||||||
|
false);
|
||||||
|
|
||||||
|
this->insertCustomRow(elevatedMessageRow,
|
||||||
|
HighlightRowIndexes::ElevatedMessageRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||||
|
@ -215,6 +247,11 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||||
getSettings()->enableFirstMessageHighlight.setValue(
|
getSettings()->enableFirstMessageHighlight.setValue(
|
||||||
value.toBool());
|
value.toBool());
|
||||||
}
|
}
|
||||||
|
else if (rowIndex == HighlightRowIndexes::ElevatedMessageRow)
|
||||||
|
{
|
||||||
|
getSettings()->enableElevatedMessageHighlight.setValue(
|
||||||
|
value.toBool());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -257,6 +294,12 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||||
// getSettings()->enableFirstMessageHighlightTaskbar.setValue(
|
// getSettings()->enableFirstMessageHighlightTaskbar.setValue(
|
||||||
// value.toBool());
|
// value.toBool());
|
||||||
}
|
}
|
||||||
|
else if (rowIndex == HighlightRowIndexes::ElevatedMessageRow)
|
||||||
|
{
|
||||||
|
// getSettings()
|
||||||
|
// ->enableElevatedMessageHighlightTaskbar.setvalue(
|
||||||
|
// value.toBool());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -288,6 +331,11 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||||
// getSettings()->enableFirstMessageHighlightSound.setValue(
|
// getSettings()->enableFirstMessageHighlightSound.setValue(
|
||||||
// value.toBool());
|
// value.toBool());
|
||||||
}
|
}
|
||||||
|
else if (rowIndex == HighlightRowIndexes::ElevatedMessageRow)
|
||||||
|
{
|
||||||
|
// getSettings()->enableElevatedMessageHighlightSound.setValue(
|
||||||
|
// value.toBool());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -328,6 +376,11 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||||
getSettings()->firstMessageHighlightSoundUrl.setValue(
|
getSettings()->firstMessageHighlightSoundUrl.setValue(
|
||||||
value.toString());
|
value.toString());
|
||||||
}
|
}
|
||||||
|
if (rowIndex == HighlightRowIndexes::ElevatedMessageRow)
|
||||||
|
{
|
||||||
|
getSettings()->elevatedMessageHighlightSoundUrl.setValue(
|
||||||
|
value.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -363,6 +416,14 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||||
.updateColor(ColorType::FirstMessageHighlight,
|
.updateColor(ColorType::FirstMessageHighlight,
|
||||||
QColor(colorName));
|
QColor(colorName));
|
||||||
}
|
}
|
||||||
|
else if (rowIndex == HighlightRowIndexes::ElevatedMessageRow)
|
||||||
|
{
|
||||||
|
getSettings()->elevatedMessageHighlightColor.setValue(
|
||||||
|
colorName);
|
||||||
|
const_cast<ColorProvider &>(ColorProvider::instance())
|
||||||
|
.updateColor(ColorType::ElevatedMessageHighlight,
|
||||||
|
QColor(colorName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
SubRow = 2,
|
SubRow = 2,
|
||||||
RedeemedRow = 3,
|
RedeemedRow = 3,
|
||||||
FirstMessageRow = 4,
|
FirstMessageRow = 4,
|
||||||
|
ElevatedMessageRow = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -14,6 +14,8 @@ QColor HighlightPhrase::FALLBACK_REDEEMED_HIGHLIGHT_COLOR =
|
||||||
QColor(28, 126, 141, 60);
|
QColor(28, 126, 141, 60);
|
||||||
QColor HighlightPhrase::FALLBACK_FIRST_MESSAGE_HIGHLIGHT_COLOR =
|
QColor HighlightPhrase::FALLBACK_FIRST_MESSAGE_HIGHLIGHT_COLOR =
|
||||||
QColor(72, 127, 63, 60);
|
QColor(72, 127, 63, 60);
|
||||||
|
QColor HighlightPhrase::FALLBACK_ELEVATED_MESSAGE_HIGHLIGHT_COLOR =
|
||||||
|
QColor(255, 174, 66, 60);
|
||||||
QColor HighlightPhrase::FALLBACK_SUB_COLOR = QColor(196, 102, 255, 100);
|
QColor HighlightPhrase::FALLBACK_SUB_COLOR = QColor(196, 102, 255, 100);
|
||||||
|
|
||||||
bool HighlightPhrase::operator==(const HighlightPhrase &other) const
|
bool HighlightPhrase::operator==(const HighlightPhrase &other) const
|
||||||
|
|
|
@ -83,6 +83,7 @@ public:
|
||||||
static QColor FALLBACK_REDEEMED_HIGHLIGHT_COLOR;
|
static QColor FALLBACK_REDEEMED_HIGHLIGHT_COLOR;
|
||||||
static QColor FALLBACK_SUB_COLOR;
|
static QColor FALLBACK_SUB_COLOR;
|
||||||
static QColor FALLBACK_FIRST_MESSAGE_HIGHLIGHT_COLOR;
|
static QColor FALLBACK_FIRST_MESSAGE_HIGHLIGHT_COLOR;
|
||||||
|
static QColor FALLBACK_ELEVATED_MESSAGE_HIGHLIGHT_COLOR;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString pattern_;
|
QString pattern_;
|
||||||
|
|
|
@ -42,12 +42,19 @@ SBHighlight Message::getScrollBarHighlight() const
|
||||||
ColorProvider::instance().color(ColorType::RedeemedHighlight),
|
ColorProvider::instance().color(ColorType::RedeemedHighlight),
|
||||||
SBHighlight::Default, true);
|
SBHighlight::Default, true);
|
||||||
}
|
}
|
||||||
|
else if (this->flags.has(MessageFlag::ElevatedMessage))
|
||||||
|
{
|
||||||
|
return SBHighlight(ColorProvider::instance().color(
|
||||||
|
ColorType::ElevatedMessageHighlight),
|
||||||
|
SBHighlight::Default, false, false, true);
|
||||||
|
}
|
||||||
else if (this->flags.has(MessageFlag::FirstMessage))
|
else if (this->flags.has(MessageFlag::FirstMessage))
|
||||||
{
|
{
|
||||||
return SBHighlight(
|
return SBHighlight(
|
||||||
ColorProvider::instance().color(ColorType::FirstMessageHighlight),
|
ColorProvider::instance().color(ColorType::FirstMessageHighlight),
|
||||||
SBHighlight::Default, false, true);
|
SBHighlight::Default, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SBHighlight();
|
return SBHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum class MessageFlag : uint32_t {
|
||||||
ShowInMentions = (1 << 22),
|
ShowInMentions = (1 << 22),
|
||||||
FirstMessage = (1 << 23),
|
FirstMessage = (1 << 23),
|
||||||
ReplyMessage = (1 << 24),
|
ReplyMessage = (1 << 24),
|
||||||
|
ElevatedMessage = (1 << 25),
|
||||||
};
|
};
|
||||||
using MessageFlags = FlagsEnum<MessageFlag>;
|
using MessageFlags = FlagsEnum<MessageFlag>;
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,15 @@ void MessageLayout::updateBuffer(QPixmap *buffer, int /*messageIndex*/,
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (this->message_->flags.has(MessageFlag::FirstMessage) &&
|
if (this->message_->flags.has(MessageFlag::ElevatedMessage) &&
|
||||||
|
getSettings()->enableElevatedMessageHighlight.getValue())
|
||||||
|
{
|
||||||
|
backgroundColor = blendColors(backgroundColor,
|
||||||
|
*ColorProvider::instance().color(
|
||||||
|
ColorType::ElevatedMessageHighlight));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (this->message_->flags.has(MessageFlag::FirstMessage) &&
|
||||||
getSettings()->enableFirstMessageHighlight.getValue())
|
getSettings()->enableFirstMessageHighlight.getValue())
|
||||||
{
|
{
|
||||||
backgroundColor = blendColors(
|
backgroundColor = blendColors(
|
||||||
|
|
|
@ -133,6 +133,20 @@ void ColorProvider::initTypeColorMap()
|
||||||
std::make_shared<QColor>(
|
std::make_shared<QColor>(
|
||||||
HighlightPhrase::FALLBACK_FIRST_MESSAGE_HIGHLIGHT_COLOR)});
|
HighlightPhrase::FALLBACK_FIRST_MESSAGE_HIGHLIGHT_COLOR)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
customColor = getSettings()->elevatedMessageHighlightColor;
|
||||||
|
if (QColor(customColor).isValid())
|
||||||
|
{
|
||||||
|
this->typeColorMap_.insert({ColorType::ElevatedMessageHighlight,
|
||||||
|
std::make_shared<QColor>(customColor)});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->typeColorMap_.insert(
|
||||||
|
{ColorType::ElevatedMessageHighlight,
|
||||||
|
std::make_shared<QColor>(
|
||||||
|
HighlightPhrase::FALLBACK_ELEVATED_MESSAGE_HIGHLIGHT_COLOR)});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorProvider::initDefaultColors()
|
void ColorProvider::initDefaultColors()
|
||||||
|
|
|
@ -13,6 +13,7 @@ enum class ColorType {
|
||||||
Whisper,
|
Whisper,
|
||||||
RedeemedHighlight,
|
RedeemedHighlight,
|
||||||
FirstMessageHighlight,
|
FirstMessageHighlight,
|
||||||
|
ElevatedMessageHighlight,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ColorProvider
|
class ColorProvider
|
||||||
|
|
|
@ -198,6 +198,11 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
this->message().flags.set(MessageFlag::FirstMessage);
|
this->message().flags.set(MessageFlag::FirstMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->tags.contains("pinned-chat-paid-amount"))
|
||||||
|
{
|
||||||
|
this->message().flags.set(MessageFlag::ElevatedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
// reply threads
|
// reply threads
|
||||||
if (this->thread_)
|
if (this->thread_)
|
||||||
{
|
{
|
||||||
|
|
|
@ -292,6 +292,17 @@ public:
|
||||||
QStringSetting firstMessageHighlightColor = {
|
QStringSetting firstMessageHighlightColor = {
|
||||||
"/highlighting/firstMessageHighlightColor", ""};
|
"/highlighting/firstMessageHighlightColor", ""};
|
||||||
|
|
||||||
|
BoolSetting enableElevatedMessageHighlight = {
|
||||||
|
"/highlighting/elevatedMessageHighlight/highlighted", true};
|
||||||
|
// BoolSetting enableElevatedMessageHighlightSound = {
|
||||||
|
// "/highlighting/elevatedMessageHighlight/enableSound", false};
|
||||||
|
// BoolSetting enableElevatedMessageHighlightTaskbar = {
|
||||||
|
// "/highlighting/elevatedMessageHighlight/enableTaskbarFlashing", false};
|
||||||
|
QStringSetting elevatedMessageHighlightSoundUrl = {
|
||||||
|
"/highlighting/elevatedMessageHighlight/soundUrl", ""};
|
||||||
|
QStringSetting elevatedMessageHighlightColor = {
|
||||||
|
"/highlighting/elevatedMessageHighlight/color", ""};
|
||||||
|
|
||||||
BoolSetting enableSubHighlight = {
|
BoolSetting enableSubHighlight = {
|
||||||
"/highlighting/subHighlight/subsHighlighted", true};
|
"/highlighting/subHighlight/subsHighlighted", true};
|
||||||
BoolSetting enableSubHighlightSound = {
|
BoolSetting enableSubHighlightSound = {
|
||||||
|
|
|
@ -106,6 +106,9 @@ const QStringList &getSampleMiscMessages()
|
||||||
|
|
||||||
// mod announcement
|
// mod announcement
|
||||||
R"(@badge-info=subscriber/47;badges=broadcaster/1,subscriber/3012,twitchconAmsterdam2020/1;color=#FF0000;display-name=Supinic;emotes=;flags=;id=8c26e1ab-b50c-4d9d-bc11-3fd57a941d90;login=supinic;mod=0;msg-id=announcement;msg-param-color=PRIMARY;room-id=31400525;subscriber=1;system-msg=;tmi-sent-ts=1648762219962;user-id=31400525;user-type= :tmi.twitch.tv USERNOTICE #supinic :mm test lol)",
|
R"(@badge-info=subscriber/47;badges=broadcaster/1,subscriber/3012,twitchconAmsterdam2020/1;color=#FF0000;display-name=Supinic;emotes=;flags=;id=8c26e1ab-b50c-4d9d-bc11-3fd57a941d90;login=supinic;mod=0;msg-id=announcement;msg-param-color=PRIMARY;room-id=31400525;subscriber=1;system-msg=;tmi-sent-ts=1648762219962;user-id=31400525;user-type= :tmi.twitch.tv USERNOTICE #supinic :mm test lol)",
|
||||||
|
|
||||||
|
// Elevated Message (Paid option for keeping a message in chat longer)
|
||||||
|
R"(@badge-info=subscriber/3;badges=subscriber/0,bits-charity/1;color=#0000FF;display-name=SnoopyTheBot;emotes=;first-msg=0;flags=;id=8779a9e5-cf1b-47b3-b9fe-67a5b1b605f6;mod=0;pinned-chat-paid-amount=500;pinned-chat-paid-canonical-amount=5;pinned-chat-paid-currency=USD;pinned-chat-paid-exponent=2;returning-chatter=0;room-id=36340781;subscriber=1;tmi-sent-ts=1664505974154;turbo=0;user-id=136881249;user-type= :snoopythebot!snoopythebot@snoopythebot.tmi.twitch.tv PRIVMSG #pajlada :-$5)",
|
||||||
};
|
};
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,8 @@ void Scrollbar::paintEvent(QPaintEvent *)
|
||||||
bool enableRedeemedHighlights = getSettings()->enableRedeemedHighlight;
|
bool enableRedeemedHighlights = getSettings()->enableRedeemedHighlight;
|
||||||
bool enableFirstMessageHighlights =
|
bool enableFirstMessageHighlights =
|
||||||
getSettings()->enableFirstMessageHighlight;
|
getSettings()->enableFirstMessageHighlight;
|
||||||
|
bool enableElevatedMessageHighlights =
|
||||||
|
getSettings()->enableElevatedMessageHighlight;
|
||||||
|
|
||||||
// painter.fillRect(QRect(xOffset, 0, width(), this->buttonHeight),
|
// painter.fillRect(QRect(xOffset, 0, width(), this->buttonHeight),
|
||||||
// this->themeManager->ScrollbarArrow);
|
// this->themeManager->ScrollbarArrow);
|
||||||
|
@ -313,6 +315,12 @@ void Scrollbar::paintEvent(QPaintEvent *)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (highlight.isElevatedMessageHighlight() &&
|
||||||
|
!enableElevatedMessageHighlights)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
QColor color = highlight.getColor();
|
QColor color = highlight.getColor();
|
||||||
color.setAlpha(255);
|
color.setAlpha(255);
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,13 @@ ScrollbarHighlight::ScrollbarHighlight()
|
||||||
|
|
||||||
ScrollbarHighlight::ScrollbarHighlight(const std::shared_ptr<QColor> color,
|
ScrollbarHighlight::ScrollbarHighlight(const std::shared_ptr<QColor> color,
|
||||||
Style style, bool isRedeemedHighlight,
|
Style style, bool isRedeemedHighlight,
|
||||||
bool isFirstMessageHighlight)
|
bool isFirstMessageHighlight,
|
||||||
|
bool isElevatedMessageHighlight)
|
||||||
: color_(color)
|
: color_(color)
|
||||||
, style_(style)
|
, style_(style)
|
||||||
, isRedeemedHighlight_(isRedeemedHighlight)
|
, isRedeemedHighlight_(isRedeemedHighlight)
|
||||||
, isFirstMessageHighlight_(isFirstMessageHighlight)
|
, isFirstMessageHighlight_(isFirstMessageHighlight)
|
||||||
|
, isElevatedMessageHighlight_(isElevatedMessageHighlight)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +44,11 @@ bool ScrollbarHighlight::isFirstMessageHighlight() const
|
||||||
return this->isFirstMessageHighlight_;
|
return this->isFirstMessageHighlight_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScrollbarHighlight::isElevatedMessageHighlight() const
|
||||||
|
{
|
||||||
|
return this->isElevatedMessageHighlight_;
|
||||||
|
}
|
||||||
|
|
||||||
bool ScrollbarHighlight::isNull() const
|
bool ScrollbarHighlight::isNull() const
|
||||||
{
|
{
|
||||||
return this->style_ == None || !this->color_;
|
return this->style_ == None || !this->color_;
|
||||||
|
|
|
@ -22,12 +22,14 @@ public:
|
||||||
|
|
||||||
ScrollbarHighlight(const std::shared_ptr<QColor> color,
|
ScrollbarHighlight(const std::shared_ptr<QColor> color,
|
||||||
Style style = Default, bool isRedeemedHighlight = false,
|
Style style = Default, bool isRedeemedHighlight = false,
|
||||||
bool isFirstMessageHighlight = false);
|
bool isFirstMessageHighlight = false,
|
||||||
|
bool isElevatedMessageHighlight = false);
|
||||||
|
|
||||||
QColor getColor() const;
|
QColor getColor() const;
|
||||||
Style getStyle() const;
|
Style getStyle() const;
|
||||||
bool isRedeemedHighlight() const;
|
bool isRedeemedHighlight() const;
|
||||||
bool isFirstMessageHighlight() const;
|
bool isFirstMessageHighlight() const;
|
||||||
|
bool isElevatedMessageHighlight() const;
|
||||||
bool isNull() const;
|
bool isNull() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -35,6 +37,7 @@ private:
|
||||||
Style style_;
|
Style style_;
|
||||||
bool isRedeemedHighlight_;
|
bool isRedeemedHighlight_;
|
||||||
bool isFirstMessageHighlight_;
|
bool isFirstMessageHighlight_;
|
||||||
|
bool isElevatedMessageHighlight_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
Loading…
Reference in a new issue