aboutsummaryrefslogtreecommitdiff
path: root/events
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-01-26 09:00:33 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-01-26 09:00:33 +0900
commit76bff84a2aa63db677044cc529b910768fa018fa (patch)
treeefeb34e37b436267313169a1790e45a07e8f7fcb /events
parent7d506f7bebbcc3b5f8a37589f8fda6fa1e7e1efd (diff)
parent2f83e4be20a15013181c1ba6944e21f051ccac9d (diff)
downloadlibquotient-76bff84a2aa63db677044cc529b910768fa018fa.tar.gz
libquotient-76bff84a2aa63db677044cc529b910768fa018fa.zip
Merge branch 'master' into kitsune-gtad
Diffstat (limited to 'events')
-rw-r--r--events/event.h28
-rw-r--r--events/eventcontent.cpp15
-rw-r--r--events/eventcontent.h75
-rw-r--r--events/roommessageevent.cpp24
-rw-r--r--events/roommessageevent.h29
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