diff options
Diffstat (limited to 'events')
-rw-r--r-- | events/event.h | 28 | ||||
-rw-r--r-- | events/eventcontent.cpp | 15 | ||||
-rw-r--r-- | events/eventcontent.h | 75 | ||||
-rw-r--r-- | events/roommessageevent.cpp | 24 | ||||
-rw-r--r-- | events/roommessageevent.h | 29 |
5 files changed, 112 insertions, 59 deletions
diff --git a/events/event.h b/events/event.h index 6ed5ba49..b5a4d94e 100644 --- a/events/event.h +++ b/events/event.h @@ -256,6 +256,21 @@ namespace QMatrixClient }; template <typename ContentT> + struct Prev + { + template <typename... ContentParamTs> + explicit Prev(const QJsonObject& unsignedJson, + ContentParamTs&&... contentParams) + : senderId(unsignedJson.value("prev_sender").toString()) + , content(unsignedJson.value("prev_content").toObject(), + std::forward<ContentParamTs>(contentParams)...) + { } + + QString senderId; + ContentT content; + }; + + template <typename ContentT> class StateEvent: public StateEventBase { public: @@ -270,9 +285,8 @@ namespace QMatrixClient { auto unsignedData = obj.value("unsigned").toObject(); if (unsignedData.contains("prev_content")) - _prev.reset(new ContentT( - unsignedData.value("prev_content").toObject(), - std::forward<ContentParamTs>(contentParams)...)); + _prev = std::make_unique<Prev<ContentT>>(unsignedData, + std::forward<ContentParamTs>(contentParams)...); } template <typename... ContentParamTs> explicit StateEvent(Type type, ContentParamTs&&... contentParams) @@ -283,11 +297,15 @@ namespace QMatrixClient QJsonObject toJson() const { return _content.toJson(); } ContentT content() const { return _content; } - ContentT* prev_content() const { return _prev.data(); } + /** @deprecated Use prevContent instead */ + ContentT* prev_content() const { return prevContent(); } + ContentT* prevContent() const + { return _prev ? &_prev->content : nullptr; } + QString prevSenderId() const { return _prev ? _prev->senderId : ""; } protected: ContentT _content; - QScopedPointer<ContentT> _prev; + std::unique_ptr<Prev<ContentT>> _prev; }; } // namespace QMatrixClient Q_DECLARE_METATYPE(QMatrixClient::Event*) diff --git a/events/eventcontent.cpp b/events/eventcontent.cpp index 271669e2..f5974b46 100644 --- a/events/eventcontent.cpp +++ b/events/eventcontent.cpp @@ -44,7 +44,6 @@ FileInfo::FileInfo(const QUrl& u, const QJsonObject& infoJson, , payloadSize(infoJson["size"].toInt()) , originalName(originalFilename) { - originalInfoJson.insert("mediaId", url.authority() + url.path()); if (!mimeType.isValid()) mimeType = QMimeDatabase().mimeTypeForData(QByteArray()); } @@ -74,15 +73,13 @@ void ImageInfo::fillInfoJson(QJsonObject* infoJson) const infoJson->insert("h", imageSize.height()); } -WithThumbnail::WithThumbnail(const QJsonObject& infoJson) - : thumbnail(infoJson["thumbnail_url"].toString(), - infoJson["thumbnail_info"].toObject()) +Thumbnail::Thumbnail(const QJsonObject& infoJson) + : ImageInfo(infoJson["thumbnail_url"].toString(), + infoJson["thumbnail_info"].toObject()) { } -void WithThumbnail::fillInfoJson(QJsonObject* infoJson) const +void Thumbnail::fillInfoJson(QJsonObject* infoJson) const { - infoJson->insert("thumbnail_url", thumbnail.url.toString()); - QJsonObject thumbnailInfoJson; - thumbnail.fillInfoJson(&thumbnailInfoJson); - infoJson->insert("thumbnail_info", thumbnailInfoJson); + infoJson->insert("thumbnail_url", url.toString()); + infoJson->insert("thumbnail_info", toInfoJson<ImageInfo>(*this)); } diff --git a/events/eventcontent.h b/events/eventcontent.h index b37dc923..4afbaff3 100644 --- a/events/eventcontent.h +++ b/events/eventcontent.h @@ -27,6 +27,8 @@ #include <QtCore/QUrl> #include <QtCore/QSize> +#include <functional> + namespace QMatrixClient { namespace EventContent @@ -144,6 +146,14 @@ namespace QMatrixClient QString originalName; }; + template <typename InfoT> + QJsonObject toInfoJson(const InfoT& info) + { + QJsonObject infoJson; + info.fillInfoJson(&infoJson); + return infoJson; + } + /** * A content info class for image content types: image, thumbnail, video */ @@ -163,18 +173,18 @@ namespace QMatrixClient }; /** - * A mixin class for an info type that carries a thumbnail + * An auxiliary class for an info type that carries a thumbnail * * This class saves/loads a thumbnail to/from "info" subobject of * the JSON representation of event content; namely, * "info/thumbnail_url" and "info/thumbnail_info" fields are used. */ - class WithThumbnail + class Thumbnail : public ImageInfo { public: - WithThumbnail(const QJsonObject& infoJson); - WithThumbnail(const ImageInfo& info) - : thumbnail(info) + Thumbnail(const QJsonObject& infoJson); + Thumbnail(const ImageInfo& info) + : ImageInfo(info) { } /** @@ -182,9 +192,6 @@ namespace QMatrixClient * and thumbnail URL to "thumbnail_url" node inside "info". */ void fillInfoJson(QJsonObject* infoJson) const; - - public: - ImageInfo thumbnail; }; class TypedBase: public Base @@ -204,19 +211,22 @@ namespace QMatrixClient * the parameter type. * * \tparam InfoT base info class - * \tparam InfoMixinTs... additional info mixin classes (e.g. WithThumbnail) */ - template <class InfoT, class... InfoMixinTs> - class UrlBasedContent : - public TypedBase, public InfoT, public InfoMixinTs... + template <class InfoT> + class UrlBasedContent : public TypedBase, public InfoT { public: + UrlBasedContent(QUrl url, InfoT&& info, QString filename = {}) + : InfoT(url, std::forward<InfoT>(info), filename) + { } explicit UrlBasedContent(const QJsonObject& json) : TypedBase(json) , InfoT(json["url"].toString(), json["info"].toObject(), json["filename"].toString()) - , InfoMixinTs(InfoT::originalInfoJson)... - { } + { + // A small hack to facilitate links creation in QML. + originalJson.insert("mediaId", InfoT::mediaId()); + } QMimeType type() const override { return InfoT::mimeType; } const FileInfo* fileInfo() const override { return this; } @@ -228,12 +238,33 @@ namespace QMatrixClient json->insert("url", InfoT::url.toString()); if (!InfoT::originalName.isEmpty()) json->insert("filename", InfoT::originalName); - QJsonObject infoJson; - InfoT::fillInfoJson(&infoJson); - // http://en.cppreference.com/w/cpp/language/parameter_pack#Brace-enclosed_initializers - // Looking forward to C++17 and its folding awesomeness. - int d[] = { (InfoMixinTs::fillInfoJson(&infoJson), 0)... }; - Q_UNUSED(d); + json->insert("info", toInfoJson<InfoT>(*this)); + } + }; + + template <typename InfoT> + class UrlWithThumbnailContent : public UrlBasedContent<InfoT> + { + public: + // TODO: POD constructor + explicit UrlWithThumbnailContent(const QJsonObject& json) + : UrlBasedContent<InfoT>(json) + , thumbnail(InfoT::originalInfoJson) + { + // Another small hack, to simplify making a thumbnail link + UrlBasedContent<InfoT>::originalJson.insert( + "thumbnailMediaId", thumbnail.mediaId()); + } + + public: + Thumbnail thumbnail; + + protected: + void fillJson(QJsonObject* json) const override + { + UrlBasedContent<InfoT>::fillJson(json); + auto infoJson = json->take("info").toObject(); + thumbnail.fillInfoJson(&infoJson); json->insert("info", infoJson); } }; @@ -256,7 +287,7 @@ namespace QMatrixClient * - mimeType * - imageSize */ - using ImageContent = UrlBasedContent<ImageInfo, WithThumbnail>; + using ImageContent = UrlWithThumbnailContent<ImageInfo>; /** * Content class for m.file @@ -274,6 +305,6 @@ namespace QMatrixClient * - thumbnail.mimeType * - thumbnail.imageSize (QSize for "h" and "w" in JSON) */ - using FileContent = UrlBasedContent<FileInfo, WithThumbnail>; + using FileContent = UrlWithThumbnailContent<FileInfo>; } // namespace EventContent } // namespace QMatrixClient diff --git a/events/roommessageevent.cpp b/events/roommessageevent.cpp index 20e81564..8c088f21 100644 --- a/events/roommessageevent.cpp +++ b/events/roommessageevent.cpp @@ -116,6 +116,13 @@ QMimeType RoomMessageEvent::mimeType() const 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(); @@ -159,13 +166,13 @@ void TextContent::fillJson(QJsonObject* json) const } LocationContent::LocationContent(const QString& geoUri, const ImageInfo& thumbnail) - : WithThumbnail(thumbnail), geoUri(geoUri) + : geoUri(geoUri), thumbnail(thumbnail) { } LocationContent::LocationContent(const QJsonObject& json) : TypedBase(json) - , WithThumbnail(json["info"].toObject()) , geoUri(json["geo_uri"].toString()) + , thumbnail(json["info"].toObject()) { } QMimeType LocationContent::type() const @@ -177,16 +184,5 @@ void LocationContent::fillJson(QJsonObject* o) const { Q_ASSERT(o); o->insert("geo_uri", geoUri); - QJsonObject infoJson; - WithThumbnail::fillInfoJson(&infoJson); - o->insert("info", infoJson); -} - -WithDuration::WithDuration(const QJsonObject& infoJson) - : duration(infoJson["duration"].toInt()) -{ } - -void WithDuration::fillInfoJson(QJsonObject* infoJson) const -{ - infoJson->insert("duration", duration); + o->insert("info", toInfoJson(thumbnail)); } diff --git a/events/roommessageevent.h b/events/roommessageevent.h index 6b551b76..2a5eeb7e 100644 --- a/events/roommessageevent.h +++ b/events/roommessageevent.h @@ -59,6 +59,7 @@ namespace QMatrixClient EventContent::TypedBase* content() const { return _content.data(); } QMimeType mimeType() const; + bool hasTextContent() const; bool hasFileContent() const; QJsonObject toJson() const; @@ -112,7 +113,7 @@ namespace QMatrixClient * - thumbnail.mimeType * - thumbnail.imageSize */ - class LocationContent: public TypedBase, public WithThumbnail + class LocationContent: public TypedBase { public: LocationContent(const QString& geoUri, @@ -123,21 +124,32 @@ namespace QMatrixClient public: QString geoUri; + Thumbnail thumbnail; protected: void fillJson(QJsonObject* o) const override; }; /** - * A mixin class for info types that include duration: audio and video + * A base class for info types that include duration: audio and video */ - class WithDuration + template <typename ContentT> + class PlayableContent : public ContentT { public: - explicit WithDuration(int duration) : duration(duration) { } - WithDuration(const QJsonObject& infoJson); + PlayableContent(const QJsonObject& json) + : ContentT(json) + , duration(ContentT::originalInfoJson["duration"].toInt()) + { } - void fillInfoJson(QJsonObject* infoJson) const; + protected: + void fillJson(QJsonObject* json) const override + { + ContentT::fillJson(json); + auto infoJson = json->take("info").toObject(); + infoJson.insert("duration", duration); + json->insert("info", infoJson); + } public: int duration; @@ -162,8 +174,7 @@ namespace QMatrixClient * - mimeType * - imageSize */ - using VideoContent = - UrlBasedContent<ImageInfo, WithThumbnail, WithDuration>; + using VideoContent = PlayableContent<UrlWithThumbnailContent<ImageInfo>>; /** * Content class for m.audio @@ -177,6 +188,6 @@ namespace QMatrixClient * - mimeType ("mimetype" in JSON) * - duration */ - using AudioContent = UrlBasedContent<FileInfo, WithDuration>; + using AudioContent = PlayableContent<UrlBasedContent<FileInfo>>; } // namespace EventContent } // namespace QMatrixClient |