mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
feat: include more data when copying messages as JSON (#5600)
This commit is contained in:
parent
edf18a7a0f
commit
e149be3820
|
@ -90,6 +90,7 @@
|
||||||
- Dev: The timer for `StreamerMode` is now destroyed on the correct thread. (#5571)
|
- Dev: The timer for `StreamerMode` is now destroyed on the correct thread. (#5571)
|
||||||
- Dev: Cleanup some parts of the `magic_enum` adaptation for Qt. (#5587)
|
- Dev: Cleanup some parts of the `magic_enum` adaptation for Qt. (#5587)
|
||||||
- Dev: Refactored `static`s in headers to only be present once in the final app. (#5588)
|
- Dev: Refactored `static`s in headers to only be present once in the final app. (#5588)
|
||||||
|
- Dev: The JSON output when copying a message (<kbd>SHIFT</kbd> + right-click) is now more extensive. (#5600)
|
||||||
|
|
||||||
## 2.5.1
|
## 2.5.1
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
#include "messages/Emote.hpp"
|
#include "messages/Emote.hpp"
|
||||||
|
|
||||||
|
#include "common/Literals.hpp"
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
using namespace literals;
|
||||||
|
|
||||||
bool operator==(const Emote &a, const Emote &b)
|
bool operator==(const Emote &a, const Emote &b)
|
||||||
{
|
{
|
||||||
return std::tie(a.homePage, a.name, a.tooltip, a.images) ==
|
return std::tie(a.homePage, a.name, a.tooltip, a.images) ==
|
||||||
|
@ -15,6 +21,37 @@ bool operator!=(const Emote &a, const Emote &b)
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject Emote::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject obj{
|
||||||
|
{"name"_L1, this->name.string},
|
||||||
|
{"images"_L1, this->images.toJson()},
|
||||||
|
{"tooltip"_L1, this->tooltip.string},
|
||||||
|
};
|
||||||
|
if (!this->homePage.string.isEmpty())
|
||||||
|
{
|
||||||
|
obj["homePage"_L1] = this->homePage.string;
|
||||||
|
}
|
||||||
|
if (this->zeroWidth)
|
||||||
|
{
|
||||||
|
obj["zeroWidth"_L1] = this->zeroWidth;
|
||||||
|
}
|
||||||
|
if (!this->id.string.isEmpty())
|
||||||
|
{
|
||||||
|
obj["id"_L1] = this->id.string;
|
||||||
|
}
|
||||||
|
if (!this->author.string.isEmpty())
|
||||||
|
{
|
||||||
|
obj["author"_L1] = this->author.string;
|
||||||
|
}
|
||||||
|
if (this->baseName)
|
||||||
|
{
|
||||||
|
obj["baseName"_L1] = this->baseName->string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
EmotePtr cachedOrMakeEmotePtr(Emote &&emote, const EmoteMap &cache)
|
EmotePtr cachedOrMakeEmotePtr(Emote &&emote, const EmoteMap &cache)
|
||||||
{
|
{
|
||||||
// reuse old shared_ptr if nothing changed
|
// reuse old shared_ptr if nothing changed
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class QJsonObject;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
struct Emote {
|
struct Emote {
|
||||||
|
@ -30,6 +32,8 @@ struct Emote {
|
||||||
{
|
{
|
||||||
return name.string;
|
return name.string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(const Emote &a, const Emote &b);
|
bool operator==(const Emote &a, const Emote &b);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "messages/Image.hpp"
|
#include "messages/Image.hpp"
|
||||||
#include "singletons/Settings.hpp"
|
#include "singletons/Settings.hpp"
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
ImageSet::ImageSet()
|
ImageSet::ImageSet()
|
||||||
|
@ -135,4 +137,22 @@ bool ImageSet::operator!=(const ImageSet &other) const
|
||||||
return !this->operator==(other);
|
return !this->operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ImageSet::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject obj;
|
||||||
|
if (!this->imageX1_->isEmpty())
|
||||||
|
{
|
||||||
|
obj[u"1x"] = this->imageX1_->url().string;
|
||||||
|
}
|
||||||
|
if (!this->imageX2_->isEmpty())
|
||||||
|
{
|
||||||
|
obj[u"2x"] = this->imageX2_->url().string;
|
||||||
|
}
|
||||||
|
if (!this->imageX3_->isEmpty())
|
||||||
|
{
|
||||||
|
obj[u"3x"] = this->imageX3_->url().string;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class QJsonObject;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class Image;
|
class Image;
|
||||||
|
@ -34,6 +36,8 @@ public:
|
||||||
bool operator==(const ImageSet &other) const;
|
bool operator==(const ImageSet &other) const;
|
||||||
bool operator!=(const ImageSet &other) const;
|
bool operator!=(const ImageSet &other) const;
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImagePtr imageX1_;
|
ImagePtr imageX1_;
|
||||||
ImagePtr imageX2_;
|
ImagePtr imageX2_;
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
#include "messages/Message.hpp"
|
#include "messages/Message.hpp"
|
||||||
|
|
||||||
|
#include "Application.hpp"
|
||||||
|
#include "common/Literals.hpp"
|
||||||
|
#include "messages/MessageThread.hpp"
|
||||||
#include "providers/colors/ColorProvider.hpp"
|
#include "providers/colors/ColorProvider.hpp"
|
||||||
#include "providers/twitch/TwitchBadge.hpp"
|
#include "providers/twitch/TwitchBadge.hpp"
|
||||||
#include "singletons/Settings.hpp"
|
#include "singletons/Settings.hpp"
|
||||||
#include "util/DebugCount.hpp"
|
#include "util/DebugCount.hpp"
|
||||||
|
#include "util/QMagicEnum.hpp"
|
||||||
#include "widgets/helper/ScrollbarHighlight.hpp"
|
#include "widgets/helper/ScrollbarHighlight.hpp"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
using namespace literals;
|
||||||
|
|
||||||
Message::Message()
|
Message::Message()
|
||||||
: parseTime(QTime::currentTime())
|
: parseTime(QTime::currentTime())
|
||||||
{
|
{
|
||||||
|
@ -80,4 +90,72 @@ ScrollbarHighlight Message::getScrollBarHighlight() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject Message::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject msg{
|
||||||
|
{"flags"_L1, qmagicenum::enumFlagsName(this->flags.value())},
|
||||||
|
{"id"_L1, this->id},
|
||||||
|
{"searchText"_L1, this->searchText},
|
||||||
|
{"messageText"_L1, this->messageText},
|
||||||
|
{"loginName"_L1, this->loginName},
|
||||||
|
{"displayName"_L1, this->displayName},
|
||||||
|
{"localizedName"_L1, this->localizedName},
|
||||||
|
{"timeoutUser"_L1, this->timeoutUser},
|
||||||
|
{"channelName"_L1, this->channelName},
|
||||||
|
{"usernameColor"_L1, this->usernameColor.name(QColor::HexArgb)},
|
||||||
|
{"count"_L1, static_cast<qint64>(this->count)},
|
||||||
|
{"serverReceivedTime"_L1,
|
||||||
|
this->serverReceivedTime.toString(Qt::ISODate)},
|
||||||
|
};
|
||||||
|
|
||||||
|
QJsonArray badges;
|
||||||
|
for (const auto &badge : this->badges)
|
||||||
|
{
|
||||||
|
badges.append(badge.key_);
|
||||||
|
}
|
||||||
|
msg["badges"_L1] = badges;
|
||||||
|
|
||||||
|
QJsonObject badgeInfos;
|
||||||
|
for (const auto &[key, value] : this->badgeInfos)
|
||||||
|
{
|
||||||
|
badgeInfos.insert(key, value);
|
||||||
|
}
|
||||||
|
msg["badgeInfos"_L1] = badgeInfos;
|
||||||
|
|
||||||
|
if (this->highlightColor)
|
||||||
|
{
|
||||||
|
msg["highlightColor"_L1] = this->highlightColor->name(QColor::HexArgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->replyThread)
|
||||||
|
{
|
||||||
|
msg["replyThread"_L1] = this->replyThread->toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->replyParent)
|
||||||
|
{
|
||||||
|
msg["replyParent"_L1] = this->replyParent->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->reward)
|
||||||
|
{
|
||||||
|
msg["reward"_L1] = this->reward->toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: figure out if we can add this in tests
|
||||||
|
if (!getApp()->isTest())
|
||||||
|
{
|
||||||
|
msg["parseTime"_L1] = this->parseTime.toString(Qt::ISODate);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonArray elements;
|
||||||
|
for (const auto &element : this->elements)
|
||||||
|
{
|
||||||
|
elements.append(element->toJson());
|
||||||
|
}
|
||||||
|
msg["elements"_L1] = elements;
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class QJsonObject;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
class MessageElement;
|
class MessageElement;
|
||||||
class MessageThread;
|
class MessageThread;
|
||||||
|
@ -62,6 +64,8 @@ struct Message {
|
||||||
ScrollbarHighlight getScrollBarHighlight() const;
|
ScrollbarHighlight getScrollBarHighlight() const;
|
||||||
|
|
||||||
std::shared_ptr<ChannelPointReward> reward = nullptr;
|
std::shared_ptr<ChannelPointReward> reward = nullptr;
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -33,4 +33,21 @@ const QColor &MessageColor::getColor(Theme &themeManager) const
|
||||||
return _default;
|
return _default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString MessageColor::toString() const
|
||||||
|
{
|
||||||
|
switch (this->type_)
|
||||||
|
{
|
||||||
|
case Type::Custom:
|
||||||
|
return this->customColor_.name(QColor::HexArgb);
|
||||||
|
case Type::Text:
|
||||||
|
return QStringLiteral("Text");
|
||||||
|
case Type::System:
|
||||||
|
return QStringLiteral("System");
|
||||||
|
case Type::Link:
|
||||||
|
return QStringLiteral("Link");
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
class Theme;
|
class Theme;
|
||||||
|
@ -13,6 +14,8 @@ struct MessageColor {
|
||||||
|
|
||||||
const QColor &getColor(Theme &themeManager) const;
|
const QColor &getColor(Theme &themeManager) const;
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type type_;
|
Type type_;
|
||||||
QColor customColor_;
|
QColor customColor_;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "messages/MessageElement.hpp"
|
#include "messages/MessageElement.hpp"
|
||||||
|
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
|
#include "common/Literals.hpp"
|
||||||
#include "controllers/moderationactions/ModerationAction.hpp"
|
#include "controllers/moderationactions/ModerationAction.hpp"
|
||||||
#include "debug/Benchmark.hpp"
|
#include "debug/Benchmark.hpp"
|
||||||
#include "messages/Emote.hpp"
|
#include "messages/Emote.hpp"
|
||||||
|
@ -14,8 +15,14 @@
|
||||||
#include "util/DebugCount.hpp"
|
#include "util/DebugCount.hpp"
|
||||||
#include "util/Variant.hpp"
|
#include "util/Variant.hpp"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
using namespace literals;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Computes the bounding box for the given vector of images
|
// Computes the bounding box for the given vector of images
|
||||||
|
@ -88,6 +95,22 @@ void MessageElement::addFlags(MessageElementFlags flags)
|
||||||
this->flags_.set(flags);
|
this->flags_.set(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject MessageElement::toJson() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
{"trailingSpace"_L1, this->trailingSpace},
|
||||||
|
{
|
||||||
|
"link"_L1,
|
||||||
|
{{
|
||||||
|
{"type"_L1, qmagicenum::enumNameString(this->link_.type)},
|
||||||
|
{"value"_L1, this->link_.value},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{"tooltip"_L1, this->tooltip_},
|
||||||
|
{"flags"_L1, qmagicenum::enumFlagsName(this->flags_.value())},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// IMAGE
|
// IMAGE
|
||||||
ImageElement::ImageElement(ImagePtr image, MessageElementFlags flags)
|
ImageElement::ImageElement(ImagePtr image, MessageElementFlags flags)
|
||||||
: MessageElement(flags)
|
: MessageElement(flags)
|
||||||
|
@ -108,6 +131,15 @@ void ImageElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ImageElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"ImageElement"_s;
|
||||||
|
base["url"_L1] = this->image_->url().string;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
CircularImageElement::CircularImageElement(ImagePtr image, int padding,
|
CircularImageElement::CircularImageElement(ImagePtr image, int padding,
|
||||||
QColor background,
|
QColor background,
|
||||||
MessageElementFlags flags)
|
MessageElementFlags flags)
|
||||||
|
@ -131,6 +163,17 @@ void CircularImageElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject CircularImageElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"CircularImageElement"_s;
|
||||||
|
base["url"_L1] = this->image_->url().string;
|
||||||
|
base["padding"_L1] = this->padding_;
|
||||||
|
base["background"_L1] = this->background_.name(QColor::HexArgb);
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// EMOTE
|
// EMOTE
|
||||||
EmoteElement::EmoteElement(const EmotePtr &emote, MessageElementFlags flags,
|
EmoteElement::EmoteElement(const EmotePtr &emote, MessageElementFlags flags,
|
||||||
const MessageColor &textElementColor)
|
const MessageColor &textElementColor)
|
||||||
|
@ -187,6 +230,19 @@ MessageLayoutElement *EmoteElement::makeImageLayoutElement(
|
||||||
return new ImageLayoutElement(*this, image, size);
|
return new ImageLayoutElement(*this, image, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject EmoteElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"EmoteElement"_s;
|
||||||
|
base["emote"_L1] = this->emote_->toJson();
|
||||||
|
if (this->textElement_)
|
||||||
|
{
|
||||||
|
base["text"_L1] = this->textElement_->toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
LayeredEmoteElement::LayeredEmoteElement(
|
LayeredEmoteElement::LayeredEmoteElement(
|
||||||
std::vector<LayeredEmoteElement::Emote> &&emotes, MessageElementFlags flags,
|
std::vector<LayeredEmoteElement::Emote> &&emotes, MessageElementFlags flags,
|
||||||
const MessageColor &textElementColor)
|
const MessageColor &textElementColor)
|
||||||
|
@ -350,6 +406,38 @@ std::vector<LayeredEmoteElement::Emote> LayeredEmoteElement::getUniqueEmotes()
|
||||||
return unique;
|
return unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject LayeredEmoteElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"LayeredEmoteElement"_s;
|
||||||
|
|
||||||
|
QJsonArray emotes;
|
||||||
|
for (const auto &emote : this->emotes_)
|
||||||
|
{
|
||||||
|
emotes.append({{
|
||||||
|
{"flags"_L1, qmagicenum::enumFlagsName(emote.flags.value())},
|
||||||
|
{"emote"_L1, emote.ptr->toJson()},
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
base["emotes"_L1] = emotes;
|
||||||
|
|
||||||
|
QJsonArray tooltips;
|
||||||
|
for (const auto &tooltip : this->emoteTooltips_)
|
||||||
|
{
|
||||||
|
emotes.append(tooltip);
|
||||||
|
}
|
||||||
|
base["tooltips"_L1] = tooltips;
|
||||||
|
|
||||||
|
if (this->textElement_)
|
||||||
|
{
|
||||||
|
base["text"_L1] = this->textElement_->toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
base["textElementColor"_L1] = this->textElementColor_.toString();
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// BADGE
|
// BADGE
|
||||||
BadgeElement::BadgeElement(const EmotePtr &emote, MessageElementFlags flags)
|
BadgeElement::BadgeElement(const EmotePtr &emote, MessageElementFlags flags)
|
||||||
: MessageElement(flags)
|
: MessageElement(flags)
|
||||||
|
@ -390,6 +478,15 @@ MessageLayoutElement *BadgeElement::makeImageLayoutElement(
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject BadgeElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"BadgeElement"_s;
|
||||||
|
base["emote"_L1] = this->emote_->toJson();
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// MOD BADGE
|
// MOD BADGE
|
||||||
ModBadgeElement::ModBadgeElement(const EmotePtr &data,
|
ModBadgeElement::ModBadgeElement(const EmotePtr &data,
|
||||||
MessageElementFlags flags_)
|
MessageElementFlags flags_)
|
||||||
|
@ -408,6 +505,14 @@ MessageLayoutElement *ModBadgeElement::makeImageLayoutElement(
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ModBadgeElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = BadgeElement::toJson();
|
||||||
|
base["type"_L1] = u"ModBadgeElement"_s;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// VIP BADGE
|
// VIP BADGE
|
||||||
VipBadgeElement::VipBadgeElement(const EmotePtr &data,
|
VipBadgeElement::VipBadgeElement(const EmotePtr &data,
|
||||||
MessageElementFlags flags_)
|
MessageElementFlags flags_)
|
||||||
|
@ -423,6 +528,14 @@ MessageLayoutElement *VipBadgeElement::makeImageLayoutElement(
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject VipBadgeElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = BadgeElement::toJson();
|
||||||
|
base["type"_L1] = u"VipBadgeElement"_s;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// FFZ Badge
|
// FFZ Badge
|
||||||
FfzBadgeElement::FfzBadgeElement(const EmotePtr &data,
|
FfzBadgeElement::FfzBadgeElement(const EmotePtr &data,
|
||||||
MessageElementFlags flags_, QColor color_)
|
MessageElementFlags flags_, QColor color_)
|
||||||
|
@ -440,6 +553,15 @@ MessageLayoutElement *FfzBadgeElement::makeImageLayoutElement(
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject FfzBadgeElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = BadgeElement::toJson();
|
||||||
|
base["type"_L1] = u"FfzBadgeElement"_s;
|
||||||
|
base["color"_L1] = this->color.name(QColor::HexArgb);
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// TEXT
|
// TEXT
|
||||||
TextElement::TextElement(const QString &text, MessageElementFlags flags,
|
TextElement::TextElement(const QString &text, MessageElementFlags flags,
|
||||||
const MessageColor &color, FontStyle style)
|
const MessageColor &color, FontStyle style)
|
||||||
|
@ -549,6 +671,17 @@ void TextElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject TextElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"TextElement"_s;
|
||||||
|
base["words"_L1] = QJsonArray::fromStringList(this->words_);
|
||||||
|
base["color"_L1] = this->color_.toString();
|
||||||
|
base["style"_L1] = qmagicenum::enumNameString(this->style_);
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
SingleLineTextElement::SingleLineTextElement(const QString &text,
|
SingleLineTextElement::SingleLineTextElement(const QString &text,
|
||||||
MessageElementFlags flags,
|
MessageElementFlags flags,
|
||||||
const MessageColor &color,
|
const MessageColor &color,
|
||||||
|
@ -677,6 +810,22 @@ void SingleLineTextElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject SingleLineTextElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"SingleLineTextElement"_s;
|
||||||
|
QJsonArray words;
|
||||||
|
for (const auto &word : this->words_)
|
||||||
|
{
|
||||||
|
words.append(word.text);
|
||||||
|
}
|
||||||
|
base["words"_L1] = words;
|
||||||
|
base["color"_L1] = this->color_.toString();
|
||||||
|
base["style"_L1] = qmagicenum::enumNameString(this->style_);
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
LinkElement::LinkElement(const Parsed &parsed, const QString &fullUrl,
|
LinkElement::LinkElement(const Parsed &parsed, const QString &fullUrl,
|
||||||
MessageElementFlags flags, const MessageColor &color,
|
MessageElementFlags flags, const MessageColor &color,
|
||||||
FontStyle style)
|
FontStyle style)
|
||||||
|
@ -701,6 +850,17 @@ Link LinkElement::getLink() const
|
||||||
return {Link::Url, this->linkInfo_.url()};
|
return {Link::Url, this->linkInfo_.url()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject LinkElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = TextElement::toJson();
|
||||||
|
base["type"_L1] = u"LinkElement"_s;
|
||||||
|
base["link"_L1] = this->linkInfo_.originalUrl();
|
||||||
|
base["lowercase"_L1] = QJsonArray::fromStringList(this->lowercase_);
|
||||||
|
base["original"_L1] = QJsonArray::fromStringList(this->original_);
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
MentionElement::MentionElement(const QString &displayName, QString loginName_,
|
MentionElement::MentionElement(const QString &displayName, QString loginName_,
|
||||||
MessageColor fallbackColor_,
|
MessageColor fallbackColor_,
|
||||||
MessageColor userColor_)
|
MessageColor userColor_)
|
||||||
|
@ -756,7 +916,24 @@ Link MentionElement::getLink() const
|
||||||
return {Link::UserInfo, this->userLoginName};
|
return {Link::UserInfo, this->userLoginName};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject MentionElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = TextElement::toJson();
|
||||||
|
base["type"_L1] = u"MentionElement"_s;
|
||||||
|
base["fallbackColor"_L1] = this->fallbackColor.toString();
|
||||||
|
base["userColor"_L1] = this->userColor.toString();
|
||||||
|
base["userLoginName"_L1] = this->userLoginName;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// TIMESTAMP
|
// TIMESTAMP
|
||||||
|
TimestampElement::TimestampElement()
|
||||||
|
: TimestampElement(getApp()->isTest() ? QTime::fromMSecsSinceStartOfDay(0)
|
||||||
|
: QTime::currentTime())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
TimestampElement::TimestampElement(QTime time)
|
TimestampElement::TimestampElement(QTime time)
|
||||||
: MessageElement(MessageElementFlag::Timestamp)
|
: MessageElement(MessageElementFlag::Timestamp)
|
||||||
, time_(time)
|
, time_(time)
|
||||||
|
@ -790,6 +967,17 @@ TextElement *TimestampElement::formatTime(const QTime &time)
|
||||||
MessageColor::System, FontStyle::ChatMedium);
|
MessageColor::System, FontStyle::ChatMedium);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject TimestampElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"TimestampElement"_s;
|
||||||
|
base["time"_L1] = this->time_.toString(Qt::ISODate);
|
||||||
|
base["element"_L1] = this->element_->toJson();
|
||||||
|
base["format"_L1] = this->format_;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
// TWITCH MODERATION
|
// TWITCH MODERATION
|
||||||
TwitchModerationElement::TwitchModerationElement()
|
TwitchModerationElement::TwitchModerationElement()
|
||||||
: MessageElement(MessageElementFlag::ModeratorTools)
|
: MessageElement(MessageElementFlag::ModeratorTools)
|
||||||
|
@ -824,6 +1012,14 @@ void TwitchModerationElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject TwitchModerationElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"TwitchModerationElement"_s;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
LinebreakElement::LinebreakElement(MessageElementFlags flags)
|
LinebreakElement::LinebreakElement(MessageElementFlags flags)
|
||||||
: MessageElement(flags)
|
: MessageElement(flags)
|
||||||
{
|
{
|
||||||
|
@ -838,6 +1034,14 @@ void LinebreakElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject LinebreakElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"LinebreakElement"_s;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
ScalingImageElement::ScalingImageElement(ImageSet images,
|
ScalingImageElement::ScalingImageElement(ImageSet images,
|
||||||
MessageElementFlags flags)
|
MessageElementFlags flags)
|
||||||
: MessageElement(flags)
|
: MessageElement(flags)
|
||||||
|
@ -864,6 +1068,15 @@ void ScalingImageElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ScalingImageElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"ScalingImageElement"_s;
|
||||||
|
base["image"_L1] = this->images_.getImage1()->url().string;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
ReplyCurveElement::ReplyCurveElement()
|
ReplyCurveElement::ReplyCurveElement()
|
||||||
: MessageElement(MessageElementFlag::RepliedMessage)
|
: MessageElement(MessageElementFlag::RepliedMessage)
|
||||||
{
|
{
|
||||||
|
@ -886,4 +1099,12 @@ void ReplyCurveElement::addToContainer(MessageLayoutContainer &container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ReplyCurveElement::toJson() const
|
||||||
|
{
|
||||||
|
auto base = MessageElement::toJson();
|
||||||
|
base["type"_L1] = u"ReplyCurveElement"_s;
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "providers/links/LinkInfo.hpp"
|
#include "providers/links/LinkInfo.hpp"
|
||||||
#include "singletons/Fonts.hpp"
|
#include "singletons/Fonts.hpp"
|
||||||
|
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
#include <pajlada/signals/signalholder.hpp>
|
#include <pajlada/signals/signalholder.hpp>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -16,6 +17,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class QJsonObject;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
class Channel;
|
class Channel;
|
||||||
struct MessageLayoutContainer;
|
struct MessageLayoutContainer;
|
||||||
|
@ -183,6 +186,8 @@ public:
|
||||||
virtual void addToContainer(MessageLayoutContainer &container,
|
virtual void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) = 0;
|
MessageElementFlags flags) = 0;
|
||||||
|
|
||||||
|
virtual QJsonObject toJson() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageElement(MessageElementFlags flags);
|
MessageElement(MessageElementFlags flags);
|
||||||
bool trailingSpace = true;
|
bool trailingSpace = true;
|
||||||
|
@ -202,6 +207,8 @@ public:
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImagePtr image_;
|
ImagePtr image_;
|
||||||
};
|
};
|
||||||
|
@ -216,6 +223,8 @@ public:
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImagePtr image_;
|
ImagePtr image_;
|
||||||
int padding_;
|
int padding_;
|
||||||
|
@ -234,6 +243,8 @@ public:
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QStringList words_;
|
QStringList words_;
|
||||||
|
|
||||||
|
@ -253,6 +264,8 @@ public:
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageColor color_;
|
MessageColor color_;
|
||||||
FontStyle style_;
|
FontStyle style_;
|
||||||
|
@ -294,6 +307,8 @@ public:
|
||||||
return &this->linkInfo_;
|
return &this->linkInfo_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LinkInfo linkInfo_;
|
LinkInfo linkInfo_;
|
||||||
// these are implicitly shared
|
// these are implicitly shared
|
||||||
|
@ -328,6 +343,8 @@ public:
|
||||||
MessageElement *setLink(const Link &link) override;
|
MessageElement *setLink(const Link &link) override;
|
||||||
Link getLink() const override;
|
Link getLink() const override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* The color of the element in case the "Colorize @usernames" is disabled
|
* The color of the element in case the "Colorize @usernames" is disabled
|
||||||
|
@ -355,6 +372,8 @@ public:
|
||||||
MessageElementFlags flags_) override;
|
MessageElementFlags flags_) override;
|
||||||
EmotePtr getEmote() const;
|
EmotePtr getEmote() const;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||||
const QSize &size);
|
const QSize &size);
|
||||||
|
@ -390,6 +409,8 @@ public:
|
||||||
std::vector<Emote> getUniqueEmotes() const;
|
std::vector<Emote> getUniqueEmotes() const;
|
||||||
const std::vector<QString> &getEmoteTooltips() const;
|
const std::vector<QString> &getEmoteTooltips() const;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageLayoutElement *makeImageLayoutElement(
|
MessageLayoutElement *makeImageLayoutElement(
|
||||||
const std::vector<ImagePtr> &image, const std::vector<QSize> &sizes,
|
const std::vector<ImagePtr> &image, const std::vector<QSize> &sizes,
|
||||||
|
@ -416,6 +437,8 @@ public:
|
||||||
|
|
||||||
EmotePtr getEmote() const;
|
EmotePtr getEmote() const;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||||
const QSize &size);
|
const QSize &size);
|
||||||
|
@ -429,6 +452,8 @@ class ModBadgeElement : public BadgeElement
|
||||||
public:
|
public:
|
||||||
ModBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
|
ModBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||||
const QSize &size) override;
|
const QSize &size) override;
|
||||||
|
@ -439,6 +464,8 @@ class VipBadgeElement : public BadgeElement
|
||||||
public:
|
public:
|
||||||
VipBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
|
VipBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||||
const QSize &size) override;
|
const QSize &size) override;
|
||||||
|
@ -450,6 +477,8 @@ public:
|
||||||
FfzBadgeElement(const EmotePtr &data, MessageElementFlags flags_,
|
FfzBadgeElement(const EmotePtr &data, MessageElementFlags flags_,
|
||||||
QColor color_);
|
QColor color_);
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
|
||||||
const QSize &size) override;
|
const QSize &size) override;
|
||||||
|
@ -460,7 +489,8 @@ protected:
|
||||||
class TimestampElement : public MessageElement
|
class TimestampElement : public MessageElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TimestampElement(QTime time_ = QTime::currentTime());
|
TimestampElement();
|
||||||
|
TimestampElement(QTime time_);
|
||||||
~TimestampElement() override = default;
|
~TimestampElement() override = default;
|
||||||
|
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
|
@ -468,6 +498,8 @@ public:
|
||||||
|
|
||||||
TextElement *formatTime(const QTime &time);
|
TextElement *formatTime(const QTime &time);
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTime time_;
|
QTime time_;
|
||||||
std::unique_ptr<TextElement> element_;
|
std::unique_ptr<TextElement> element_;
|
||||||
|
@ -483,6 +515,8 @@ public:
|
||||||
|
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forces a linebreak
|
// Forces a linebreak
|
||||||
|
@ -493,6 +527,8 @@ public:
|
||||||
|
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Image element which will pick the quality of the image based on ui scale
|
// Image element which will pick the quality of the image based on ui scale
|
||||||
|
@ -504,6 +540,8 @@ public:
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImageSet images_;
|
ImageSet images_;
|
||||||
};
|
};
|
||||||
|
@ -515,6 +553,13 @@ public:
|
||||||
|
|
||||||
void addToContainer(MessageLayoutContainer &container,
|
void addToContainer(MessageLayoutContainer &container,
|
||||||
MessageElementFlags flags) override;
|
MessageElementFlags flags) override;
|
||||||
|
|
||||||
|
QJsonObject toJson() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<chatterino::MessageElementFlag> {
|
||||||
|
static constexpr bool is_flags = true; // NOLINT(readability-identifier-*)
|
||||||
|
};
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
#include "messages/MessageThread.hpp"
|
#include "messages/MessageThread.hpp"
|
||||||
|
|
||||||
|
#include "common/Literals.hpp"
|
||||||
#include "messages/Message.hpp"
|
#include "messages/Message.hpp"
|
||||||
#include "util/DebugCount.hpp"
|
#include "util/DebugCount.hpp"
|
||||||
|
#include "util/QMagicEnum.hpp"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
using namespace literals;
|
||||||
|
|
||||||
MessageThread::MessageThread(std::shared_ptr<const Message> rootMessage)
|
MessageThread::MessageThread(std::shared_ptr<const Message> rootMessage)
|
||||||
: rootMessageId_(rootMessage->id)
|
: rootMessageId_(rootMessage->id)
|
||||||
, rootMessage_(std::move(rootMessage))
|
, rootMessage_(std::move(rootMessage))
|
||||||
|
@ -80,4 +88,29 @@ void MessageThread::markUnsubscribed()
|
||||||
this->subscriptionUpdated();
|
this->subscriptionUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject MessageThread::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject obj{
|
||||||
|
{"rootId"_L1, this->rootMessageId_},
|
||||||
|
{"subscription"_L1, qmagicenum::enumNameString(this->subscription_)},
|
||||||
|
};
|
||||||
|
|
||||||
|
QJsonArray replies;
|
||||||
|
for (const auto &msg : this->replies_)
|
||||||
|
{
|
||||||
|
auto locked = msg.lock();
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
replies.append(locked->id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
replies.append(QJsonValue::Null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj["replies"_L1] = replies;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class QJsonObject;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
struct Message;
|
struct Message;
|
||||||
|
|
||||||
|
@ -62,6 +64,8 @@ public:
|
||||||
return replies_;
|
return replies_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
|
|
||||||
boost::signals2::signal<void()> subscriptionUpdated;
|
boost::signals2::signal<void()> subscriptionUpdated;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "providers/twitch/ChannelPointReward.hpp"
|
#include "providers/twitch/ChannelPointReward.hpp"
|
||||||
|
|
||||||
|
#include "common/Literals.hpp"
|
||||||
#include "messages/Image.hpp"
|
#include "messages/Image.hpp"
|
||||||
|
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
|
@ -15,6 +16,8 @@ QString twitchChannelPointRewardUrl(const QString &file)
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
using namespace literals;
|
||||||
|
|
||||||
ChannelPointReward::ChannelPointReward(const QJsonObject &redemption)
|
ChannelPointReward::ChannelPointReward(const QJsonObject &redemption)
|
||||||
{
|
{
|
||||||
auto reward = redemption.value("reward").toObject();
|
auto reward = redemption.value("reward").toObject();
|
||||||
|
@ -113,4 +116,25 @@ ChannelPointReward::ChannelPointReward(const QJsonObject &redemption)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ChannelPointReward::toJson() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
{"id"_L1, this->id},
|
||||||
|
{"channelId"_L1, this->channelId},
|
||||||
|
{"title"_L1, this->title},
|
||||||
|
{"cost"_L1, this->cost},
|
||||||
|
{"image"_L1, this->image.toJson()},
|
||||||
|
{"isUserInputRequired"_L1, this->isUserInputRequired},
|
||||||
|
{"isBits"_L1, this->isBits},
|
||||||
|
{"emoteId"_L1, this->emoteId},
|
||||||
|
{"emoteName"_L1, this->emoteName},
|
||||||
|
{"user"_L1,
|
||||||
|
{{
|
||||||
|
{"id"_L1, this->user.id},
|
||||||
|
{"login"_L1, this->user.login},
|
||||||
|
{"displayName"_L1, this->user.displayName},
|
||||||
|
}}},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -24,6 +24,8 @@ struct ChannelPointReward {
|
||||||
QString login;
|
QString login;
|
||||||
QString displayName;
|
QString displayName;
|
||||||
} user;
|
} user;
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -256,40 +256,14 @@ void addHiddenContextMenuItems(QMenu *menu,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto *message = layout->getMessage();
|
auto message = layout->getMessagePtr();
|
||||||
|
|
||||||
if (message != nullptr)
|
if (message)
|
||||||
{
|
{
|
||||||
QJsonDocument jsonDocument;
|
menu->addAction("Copy message &JSON", [message] {
|
||||||
|
auto jsonString = QJsonDocument{message->toJson()}.toJson(
|
||||||
QJsonObject jsonObject;
|
QJsonDocument::Indented);
|
||||||
|
crossPlatformCopy(QString::fromUtf8(jsonString));
|
||||||
jsonObject["id"] = message->id;
|
|
||||||
jsonObject["searchText"] = message->searchText;
|
|
||||||
jsonObject["messageText"] = message->messageText;
|
|
||||||
jsonObject["flags"] = qmagicenum::enumFlagsName(message->flags.value());
|
|
||||||
if (message->reward)
|
|
||||||
{
|
|
||||||
QJsonObject reward;
|
|
||||||
reward["id"] = message->reward->id;
|
|
||||||
reward["title"] = message->reward->title;
|
|
||||||
reward["cost"] = message->reward->cost;
|
|
||||||
reward["isUserInputRequired"] =
|
|
||||||
message->reward->isUserInputRequired;
|
|
||||||
jsonObject["reward"] = reward;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
jsonObject["reward"] = QJsonValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonDocument.setObject(jsonObject);
|
|
||||||
|
|
||||||
auto jsonString =
|
|
||||||
jsonDocument.toJson(QJsonDocument::JsonFormat::Indented);
|
|
||||||
|
|
||||||
menu->addAction("Copy message &JSON", [jsonString] {
|
|
||||||
crossPlatformCopy(jsonString);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue