diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-05-28 13:00:44 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-28 13:00:44 +0900 |
commit | 36dbba9c543b819aec526f18c33f1d95b0ee61c7 (patch) | |
tree | 49caf6450be52072d8f1e4e40e2dfb8490d73732 /events | |
parent | ced7a66686596e74a1f25b5d9634b9b562870943 (diff) | |
parent | a5e14da86c3299ca8d36eb4a4eb58ce2a245dc4e (diff) | |
download | libquotient-36dbba9c543b819aec526f18c33f1d95b0ee61c7.tar.gz libquotient-36dbba9c543b819aec526f18c33f1d95b0ee61c7.zip |
Merge pull request #65 from QMatrixClient/kitsune-simplify-events
Events refactoring
Diffstat (limited to 'events')
-rw-r--r-- | events/event.cpp | 145 | ||||
-rw-r--r-- | events/event.h | 103 | ||||
-rw-r--r-- | events/receiptevent.cpp | 40 | ||||
-rw-r--r-- | events/receiptevent.h | 35 | ||||
-rw-r--r-- | events/roomaliasesevent.cpp | 42 | ||||
-rw-r--r-- | events/roomaliasesevent.h | 14 | ||||
-rw-r--r-- | events/roomcanonicalaliasevent.cpp | 32 | ||||
-rw-r--r-- | events/roomcanonicalaliasevent.h | 17 | ||||
-rw-r--r-- | events/roommemberevent.cpp | 77 | ||||
-rw-r--r-- | events/roommemberevent.h | 29 | ||||
-rw-r--r-- | events/roommessageevent.cpp | 121 | ||||
-rw-r--r-- | events/roommessageevent.h | 67 | ||||
-rw-r--r-- | events/roomnameevent.cpp | 30 | ||||
-rw-r--r-- | events/roomnameevent.h | 17 | ||||
-rw-r--r-- | events/roomtopicevent.cpp | 29 | ||||
-rw-r--r-- | events/roomtopicevent.h | 17 | ||||
-rw-r--r-- | events/typingevent.cpp | 42 | ||||
-rw-r--r-- | events/typingevent.h | 12 |
18 files changed, 304 insertions, 565 deletions
diff --git a/events/event.cpp b/events/event.cpp index 07649b02..bd7e1b03 100644 --- a/events/event.cpp +++ b/events/event.cpp @@ -18,9 +18,6 @@ #include "event.h" -#include <QtCore/QJsonArray> -#include <QtCore/QJsonDocument> - #include "roommessageevent.h" #include "roomnameevent.h" #include "roomaliasesevent.h" @@ -31,121 +28,101 @@ #include "receiptevent.h" #include "unknownevent.h" #include "logging.h" -#include "util.h" -using namespace QMatrixClient; +#include <QtCore/QJsonDocument> -class Event::Private -{ - public: - EventType type; - QString id; - QDateTime timestamp; - QString roomId; - QString senderId; - QString originalJson; -}; +using namespace QMatrixClient; -Event::Event(EventType type) - : d(new Private) +Event::Event(Type type, const QJsonObject& rep) + : _type(type), _originalJson(rep) { - d->type = type; + if (!rep.contains("content")) + { + qCWarning(EVENTS) << "Event without 'content' node"; + qCWarning(EVENTS) << formatJson << rep; + } } -Event::~Event() +QByteArray Event::originalJson() const { - delete d; + return QJsonDocument(_originalJson).toJson(); } -EventType Event::type() const +QDateTime Event::toTimestamp(const QJsonValue& v) { - return d->type; + Q_ASSERT(v.isDouble()); + return QDateTime::fromMSecsSinceEpoch( + static_cast<long long int>(v.toDouble()), Qt::UTC); } -QString Event::id() const +QStringList Event::toStringList(const QJsonValue& v) { - return d->id; -} + Q_ASSERT(v.isArray()); -QDateTime Event::timestamp() const -{ - return d->timestamp; + QStringList l; + for( const QJsonValue& e : v.toArray() ) + l.push_back(e.toString()); + return l; } -QString Event::roomId() const +const QJsonObject Event::contentJson() const { - return d->roomId; + return _originalJson["content"].toObject(); } -QString Event::senderId() const +template <typename EventT> +EventT* make(const QJsonObject& o) { - return d->senderId; + return new EventT(o); } -QString Event::originalJson() const +Event* Event::fromJson(const QJsonObject& obj) { - return d->originalJson; + // Check more specific event types first + if (auto e = RoomEvent::fromJson(obj)) + return e; + + return dispatch<Event*>(obj).to(obj["type"].toString(), + "m.typing", make<TypingEvent>, + "m.receipt", make<ReceiptEvent>, + /* Insert new event types (except room events) BEFORE this line */ + nullptr + ); } -template <typename T> -Event* make(const QJsonObject& obj) +RoomEvent::RoomEvent(Type type, const QJsonObject& rep) + : Event(type, rep), _id(rep["event_id"].toString()) + , _serverTimestamp(toTimestamp(rep["origin_server_ts"])) + , _roomId(rep["room_id"].toString()) + , _senderId(rep["sender"].toString()) { - return T::fromJson(obj); + if (_id.isEmpty()) + { + qCWarning(EVENTS) << "Can't find event_id in a room event"; + qCWarning(EVENTS) << formatJson << rep; + } + if (!rep.contains("origin_server_ts")) + { + qCWarning(EVENTS) << "Event: can't find server timestamp in a room event"; + qCWarning(EVENTS) << formatJson << rep; + } + if (_senderId.isEmpty()) + { + qCWarning(EVENTS) << "user_id not found in a room event"; + qCWarning(EVENTS) << formatJson << rep; + } } -Event* Event::fromJson(const QJsonObject& obj) +RoomEvent* RoomEvent::fromJson(const QJsonObject& obj) { - auto delegate = lookup(obj.value("type").toString(), + return dispatch<RoomEvent*>(obj).to(obj["type"].toString(), "m.room.message", make<RoomMessageEvent>, "m.room.name", make<RoomNameEvent>, "m.room.aliases", make<RoomAliasesEvent>, "m.room.canonical_alias", make<RoomCanonicalAliasEvent>, "m.room.member", make<RoomMemberEvent>, "m.room.topic", make<RoomTopicEvent>, - "m.typing", make<TypingEvent>, - "m.receipt", make<ReceiptEvent>, - /* Insert new event types BEFORE this line */ - make<UnknownEvent> + /* Insert new ROOM event types BEFORE this line */ + nullptr ); - return delegate(obj); -} - -bool Event::parseJson(const QJsonObject& obj) -{ - d->originalJson = QString::fromUtf8(QJsonDocument(obj).toJson()); - d->id = obj.value("event_id").toString(); - d->roomId = obj.value("room_id").toString(); - d->senderId = obj.value("sender").toString(); - bool correct = (d->type != EventType::Unknown); - if ( d->type != EventType::Typing && - d->type != EventType::Receipt ) - { - if (d->id.isEmpty()) - { - correct = false; - qCDebug(EVENTS) << "Event: can't find event_id; event dump follows"; - qCDebug(EVENTS) << formatJson << obj; - } - if( obj.contains("origin_server_ts") ) - { - d->timestamp = QDateTime::fromMSecsSinceEpoch( - static_cast<qint64>(obj.value("origin_server_ts").toDouble()), Qt::UTC ); - } - else if (d->type != EventType::Unknown) - { - correct = false; - qCDebug(EVENTS) << "Event: can't find ts; event dump follows"; - qCDebug(EVENTS) << formatJson << obj; - } - } - return correct; -} - -Events QMatrixClient::eventsFromJson(const QJsonArray& json) -{ - Events evs; - evs.reserve(json.size()); - for (auto event: json) - evs.push_back(Event::fromJson(event.toObject())); - return evs; } diff --git a/events/event.h b/events/event.h index f60dfb64..fd2f6feb 100644 --- a/events/event.h +++ b/events/event.h @@ -21,43 +21,92 @@ #include <QtCore/QString> #include <QtCore/QDateTime> #include <QtCore/QJsonObject> -#include <QtCore/QVector> +#include <QtCore/QJsonArray> -class QJsonArray; +#include "util.h" namespace QMatrixClient { - enum class EventType - { - RoomMessage, RoomName, RoomAliases, RoomCanonicalAlias, - RoomMember, RoomTopic, Typing, Receipt, Unknown - }; - class Event { + Q_GADGET public: - explicit Event(EventType type); - Event(Event&) = delete; - virtual ~Event(); - - EventType type() const; - QString id() const; - QDateTime timestamp() const; - QString roomId() const; - QString senderId() const; - // only for debug purposes! - QString originalJson() const; + enum class Type + { + RoomMessage, RoomName, RoomAliases, RoomCanonicalAlias, + RoomMember, RoomTopic, Typing, Receipt, Unknown + }; + + explicit Event(Type type, const QJsonObject& rep); + Event(const Event&) = delete; + + Type type() const { return _type; } + QByteArray originalJson() const; + + // Every event also has a "content" object but since its structure is + // different for different types, we're implementing it per-event type + // (and in most cases it will be a combination of other fields + // instead of "content" field). static Event* fromJson(const QJsonObject& obj); - + protected: - bool parseJson(const QJsonObject& obj); - + static QDateTime toTimestamp(const QJsonValue& v); + static QStringList toStringList(const QJsonValue& v); + + const QJsonObject contentJson() const; + private: - class Private; - Private* d; + Type _type; + QJsonObject _originalJson; + + REGISTER_ENUM(Type) }; - using Events = QVector<Event*>; + using EventType = Event::Type; + template <typename EventT> + using EventsBatch = std::vector<EventT*>; + using Events = EventsBatch<Event>; + + template <typename BaseEventT> + BaseEventT* makeEvent(const QJsonObject& obj) + { + if (auto e = BaseEventT::fromJson(obj)) + return e; + + return new BaseEventT(EventType::Unknown, obj); + } + + template <typename BaseEventT = Event, + typename BatchT = EventsBatch<BaseEventT> > + BatchT makeEvents(const QJsonArray& objs) + { + BatchT evs; + // The below line accommodates the difference in size types of + // STL and Qt containers. + evs.reserve(static_cast<typename BatchT::size_type>(objs.size())); + for (auto obj: objs) + evs.push_back(makeEvent<BaseEventT>(obj.toObject())); + return evs; + } - Events eventsFromJson(const QJsonArray& json); -} + class RoomEvent : public Event + { + public: + RoomEvent(Type type, const QJsonObject& rep); + + const QString& id() const { return _id; } + const QDateTime& timestamp() const { return _serverTimestamp; } + const QString& roomId() const { return _roomId; } + const QString& senderId() const { return _senderId; } + + // "Static override" of the one in Event + static RoomEvent* fromJson(const QJsonObject& obj); + + private: + QString _id; + QDateTime _serverTimestamp; + QString _roomId; + QString _senderId; + }; + using RoomEvents = EventsBatch<RoomEvent>; +} // namespace QMatrixClient diff --git a/events/receiptevent.cpp b/events/receiptevent.cpp index c163424f..e3478cf1 100644 --- a/events/receiptevent.cpp +++ b/events/receiptevent.cpp @@ -41,34 +41,13 @@ Example of a Receipt Event: using namespace QMatrixClient; -class ReceiptEvent::Private +ReceiptEvent::ReceiptEvent(const QJsonObject& obj) + : Event(Type::Receipt, obj) { - public: - EventsToReceipts eventsToReceipts; -}; + Q_ASSERT(obj["type"].toString() == jsonType); -ReceiptEvent::ReceiptEvent() - : Event(EventType::Receipt) - , d(new Private) -{ -} - -ReceiptEvent::~ReceiptEvent() -{ - delete d; -} - -EventsToReceipts ReceiptEvent::events() const -{ - return d->eventsToReceipts; -} - -ReceiptEvent* ReceiptEvent::fromJson(const QJsonObject& obj) -{ - ReceiptEvent* e = new ReceiptEvent(); - e->parseJson(obj); const QJsonObject contents = obj["content"].toObject(); - e->d->eventsToReceipts.reserve(contents.size()); + _eventsWithReceipts.reserve(static_cast<size_t>(contents.size())); for( auto eventIt = contents.begin(); eventIt != contents.end(); ++eventIt ) { if (eventIt.key().isEmpty()) @@ -78,15 +57,14 @@ ReceiptEvent* ReceiptEvent::fromJson(const QJsonObject& obj) continue; } const QJsonObject reads = eventIt.value().toObject().value("m.read").toObject(); - Receipts receipts; receipts.reserve(reads.size()); + std::vector<Receipt> receipts; + receipts.reserve(static_cast<size_t>(reads.size())); for( auto userIt = reads.begin(); userIt != reads.end(); ++userIt ) { const QJsonObject user = userIt.value().toObject(); - const auto time = QDateTime::fromMSecsSinceEpoch( - static_cast<qint64>(user["ts"].toDouble()), Qt::UTC ); - receipts.push_back({ userIt.key(), time }); + receipts.push_back({userIt.key(), toTimestamp(user["ts"])}); } - e->d->eventsToReceipts.push_back({ eventIt.key(), receipts }); + _eventsWithReceipts.push_back({eventIt.key(), receipts}); } - return e; } + diff --git a/events/receiptevent.h b/events/receiptevent.h index 40c0384f..1d280822 100644 --- a/events/receiptevent.h +++ b/events/receiptevent.h @@ -22,32 +22,29 @@ namespace QMatrixClient { - class Receipt + struct Receipt { - public: - QString userId; - QDateTime timestamp; + QString userId; + QDateTime timestamp; }; -} -Q_DECLARE_TYPEINFO(QMatrixClient::Receipt, Q_MOVABLE_TYPE); - -namespace QMatrixClient -{ - using Receipts = QVector<Receipt>; - using EventsToReceipts = QVector< QPair<QString, Receipts> >; + struct ReceiptsForEvent + { + QString evtId; + std::vector<Receipt> receipts; + }; + using EventsWithReceipts = std::vector<ReceiptsForEvent>; class ReceiptEvent: public Event { public: - ReceiptEvent(); - virtual ~ReceiptEvent(); + explicit ReceiptEvent(const QJsonObject& obj); - EventsToReceipts events() const; - - static ReceiptEvent* fromJson(const QJsonObject& obj); + EventsWithReceipts eventsWithReceipts() const + { return _eventsWithReceipts; } private: - class Private; - Private* d; + EventsWithReceipts _eventsWithReceipts; + + static constexpr const char * jsonType = "m.receipt"; }; -} +} // namespace QMatrixClient diff --git a/events/roomaliasesevent.cpp b/events/roomaliasesevent.cpp index ab414498..344b4367 100644 --- a/events/roomaliasesevent.cpp +++ b/events/roomaliasesevent.cpp @@ -34,44 +34,10 @@ #include "roomaliasesevent.h" -#include "logging.h" - -#include <QtCore/QJsonArray> - using namespace QMatrixClient; -class RoomAliasesEvent::Private -{ - public: - QStringList aliases; -}; - -RoomAliasesEvent::RoomAliasesEvent() - : Event(EventType::RoomAliases) - , d(new Private) -{ -} - -RoomAliasesEvent::~RoomAliasesEvent() -{ - delete d; -} - -QStringList RoomAliasesEvent::aliases() const -{ - return d->aliases; -} +RoomAliasesEvent::RoomAliasesEvent(const QJsonObject& obj) + : RoomEvent(Type::RoomAliases, obj) + , _aliases(toStringList(contentJson()["aliases"])) +{ } -RoomAliasesEvent* RoomAliasesEvent::fromJson(const QJsonObject& obj) -{ - RoomAliasesEvent* e = new RoomAliasesEvent(); - e->parseJson(obj); - const QJsonObject contents = obj.value("content").toObject(); - const QJsonArray aliases = contents.value("aliases").toArray(); - for( const QJsonValue& alias : aliases ) - { - e->d->aliases << alias.toString(); - } - qCDebug(EVENTS) << "RoomAliasesEvent:" << e->d->aliases; - return e; -} diff --git a/events/roomaliasesevent.h b/events/roomaliasesevent.h index 8f638be2..efafcb30 100644 --- a/events/roomaliasesevent.h +++ b/events/roomaliasesevent.h @@ -24,18 +24,14 @@ namespace QMatrixClient { - class RoomAliasesEvent: public Event + class RoomAliasesEvent: public RoomEvent { public: - RoomAliasesEvent(); - virtual ~RoomAliasesEvent(); + explicit RoomAliasesEvent(const QJsonObject& obj); - QStringList aliases() const; - - static RoomAliasesEvent* fromJson(const QJsonObject& obj); + QStringList aliases() const { return _aliases; } private: - class Private; - Private* d; + QStringList _aliases; }; -} +} // namespace QMatrixClient diff --git a/events/roomcanonicalaliasevent.cpp b/events/roomcanonicalaliasevent.cpp index d84c07fc..6884bc15 100644 --- a/events/roomcanonicalaliasevent.cpp +++ b/events/roomcanonicalaliasevent.cpp @@ -19,35 +19,3 @@ #include "roomcanonicalaliasevent.h" using namespace QMatrixClient; - -class RoomCanonicalAliasEvent::Private -{ - public: - QString alias; -}; - -RoomCanonicalAliasEvent::RoomCanonicalAliasEvent() - : Event(EventType::RoomCanonicalAlias) - , d(new Private) -{ -} - -RoomCanonicalAliasEvent::~RoomCanonicalAliasEvent() -{ - delete d; -} - -QString RoomCanonicalAliasEvent::alias() -{ - return d->alias; -} - -RoomCanonicalAliasEvent* RoomCanonicalAliasEvent::fromJson(const QJsonObject& obj) -{ - RoomCanonicalAliasEvent* e = new RoomCanonicalAliasEvent(); - e->parseJson(obj); - const QJsonObject contents = obj.value("content").toObject(); - e->d->alias = contents.value("alias").toString(); - return e; -} - diff --git a/events/roomcanonicalaliasevent.h b/events/roomcanonicalaliasevent.h index 87219be6..72620d74 100644 --- a/events/roomcanonicalaliasevent.h +++ b/events/roomcanonicalaliasevent.h @@ -22,18 +22,17 @@ namespace QMatrixClient { - class RoomCanonicalAliasEvent: public Event + class RoomCanonicalAliasEvent : public RoomEvent { public: - RoomCanonicalAliasEvent(); - virtual ~RoomCanonicalAliasEvent(); + explicit RoomCanonicalAliasEvent(const QJsonObject& obj) + : RoomEvent(Type::RoomCanonicalAlias, obj) + , _canonicalAlias(contentJson()["alias"].toString()) + { } - QString alias(); - - static RoomCanonicalAliasEvent* fromJson(const QJsonObject& obj); + QString alias() const { return _canonicalAlias; } private: - class Private; - Private* d; + QString _canonicalAlias; }; -} +} // namespace QMatrixClient diff --git a/events/roommemberevent.cpp b/events/roommemberevent.cpp index 51dbbbab..5973acc7 100644 --- a/events/roommemberevent.cpp +++ b/events/roommemberevent.cpp @@ -22,66 +22,19 @@ using namespace QMatrixClient; -class RoomMemberEvent::Private -{ - public: - MembershipType membership; - QString userId; - QString displayname; - QUrl avatarUrl; -}; - -RoomMemberEvent::RoomMemberEvent() - : Event(EventType::RoomMember) - , d(new Private) -{ -} - -RoomMemberEvent::~RoomMemberEvent() -{ - delete d; -} - -MembershipType RoomMemberEvent::membership() const -{ - return d->membership; -} - -QString RoomMemberEvent::userId() const -{ - return d->userId; -} - -QString RoomMemberEvent::displayName() const -{ - return d->displayname; -} - -QUrl RoomMemberEvent::avatarUrl() const -{ - return d->avatarUrl; -} - -RoomMemberEvent* RoomMemberEvent::fromJson(const QJsonObject& obj) -{ - RoomMemberEvent* e = new RoomMemberEvent(); - e->parseJson(obj); - e->d->userId = obj.value("state_key").toString(); - QJsonObject content = obj.value("content").toObject(); - e->d->displayname = content.value("displayname").toString(); - QString membershipString = content.value("membership").toString(); - if( membershipString == "invite" ) - e->d->membership = MembershipType::Invite; - else if( membershipString == "join" ) - e->d->membership = MembershipType::Join; - else if( membershipString == "knock" ) - e->d->membership = MembershipType::Knock; - else if( membershipString == "leave" ) - e->d->membership = MembershipType::Leave; - else if( membershipString == "ban" ) - e->d->membership = MembershipType::Ban; - else - qCDebug(EVENTS) << "Unknown MembershipType: " << membershipString; - e->d->avatarUrl = QUrl(content.value("avatar_url").toString()); - return e; +RoomMemberEvent::RoomMemberEvent(const QJsonObject& obj) + : RoomEvent(Type::RoomMember, obj), _userId(obj["state_key"].toString()) +{ + const auto contentObj = contentJson(); + _displayName = contentObj["displayname"].toString(); + _avatarUrl = contentObj["avatar_url"].toString(); + QString membershipString = contentObj["membership"].toString(); + const auto supportedStrings = { "invite", "join", "knock", "leave", "ban" }; + for (auto it = supportedStrings.begin(); it != supportedStrings.end(); ++it) + if (membershipString == *it) + { + _membership = MembershipType(it - supportedStrings.begin()); + return; + } + qCWarning(EVENTS) << "Unknown MembershipType: " << membershipString; } diff --git a/events/roommemberevent.h b/events/roommemberevent.h index a33c2982..9ebb75ee 100644 --- a/events/roommemberevent.h +++ b/events/roommemberevent.h @@ -24,23 +24,26 @@ namespace QMatrixClient { - enum class MembershipType {Invite, Join, Knock, Leave, Ban}; - - class RoomMemberEvent: public Event + class RoomMemberEvent: public RoomEvent { + Q_GADGET public: - RoomMemberEvent(); - virtual ~RoomMemberEvent(); + enum MembershipType : int {Invite = 0, Join, Knock, Leave, Ban}; - MembershipType membership() const; - QString userId() const; - QString displayName() const; - QUrl avatarUrl() const; + explicit RoomMemberEvent(const QJsonObject& obj); - static RoomMemberEvent* fromJson(const QJsonObject& obj); + MembershipType membership() const { return _membership; } + const QString& userId() const { return _userId; } + const QString& displayName() const { return _displayName; } + const QUrl& avatarUrl() const { return _avatarUrl; } private: - class Private; - Private* d; + MembershipType _membership; + QString _userId; + QString _displayName; + QUrl _avatarUrl; + + REGISTER_ENUM(MembershipType) }; -} + using MembershipType = RoomMemberEvent::MembershipType; +} // namespace QMatrixClient diff --git a/events/roommessageevent.cpp b/events/roommessageevent.cpp index 677bb79f..19da8827 100644 --- a/events/roommessageevent.cpp +++ b/events/roommessageevent.cpp @@ -19,64 +19,15 @@ #include "roommessageevent.h" #include "logging.h" -#include "util.h" #include <QtCore/QMimeDatabase> using namespace QMatrixClient; - -class RoomMessageEvent::Private -{ - public: - Private() : msgtype(MessageEventType::Unknown), content(nullptr) {} - ~Private() { if (content) delete content; } - - QString userId; - MessageEventType msgtype; - QString plainBody; - MessageEventContent::Base* content; -}; - -RoomMessageEvent::RoomMessageEvent() - : Event(EventType::RoomMessage) - , d(new Private) -{ } - -RoomMessageEvent::~RoomMessageEvent() -{ - delete d; -} - -QString RoomMessageEvent::userId() const -{ - return d->userId; -} - -MessageEventType RoomMessageEvent::msgtype() const -{ - return d->msgtype; -} - -QString RoomMessageEvent::plainBody() const -{ - return d->plainBody; -} - -QString RoomMessageEvent::body() const -{ - return plainBody(); -} - using namespace MessageEventContent; -Base* RoomMessageEvent::content() const -{ - return d->content; -} - -using ContentPair = std::pair<MessageEventType, MessageEventContent::Base*>; +using ContentPair = std::pair<CType, Base*>; -template <MessageEventType EnumType, typename ContentT> +template <CType EnumType, typename ContentT> ContentPair make(const QJsonObject& json) { return { EnumType, new ContentT(json) }; @@ -91,59 +42,53 @@ ContentPair makeVideo(const QJsonObject& json) if (infoJson.contains("thumbnail_url")) { c->thumbnail = ImageInfo(infoJson["thumbnail_url"].toString(), - infoJson["thumbnail_info"].toObject()); + infoJson["thumbnail_info"].toObject()); } - return { MessageEventType::Video, c }; + return { CType::Video, c }; }; ContentPair makeUnknown(const QJsonObject& json) { qCDebug(EVENTS) << "RoomMessageEvent: couldn't resolve msgtype, JSON follows:"; qCDebug(EVENTS) << json; - return { MessageEventType::Unknown, new Base }; + return { CType::Unknown, new Base() }; } -RoomMessageEvent* RoomMessageEvent::fromJson(const QJsonObject& obj) +RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) + : RoomEvent(Type::RoomMessage, obj), _msgtype(CType::Unknown) + , _content(nullptr) { - RoomMessageEvent* e = new RoomMessageEvent(); - e->parseJson(obj); - if( obj.contains("sender") ) + const QJsonObject content = contentJson(); + if ( content.contains("msgtype") && content.contains("body") ) { - e->d->userId = obj.value("sender").toString(); - } else { - qCDebug(EVENTS) << "RoomMessageEvent: user_id not found"; + _plainBody = content["body"].toString(); + + auto factory = lookup(content["msgtype"].toString(), + "m.text", &make<CType::Text, TextContent>, + "m.emote", &make<CType::Emote, TextContent>, + "m.notice", &make<CType::Notice, TextContent>, + "m.image", &make<CType::Image, ImageContent>, + "m.file", &make<CType::File, FileContent>, + "m.location", &make<CType::Location, LocationContent>, + "m.video", &makeVideo, + "m.audio", &make<CType::Audio, AudioContent>, + // Insert new message types before this line + &makeUnknown + ); + std::tie(_msgtype, _content) = factory(content); } - if( obj.contains("content") ) + else { - const QJsonObject content = obj["content"].toObject(); - if ( content.contains("msgtype") && content.contains("body") ) - { - e->d->plainBody = content["body"].toString(); - - auto delegate = lookup(content.value("msgtype").toString(), - "m.text", make<MessageEventType::Text, TextContent>, - "m.emote", make<MessageEventType::Emote, TextContent>, - "m.notice", make<MessageEventType::Notice, TextContent>, - "m.image", make<MessageEventType::Image, ImageContent>, - "m.file", make<MessageEventType::File, FileContent>, - "m.location", make<MessageEventType::Location, LocationContent>, - "m.video", makeVideo, - "m.audio", make<MessageEventType::Audio, AudioContent>, - // Insert new message types before this line - makeUnknown - ); - std::tie(e->d->msgtype, e->d->content) = delegate(content); - } - else - { - qCWarning(EVENTS) << "RoomMessageEvent(" << e->id() << "): no body or msgtype"; - qCDebug(EVENTS) << obj; - } + qCWarning(EVENTS) << "No body or msgtype in room message event"; + qCWarning(EVENTS) << formatJson << obj; } - return e; } -using namespace MessageEventContent; +RoomMessageEvent::~RoomMessageEvent() +{ + if (_content) + delete _content; +} TextContent::TextContent(const QJsonObject& json) { diff --git a/events/roommessageevent.h b/events/roommessageevent.h index 5d5336aa..6acaad6f 100644 --- a/events/roommessageevent.h +++ b/events/roommessageevent.h @@ -24,44 +24,45 @@ #include <QtCore/QMimeType> #include <QtCore/QSize> +#include <memory> + namespace QMatrixClient { - enum class MessageEventType - { - Text, Emote, Notice, Image, File, Location, Video, Audio, Unknown - }; - namespace MessageEventContent { - class Base { }; - } - - class RoomMessageEvent: public Event - { - public: - RoomMessageEvent(); - virtual ~RoomMessageEvent(); - - QString userId() const; - MessageEventType msgtype() const; + class Base + { + Q_GADGET + public: + enum class Type + { + Text, Emote, Notice, Image, File, Location, Video, Audio, Unknown + }; - QString plainBody() const; + virtual ~Base() = default; - /** - * Same as plainBody() for now; might change for "best-looking body" - * in the future. For richer contents, use content-specific data. - * - * @deprecated - */ - QString body() const; + REGISTER_ENUM(Type) + }; + using CType = Base::Type; + } // namespace MessageEventContent + using MessageEventType = MessageEventContent::CType; - MessageEventContent::Base* content() const; + class RoomMessageEvent: public RoomEvent + { + public: + explicit RoomMessageEvent(const QJsonObject& obj); + ~RoomMessageEvent(); - static RoomMessageEvent* fromJson( const QJsonObject& obj ); + const QString& userId() const { return _userId; } + MessageEventType msgtype() const { return _msgtype; } + const QString& plainBody() const { return _plainBody; } + const MessageEventContent::Base* content() const { return _content; } private: - class Private; - Private* d; + QString _userId; + MessageEventType _msgtype; + QString _plainBody; + MessageEventContent::Base* _content; }; namespace MessageEventContent @@ -73,7 +74,7 @@ namespace QMatrixClient class TextContent: public Base { public: - TextContent(const QJsonObject& json); + explicit TextContent(const QJsonObject& json); QMimeType mimeType; QString body; @@ -103,7 +104,7 @@ namespace QMatrixClient class ThumbnailedContent: public ContentInfoT { public: - ThumbnailedContent(const QJsonObject& json) + explicit ThumbnailedContent(const QJsonObject& json) : ContentInfoT(json["url"].toString(), json["info"].toObject()) , thumbnail(json["thumbnail_url"].toString(), json["thumbnail_info"].toObject()) @@ -118,7 +119,7 @@ namespace QMatrixClient class LocationContent: public Base { public: - LocationContent(const QJsonObject& json); + explicit LocationContent(const QJsonObject& json); QString geoUri; ImageInfo thumbnail; @@ -142,5 +143,5 @@ namespace QMatrixClient int duration; }; using AudioContent = ThumbnailedContent<AudioInfo>; - } -} + } // namespace MessageEventContent +} // namespace QMatrixClient diff --git a/events/roomnameevent.cpp b/events/roomnameevent.cpp index c94cb2c3..c202d17a 100644 --- a/events/roomnameevent.cpp +++ b/events/roomnameevent.cpp @@ -20,33 +20,3 @@ using namespace QMatrixClient;
-class RoomNameEvent::Private
-{
- public:
- QString name;
-};
-
-RoomNameEvent::RoomNameEvent() :
- Event(EventType::RoomName),
- d(new Private)
-{
-}
-
-RoomNameEvent::~RoomNameEvent()
-{
- delete d;
-}
-
-QString RoomNameEvent::name() const
-{
- return d->name;
-}
-
-RoomNameEvent* RoomNameEvent::fromJson(const QJsonObject& obj)
-{
- RoomNameEvent* e = new RoomNameEvent();
- e->parseJson(obj);
- const QJsonObject contents = obj.value("content").toObject();
- e->d->name = contents.value("name").toString();
- return e;
-}
diff --git a/events/roomnameevent.h b/events/roomnameevent.h index 8748c4be..bb823933 100644 --- a/events/roomnameevent.h +++ b/events/roomnameevent.h @@ -22,18 +22,17 @@ namespace QMatrixClient
{
- class RoomNameEvent : public Event
+ class RoomNameEvent : public RoomEvent
{
public:
- RoomNameEvent();
- virtual ~RoomNameEvent();
+ explicit RoomNameEvent(const QJsonObject& obj)
+ : RoomEvent(Type::RoomName, obj)
+ , _name(contentJson()["name"].toString())
+ { }
- QString name() const;
-
- static RoomNameEvent* fromJson(const QJsonObject& obj);
+ QString name() const { return _name; }
private:
- class Private;
- Private *d;
+ QString _name{};
};
-}
+} // namespace QMatrixClient
diff --git a/events/roomtopicevent.cpp b/events/roomtopicevent.cpp index 2e186c4b..26677e78 100644 --- a/events/roomtopicevent.cpp +++ b/events/roomtopicevent.cpp @@ -20,32 +20,3 @@ using namespace QMatrixClient; -class RoomTopicEvent::Private -{ - public: - QString topic; -}; - -RoomTopicEvent::RoomTopicEvent() - : Event(EventType::RoomTopic) - , d(new Private) -{ -} - -RoomTopicEvent::~RoomTopicEvent() -{ - delete d; -} - -QString RoomTopicEvent::topic() const -{ - return d->topic; -} - -RoomTopicEvent* RoomTopicEvent::fromJson(const QJsonObject& obj) -{ - auto e = new RoomTopicEvent(); - e->parseJson(obj); - e->d->topic = obj.value("content").toObject().value("topic").toString(); - return e; -} diff --git a/events/roomtopicevent.h b/events/roomtopicevent.h index 4b0a24b0..fb849afe 100644 --- a/events/roomtopicevent.h +++ b/events/roomtopicevent.h @@ -22,18 +22,17 @@ namespace QMatrixClient { - class RoomTopicEvent: public Event + class RoomTopicEvent: public RoomEvent { public: - RoomTopicEvent(); - virtual ~RoomTopicEvent(); + explicit RoomTopicEvent(const QJsonObject& obj) + : RoomEvent(Type::RoomTopic, obj) + , _topic(contentJson()["topic"].toString()) + { } - QString topic() const; - - static RoomTopicEvent* fromJson(const QJsonObject& obj); + QString topic() const { return _topic; } private: - class Private; - Private* d; + QString _topic; }; -} +} // namespace QMatrixClient diff --git a/events/typingevent.cpp b/events/typingevent.cpp index 009059af..a4d3bae4 100644 --- a/events/typingevent.cpp +++ b/events/typingevent.cpp @@ -18,43 +18,15 @@ #include "typingevent.h" -#include "logging.h" - -#include <QtCore/QJsonArray> - using namespace QMatrixClient; -class TypingEvent::Private -{ - public: - QStringList users; -}; - -TypingEvent::TypingEvent() - : Event(EventType::Typing) - , d( new Private ) -{ -} - -TypingEvent::~TypingEvent() +TypingEvent::TypingEvent(const QJsonObject& obj) + : Event(Type::Typing, obj) { - delete d; -} - -QStringList TypingEvent::users() -{ - return d->users; -} - -TypingEvent* TypingEvent::fromJson(const QJsonObject& obj) -{ - TypingEvent* e = new TypingEvent(); - e->parseJson(obj); - QJsonArray array = obj.value("content").toObject().value("user_ids").toArray(); + QJsonValue result; + result= contentJson()["user_ids"]; + QJsonArray array = result.toArray(); for( const QJsonValue& user: array ) - { - e->d->users << user.toString(); - } - qCDebug(EPHEMERAL) << "Typing:" << e->d->users; - return e; + _users.push_back(user.toString()); } + diff --git a/events/typingevent.h b/events/typingevent.h index da57a389..b12d224e 100644 --- a/events/typingevent.h +++ b/events/typingevent.h @@ -27,15 +27,11 @@ namespace QMatrixClient class TypingEvent: public Event { public: - TypingEvent(); - virtual ~TypingEvent(); + TypingEvent(const QJsonObject& obj); - QStringList users(); - - static TypingEvent* fromJson(const QJsonObject& obj); + QStringList users() const { return _users; } private: - class Private; - Private* d; + QStringList _users; }; -} +} // namespace QMatrixClient |