diff options
author | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-02-13 19:25:24 +0100 |
---|---|---|
committer | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-02-13 19:25:24 +0100 |
commit | 044ae4a029b710571420f830a497647f7a54698a (patch) | |
tree | 14d50ba0eb1a5cfac995f13cd6059aed74e506b2 /lib/events/roommessageevent.cpp | |
parent | b0aef4af9cbf00755c7b70c71d77f0bf7ce0d200 (diff) | |
parent | 10ac7c13cdcd62b62af6e89cb726376cfbc53302 (diff) | |
download | libquotient-044ae4a029b710571420f830a497647f7a54698a.tar.gz libquotient-044ae4a029b710571420f830a497647f7a54698a.zip |
Merge branch 'dev'
The result is FTBFS as yet; next commits will fix that, along with a few
other things.
Diffstat (limited to 'lib/events/roommessageevent.cpp')
-rw-r--r-- | lib/events/roommessageevent.cpp | 127 |
1 files changed, 57 insertions, 70 deletions
diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp index 2b7b4166..d63352cb 100644 --- a/lib/events/roommessageevent.cpp +++ b/lib/events/roommessageevent.cpp @@ -6,6 +6,7 @@ #include "roommessageevent.h" #include "logging.h" +#include "events/eventrelation.h" #include <QtCore/QFileInfo> #include <QtCore/QMimeDatabase> @@ -19,15 +20,14 @@ using namespace EventContent; using MsgType = RoomMessageEvent::MsgType; -static const auto RelatesToKeyL = "m.relates_to"_ls; -static const auto MsgTypeKeyL = "msgtype"_ls; -static const auto FormattedBodyKeyL = "formatted_body"_ls; - -static const auto TextTypeKey = "m.text"; -static const auto EmoteTypeKey = "m.emote"; -static const auto NoticeTypeKey = "m.notice"; - -static const auto HtmlContentTypeId = QStringLiteral("org.matrix.custom.html"); +namespace { // Supporting internal definitions +constexpr auto RelatesToKey = "m.relates_to"_ls; +constexpr auto MsgTypeKey = "msgtype"_ls; +constexpr auto FormattedBodyKey = "formatted_body"_ls; +constexpr auto TextTypeKey = "m.text"_ls; +constexpr auto EmoteTypeKey = "m.emote"_ls; +constexpr auto NoticeTypeKey = "m.notice"_ls; +constexpr auto HtmlContentTypeId = "org.matrix.custom.html"_ls; template <typename ContentT> TypedBase* make(const QJsonObject& json) @@ -38,13 +38,13 @@ TypedBase* make(const QJsonObject& json) template <> TypedBase* make<TextContent>(const QJsonObject& json) { - return json.contains(FormattedBodyKeyL) || json.contains(RelatesToKeyL) + return json.contains(FormattedBodyKey) || json.contains(RelatesToKey) ? new TextContent(json) : nullptr; } struct MsgTypeDesc { - QString matrixType; + QLatin1String matrixType; MsgType enumType; TypedBase* (*maker)(const QJsonObject&); }; @@ -53,11 +53,11 @@ const std::vector<MsgTypeDesc> msgTypes = { { TextTypeKey, MsgType::Text, make<TextContent> }, { EmoteTypeKey, MsgType::Emote, make<TextContent> }, { NoticeTypeKey, MsgType::Notice, make<TextContent> }, - { QStringLiteral("m.image"), MsgType::Image, make<ImageContent> }, - { QStringLiteral("m.file"), MsgType::File, make<FileContent> }, - { QStringLiteral("m.location"), MsgType::Location, make<LocationContent> }, - { QStringLiteral("m.video"), MsgType::Video, make<VideoContent> }, - { QStringLiteral("m.audio"), MsgType::Audio, make<AudioContent> } + { "m.image"_ls, MsgType::Image, make<ImageContent> }, + { "m.file"_ls, MsgType::File, make<FileContent> }, + { "m.location"_ls, MsgType::Location, make<LocationContent> }, + { "m.video"_ls, MsgType::Video, make<VideoContent> }, + { "m.audio"_ls, MsgType::Audio, make<AudioContent> } }; QString msgTypeToJson(MsgType enumType) @@ -84,41 +84,44 @@ MsgType jsonToMsgType(const QString& matrixType) return MsgType::Unknown; } -inline bool isReplacement(const Omittable<RelatesTo>& rel) +inline bool isReplacement(const Omittable<EventRelation>& rel) { - return rel && rel->type == RelatesTo::ReplacementTypeId(); + return rel && rel->type == EventRelation::ReplacementType; } +} // anonymous namespace + QJsonObject RoomMessageEvent::assembleContentJson(const QString& plainBody, const QString& jsonMsgType, TypedBase* content) { - auto json = content ? content->toJson() : QJsonObject(); - if (json.contains(RelatesToKeyL)) { + QJsonObject json; + if (content) { + // TODO: replace with content->fillJson(json) when it starts working + json = content->toJson(); if (jsonMsgType != TextTypeKey && jsonMsgType != NoticeTypeKey && jsonMsgType != EmoteTypeKey) { - json.remove(RelatesToKeyL); - qCWarning(EVENTS) - << RelatesToKeyL << "cannot be used in" << jsonMsgType - << "messages; the relation has been stripped off"; - } else { - // After the above, we know for sure that the content is TextContent - // and that its RelatesTo structure is not omitted - auto* textContent = static_cast<const TextContent*>(content); - Q_ASSERT(textContent && textContent->relatesTo.has_value()); - if (textContent->relatesTo->type == RelatesTo::ReplacementTypeId()) { - auto newContentJson = json.take("m.new_content"_ls).toObject(); - newContentJson.insert(BodyKey, plainBody); - newContentJson.insert(MsgTypeKeyL, jsonMsgType); - json.insert(QStringLiteral("m.new_content"), newContentJson); - json[MsgTypeKeyL] = jsonMsgType; - json[BodyKeyL] = "* " + plainBody; - return json; + if (json.contains(RelatesToKey)) { + json.remove(RelatesToKey); + qCWarning(EVENTS) + << RelatesToKey << "cannot be used in" << jsonMsgType + << "messages; the relation has been stripped off"; } + } else if (auto* textContent = static_cast<const TextContent*>(content); + textContent->relatesTo + && textContent->relatesTo->type + == EventRelation::ReplacementType) { + auto newContentJson = json.take("m.new_content"_ls).toObject(); + newContentJson.insert(BodyKey, plainBody); + newContentJson.insert(MsgTypeKey, jsonMsgType); + json.insert(QStringLiteral("m.new_content"), newContentJson); + json[MsgTypeKey] = jsonMsgType; + json[BodyKeyL] = "* " + plainBody; + return json; } } - json.insert(QStringLiteral("msgtype"), jsonMsgType); - json.insert(QStringLiteral("body"), plainBody); + json.insert(MsgTypeKey, jsonMsgType); + json.insert(BodyKey, plainBody); return json; } @@ -177,8 +180,8 @@ RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) if (isRedacted()) return; const QJsonObject content = contentJson(); - if (content.contains(MsgTypeKeyL) && content.contains(BodyKeyL)) { - auto msgtype = content[MsgTypeKeyL].toString(); + if (content.contains(MsgTypeKey) && content.contains(BodyKeyL)) { + auto msgtype = content[MsgTypeKey].toString(); bool msgTypeFound = false; for (const auto& mt : msgTypes) if (mt.matrixType == msgtype) { @@ -204,7 +207,7 @@ RoomMessageEvent::MsgType RoomMessageEvent::msgtype() const QString RoomMessageEvent::rawMsgtype() const { - return contentPart<QString>(MsgTypeKeyL); + return contentPart<QString>(MsgTypeKey); } QString RoomMessageEvent::plainBody() const @@ -267,7 +270,7 @@ QString RoomMessageEvent::rawMsgTypeForFile(const QFileInfo& fi) } TextContent::TextContent(QString text, const QString& contentType, - Omittable<RelatesTo> relatesTo) + Omittable<EventRelation> relatesTo) : mimeType(QMimeDatabase().mimeTypeForName(contentType)) , body(std::move(text)) , relatesTo(std::move(relatesTo)) @@ -276,26 +279,8 @@ TextContent::TextContent(QString text, const QString& contentType, mimeType = QMimeDatabase().mimeTypeForName("text/html"); } -namespace Quotient { -// Overload the default fromJson<> logic that defined in converters.h -// as we want -template <> -Omittable<RelatesTo> fromJson(const QJsonValue& jv) -{ - const auto jo = jv.toObject(); - if (jo.isEmpty()) - return none; - const auto replyJson = jo.value(RelatesTo::ReplyTypeId()).toObject(); - if (!replyJson.isEmpty()) - return replyTo(fromJson<QString>(replyJson[EventIdKeyL])); - - return RelatesTo { jo.value("rel_type"_ls).toString(), - jo.value(EventIdKeyL).toString() }; -} -} // namespace Quotient - TextContent::TextContent(const QJsonObject& json) - : relatesTo(fromJson<Omittable<RelatesTo>>(json[RelatesToKeyL])) + : relatesTo(fromJson<Omittable<EventRelation>>(json[RelatesToKey])) { QMimeDatabase db; static const auto PlainTextMimeType = db.mimeTypeForName("text/plain"); @@ -308,7 +293,7 @@ TextContent::TextContent(const QJsonObject& json) // of sending HTML messages. if (actualJson["format"_ls].toString() == HtmlContentTypeId) { mimeType = HtmlMimeType; - body = actualJson[FormattedBodyKeyL].toString(); + body = actualJson[FormattedBodyKey].toString(); } else { // Falling back to plain text, as there's no standard way to describe // rich text in messages. @@ -320,7 +305,6 @@ TextContent::TextContent(const QJsonObject& json) void TextContent::fillJson(QJsonObject* json) const { static const auto FormatKey = QStringLiteral("format"); - static const auto FormattedBodyKey = QStringLiteral("formatted_body"); Q_ASSERT(json); if (mimeType.inherits("text/html")) { @@ -328,12 +312,15 @@ void TextContent::fillJson(QJsonObject* json) const json->insert(FormattedBodyKey, body); } if (relatesTo) { - json->insert(QStringLiteral("m.relates_to"), - relatesTo->type == RelatesTo::ReplyTypeId() ? - QJsonObject { { relatesTo->type, QJsonObject{ { EventIdKey, relatesTo->eventId } } } } : - QJsonObject { { "rel_type", relatesTo->type }, { EventIdKey, relatesTo->eventId } } - ); - if (relatesTo->type == RelatesTo::ReplacementTypeId()) { + json->insert( + QStringLiteral("m.relates_to"), + relatesTo->type == EventRelation::ReplyType + ? QJsonObject { { relatesTo->type, + QJsonObject { + { EventIdKey, relatesTo->eventId } } } } + : QJsonObject { { RelTypeKey, relatesTo->type }, + { EventIdKey, relatesTo->eventId } }); + if (relatesTo->type == EventRelation::ReplacementType) { QJsonObject newContentJson; if (mimeType.inherits("text/html")) { newContentJson.insert(FormatKey, HtmlContentTypeId); |