diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-04-13 12:36:03 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-04-13 14:44:04 +0900 |
commit | b68186efc5fcedad6980686c8a07bab3b47a874d (patch) | |
tree | 1aaf5de974996279ec7e82af199d65fc5a187a48 /lib/events/roommessageevent.cpp | |
parent | 44764f015f25db307811f2969c117b37133fc676 (diff) | |
parent | 7ca442a432994a19a86d43c917a1f537bcebb387 (diff) | |
download | libquotient-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.cpp | 193 |
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)); +} |