aboutsummaryrefslogtreecommitdiff
path: root/lib/events/roommessageevent.cpp
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-04-13 12:36:03 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-04-13 14:44:04 +0900
commitb68186efc5fcedad6980686c8a07bab3b47a874d (patch)
tree1aaf5de974996279ec7e82af199d65fc5a187a48 /lib/events/roommessageevent.cpp
parent44764f015f25db307811f2969c117b37133fc676 (diff)
parent7ca442a432994a19a86d43c917a1f537bcebb387 (diff)
downloadlibquotient-b68186efc5fcedad6980686c8a07bab3b47a874d.tar.gz
libquotient-b68186efc5fcedad6980686c8a07bab3b47a874d.zip
Merge branch 'master' into kitsune-gtad
Diffstat (limited to 'lib/events/roommessageevent.cpp')
-rw-r--r--lib/events/roommessageevent.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp
new file mode 100644
index 00000000..1a4e74bf
--- /dev/null
+++ b/lib/events/roommessageevent.cpp
@@ -0,0 +1,193 @@
+/******************************************************************************
+ * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "roommessageevent.h"
+
+#include "logging.h"
+
+#include <QtCore/QMimeDatabase>
+
+using namespace QMatrixClient;
+using namespace EventContent;
+
+using MsgType = RoomMessageEvent::MsgType;
+
+template <typename ContentT>
+TypedBase* make(const QJsonObject& json)
+{
+ return new ContentT(json);
+}
+
+struct MsgTypeDesc
+{
+ QString jsonType;
+ MsgType enumType;
+ TypedBase* (*maker)(const QJsonObject&);
+};
+
+const std::vector<MsgTypeDesc> msgTypes =
+ { { QStringLiteral("m.text"), MsgType::Text, make<TextContent> }
+ , { QStringLiteral("m.emote"), MsgType::Emote, make<TextContent> }
+ , { QStringLiteral("m.notice"), 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> }
+ };
+
+QString msgTypeToJson(MsgType enumType)
+{
+ auto it = std::find_if(msgTypes.begin(), msgTypes.end(),
+ [=](const MsgTypeDesc& mtd) { return mtd.enumType == enumType; });
+ if (it != msgTypes.end())
+ return it->jsonType;
+
+ return {};
+}
+
+MsgType jsonToMsgType(const QString& jsonType)
+{
+ auto it = std::find_if(msgTypes.begin(), msgTypes.end(),
+ [=](const MsgTypeDesc& mtd) { return mtd.jsonType == jsonType; });
+ if (it != msgTypes.end())
+ return it->enumType;
+
+ return MsgType::Unknown;
+}
+
+RoomMessageEvent::RoomMessageEvent(const QString& plainBody,
+ MsgType msgType, TypedBase* content)
+ : RoomMessageEvent(plainBody, msgTypeToJson(msgType), content)
+{ }
+
+RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj)
+ : RoomEvent(Type::RoomMessage, obj), _content(nullptr)
+{
+ if (isRedacted())
+ return;
+ const QJsonObject content = contentJson();
+ if ( content.contains("msgtype") && content.contains("body") )
+ {
+ _plainBody = content["body"].toString();
+
+ _msgtype = content["msgtype"].toString();
+ for (const auto& mt: msgTypes)
+ if (mt.jsonType == _msgtype)
+ _content.reset(mt.maker(content));
+
+ if (!_content)
+ {
+ qCWarning(EVENTS) << "RoomMessageEvent: couldn't load content,"
+ << " full content dump follows";
+ qCWarning(EVENTS) << formatJson << content;
+ }
+ }
+ else
+ {
+ qCWarning(EVENTS) << "No body or msgtype in room message event";
+ qCWarning(EVENTS) << formatJson << obj;
+ }
+}
+
+RoomMessageEvent::MsgType RoomMessageEvent::msgtype() const
+{
+ return jsonToMsgType(_msgtype);
+}
+
+QMimeType RoomMessageEvent::mimeType() const
+{
+ return _content ? _content->type() :
+ QMimeDatabase().mimeTypeForName("text/plain");
+}
+
+bool RoomMessageEvent::hasTextContent() const
+{
+ return content() &&
+ (msgtype() == MsgType::Text || msgtype() == MsgType::Emote ||
+ msgtype() == MsgType::Notice); // FIXME: Unbind from specific msgtypes
+}
+
+bool RoomMessageEvent::hasFileContent() const
+{
+ return content() && content()->fileInfo();
+}
+
+bool RoomMessageEvent::hasThumbnail() const
+{
+ return content() && content()->thumbnailInfo();
+}
+
+QJsonObject RoomMessageEvent::toJson() const
+{
+ QJsonObject obj = _content ? _content->toJson() : QJsonObject();
+ obj.insert("msgtype", msgTypeToJson(msgtype()));
+ obj.insert("body", plainBody());
+ return obj;
+}
+
+TextContent::TextContent(const QString& text, const QString& contentType)
+ : mimeType(QMimeDatabase().mimeTypeForName(contentType)), body(text)
+{ }
+
+TextContent::TextContent(const QJsonObject& json)
+{
+ QMimeDatabase db;
+
+ // Special-casing the custom matrix.org's (actually, Riot's) way
+ // of sending HTML messages.
+ if (json["format"].toString() == "org.matrix.custom.html")
+ {
+ mimeType = db.mimeTypeForName("text/html");
+ body = json["formatted_body"].toString();
+ } else {
+ // Falling back to plain text, as there's no standard way to describe
+ // rich text in messages.
+ mimeType = db.mimeTypeForName("text/plain");
+ body = json["body"].toString();
+ }
+}
+
+void TextContent::fillJson(QJsonObject* json) const
+{
+ Q_ASSERT(json);
+ json->insert("format", QStringLiteral("org.matrix.custom.html"));
+ json->insert("formatted_body", body);
+}
+
+LocationContent::LocationContent(const QString& geoUri, const ImageInfo& thumbnail)
+ : geoUri(geoUri), thumbnail(thumbnail)
+{ }
+
+LocationContent::LocationContent(const QJsonObject& json)
+ : TypedBase(json)
+ , geoUri(json["geo_uri"].toString())
+ , thumbnail(json["info"].toObject())
+{ }
+
+QMimeType LocationContent::type() const
+{
+ return QMimeDatabase().mimeTypeForData(geoUri.toLatin1());
+}
+
+void LocationContent::fillJson(QJsonObject* o) const
+{
+ Q_ASSERT(o);
+ o->insert("geo_uri", geoUri);
+ o->insert("info", toInfoJson(thumbnail));
+}