aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/csapi/event_context.h2
-rw-r--r--lib/csapi/gtad.yaml8
-rw-r--r--lib/csapi/message_pagination.h2
-rw-r--r--lib/csapi/notifications.h2
-rw-r--r--lib/csapi/peeking_events.h2
-rw-r--r--lib/csapi/presence.h2
-rw-r--r--lib/csapi/rooms.h2
-rw-r--r--lib/csapi/search.h6
-rw-r--r--lib/events/accountdataevents.h1
-rw-r--r--lib/events/directchatevent.cpp2
-rw-r--r--lib/events/event.cpp79
-rw-r--r--lib/events/event.h174
-rw-r--r--lib/events/eventloader.h57
-rw-r--r--lib/events/receiptevent.cpp1
-rw-r--r--lib/events/receiptevent.h1
-rw-r--r--lib/events/roomevent.cpp82
-rw-r--r--lib/events/roomevent.h89
-rw-r--r--lib/events/roommemberevent.cpp1
-rw-r--r--lib/events/roommemberevent.h3
-rw-r--r--lib/events/roommessageevent.h3
-rw-r--r--lib/events/simplestateevents.h2
-rw-r--r--lib/events/stateevent.cpp30
-rw-r--r--lib/events/stateevent.h92
-rw-r--r--lib/events/typingevent.cpp2
-rw-r--r--lib/jobs/syncjob.cpp2
-rw-r--r--lib/jobs/syncjob.h2
26 files changed, 384 insertions, 265 deletions
diff --git a/lib/csapi/event_context.h b/lib/csapi/event_context.h
index 0470ba36..22c9cbc3 100644
--- a/lib/csapi/event_context.h
+++ b/lib/csapi/event_context.h
@@ -6,7 +6,7 @@
#include "jobs/basejob.h"
-#include "events/event.h"
+#include "events/eventloader.h"
#include "converters.h"
namespace QMatrixClient
diff --git a/lib/csapi/gtad.yaml b/lib/csapi/gtad.yaml
index 3d1b7e88..09344be5 100644
--- a/lib/csapi/gtad.yaml
+++ b/lib/csapi/gtad.yaml
@@ -62,11 +62,11 @@ analyzer:
- +set: { moveOnly: }
+on:
- /state_event.yaml$/:
- { type: StateEventPtr, imports: '"events/event.h"' }
+ { type: StateEventPtr, imports: '"events/eventloader.h"' }
- /room_event.yaml$/:
- { type: RoomEventPtr, imports: '"events/event.h"' }
+ { type: RoomEventPtr, imports: '"events/eventloader.h"' }
- /event.yaml$/:
- { type: EventPtr, imports: '"events/event.h"' }
+ { type: EventPtr, imports: '"events/eventloader.h"' }
- /auth_data.yaml$/: *QJsonObject # GTAD 0.6 cannot cope with this one
- /m\.room\.member$/: pass # This $ref is only used in an array, see below
- //: *UseOmittable # Also apply "avoidCopy" to all other ref'ed types
@@ -79,7 +79,7 @@ analyzer:
+on:
- /^Notification|Result$/:
type: "std::vector<{{1}}>"
- imports: '"events/event.h"'
+ imports: '"events/eventloader.h"'
- /m\.room\.member$/:
type: "EventsArray<RoomMemberEvent>"
imports: '"events/roommemberevent.h"'
diff --git a/lib/csapi/message_pagination.h b/lib/csapi/message_pagination.h
index 92b258ea..58900940 100644
--- a/lib/csapi/message_pagination.h
+++ b/lib/csapi/message_pagination.h
@@ -6,7 +6,7 @@
#include "jobs/basejob.h"
-#include "events/event.h"
+#include "events/eventloader.h"
#include "converters.h"
namespace QMatrixClient
diff --git a/lib/csapi/notifications.h b/lib/csapi/notifications.h
index 094fa3af..3698431d 100644
--- a/lib/csapi/notifications.h
+++ b/lib/csapi/notifications.h
@@ -6,7 +6,7 @@
#include "jobs/basejob.h"
-#include "events/event.h"
+#include "events/eventloader.h"
#include "converters.h"
#include <QtCore/QVector>
#include <QtCore/QVariant>
diff --git a/lib/csapi/peeking_events.h b/lib/csapi/peeking_events.h
index f8876bf1..5f2c4233 100644
--- a/lib/csapi/peeking_events.h
+++ b/lib/csapi/peeking_events.h
@@ -6,7 +6,7 @@
#include "jobs/basejob.h"
-#include "events/event.h"
+#include "events/eventloader.h"
#include "converters.h"
namespace QMatrixClient
diff --git a/lib/csapi/presence.h b/lib/csapi/presence.h
index 2def94ba..7d6665f3 100644
--- a/lib/csapi/presence.h
+++ b/lib/csapi/presence.h
@@ -6,7 +6,7 @@
#include "jobs/basejob.h"
-#include "events/event.h"
+#include "events/eventloader.h"
#include "converters.h"
namespace QMatrixClient
diff --git a/lib/csapi/rooms.h b/lib/csapi/rooms.h
index 459c6ad5..7d690ec8 100644
--- a/lib/csapi/rooms.h
+++ b/lib/csapi/rooms.h
@@ -6,8 +6,8 @@
#include "jobs/basejob.h"
-#include "events/event.h"
#include "events/roommemberevent.h"
+#include "events/eventloader.h"
#include <QtCore/QHash>
#include "converters.h"
diff --git a/lib/csapi/search.h b/lib/csapi/search.h
index 206bacca..572ea6af 100644
--- a/lib/csapi/search.h
+++ b/lib/csapi/search.h
@@ -6,12 +6,12 @@
#include "jobs/basejob.h"
-#include <unordered_map>
-#include <QtCore/QHash>
#include <QtCore/QJsonObject>
-#include "events/event.h"
#include "converters.h"
#include <QtCore/QVector>
+#include <unordered_map>
+#include <QtCore/QHash>
+#include "events/eventloader.h"
namespace QMatrixClient
{
diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h
index ed4373cd..671ed776 100644
--- a/lib/events/accountdataevents.h
+++ b/lib/events/accountdataevents.h
@@ -22,6 +22,7 @@
#include "event.h"
#include "eventcontent.h"
+#include "converters.h"
namespace QMatrixClient
{
diff --git a/lib/events/directchatevent.cpp b/lib/events/directchatevent.cpp
index 6f5d34f2..266d60d8 100644
--- a/lib/events/directchatevent.cpp
+++ b/lib/events/directchatevent.cpp
@@ -18,6 +18,8 @@
#include "directchatevent.h"
+#include <QtCore/QJsonArray>
+
using namespace QMatrixClient;
QMultiHash<QString, QString> DirectChatEvent::usersToDirectChats() const
diff --git a/lib/events/event.cpp b/lib/events/event.cpp
index 447068af..44bf79a1 100644
--- a/lib/events/event.cpp
+++ b/lib/events/event.cpp
@@ -18,13 +18,18 @@
#include "event.h"
-#include "redactionevent.h"
#include "logging.h"
#include <QtCore/QJsonDocument>
using namespace QMatrixClient;
+event_type_t QMatrixClient::nextTypeId()
+{
+ static event_type_t _id = EventTypeTraits<void>::id;
+ return ++_id;
+}
+
Event::Event(Type type, const QJsonObject& json)
: _type(type), _json(json)
{
@@ -61,75 +66,3 @@ const QJsonObject Event::unsignedJson() const
{
return fullJson()[UnsignedKeyL].toObject();
}
-
-[[gnu::unused]] static auto roomEventTypeInitialised =
- Event::factory_t::chainFactory<RoomEvent>();
-
-RoomEvent::RoomEvent(Type type, event_mtype_t matrixType,
- const QJsonObject& contentJson)
- : Event(type, matrixType, contentJson)
-{ }
-
-RoomEvent::RoomEvent(Type type, const QJsonObject& json)
- : Event(type, json)
-{
- const auto unsignedData = json[UnsignedKeyL].toObject();
- const auto redaction = unsignedData[RedactedCauseKeyL];
- if (redaction.isObject())
- {
- _redactedBecause = makeEvent<RedactionEvent>(redaction.toObject());
- return;
- }
-
- _txnId = unsignedData.value("transactionId"_ls).toString();
- if (!_txnId.isEmpty())
- qCDebug(EVENTS) << "Event transactionId:" << _txnId;
-}
-
-RoomEvent::~RoomEvent() = default; // Let the smart pointer do its job
-
-QString RoomEvent::id() const
-{
- return fullJson()[EventIdKeyL].toString();
-}
-
-QDateTime RoomEvent::timestamp() const
-{
- return QMatrixClient::fromJson<QDateTime>(fullJson()["origin_server_ts"_ls]);
-}
-
-QString RoomEvent::roomId() const
-{
- return fullJson()["room_id"_ls].toString();
-}
-
-QString RoomEvent::senderId() const
-{
- return fullJson()["sender"_ls].toString();
-}
-
-QString RoomEvent::redactionReason() const
-{
- return isRedacted() ? _redactedBecause->reason() : QString{};
-}
-
-void RoomEvent::addId(const QString& newId)
-{
- Q_ASSERT(id().isEmpty()); Q_ASSERT(!newId.isEmpty());
- editJson().insert(EventIdKey, newId);
-}
-
-[[gnu::unused]] static auto stateEventTypeInitialised =
- RoomEvent::factory_t::chainFactory<StateEventBase>();
-
-bool StateEventBase::repeatsState() const
-{
- const auto prevContentJson = unsignedJson().value(PrevContentKeyL);
- return fullJson().value(ContentKeyL) == prevContentJson;
-}
-
-event_type_t QMatrixClient::nextTypeId()
-{
- static event_type_t _id = EventTypeTraits<void>::id;
- return ++_id;
-}
diff --git a/lib/events/event.h b/lib/events/event.h
index 89ba94ac..04384aa7 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -18,10 +18,9 @@
#pragma once
-#include "converters.h"
#include "util.h"
-#include <typeindex>
+#include <QtCore/QJsonObject>
namespace QMatrixClient
{
@@ -167,39 +166,6 @@ namespace QMatrixClient
});
}
- /** Create an event with proper type from a JSON object
- * Use this factory template to detect the type from the JSON object
- * contents (the detected event type should derive from the template
- * parameter type) and create an event object of that type.
- */
- template <typename BaseEventT>
- inline event_ptr_tt<BaseEventT> loadEvent(const QJsonObject& fullJson)
- {
- return EventFactory<BaseEventT>
- ::make(fullJson, fullJson[TypeKeyL].toString());
- }
-
- /** Create an event from a type string and content JSON
- * Use this factory template to resolve the C++ type from the Matrix
- * type string in \p matrixType and create an event of that type that has
- * its content part set to \p content.
- */
- template <typename BaseEventT>
- inline event_ptr_tt<BaseEventT> loadEvent(const QString& matrixType,
- const QJsonObject& content)
- {
- return EventFactory<BaseEventT>
- ::make(basicEventJson(matrixType, content), matrixType);
- }
-
- template <typename EventT> struct FromJson<event_ptr_tt<EventT>>
- {
- auto operator()(const QJsonValue& jv) const
- {
- return loadEvent<EventT>(jv.toObject());
- }
- };
-
// === Event ===
class Event
@@ -313,144 +279,6 @@ namespace QMatrixClient
return return_type();
}
- // === RoomEvent ===
-
- class RedactionEvent;
-
- /** This class corresponds to m.room.* events */
- class RoomEvent : public Event
- {
- Q_GADGET
- Q_PROPERTY(QString id READ id)
- Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT)
- Q_PROPERTY(QString roomId READ roomId CONSTANT)
- Q_PROPERTY(QString senderId READ senderId CONSTANT)
- Q_PROPERTY(QString redactionReason READ redactionReason)
- Q_PROPERTY(bool isRedacted READ isRedacted)
- Q_PROPERTY(QString transactionId READ transactionId)
- public:
- using factory_t = EventFactory<RoomEvent>;
-
- // RedactionEvent is an incomplete type here so we cannot inline
- // constructors and destructors and we cannot use 'using'.
- RoomEvent(Type type, event_mtype_t matrixType,
- const QJsonObject& contentJson = {});
- RoomEvent(Type type, const QJsonObject& json);
- ~RoomEvent() override;
-
- QString id() const;
- QDateTime timestamp() const;
- QString roomId() const;
- QString senderId() const;
- bool isRedacted() const { return bool(_redactedBecause); }
- const event_ptr_tt<RedactionEvent>& redactedBecause() const
- {
- return _redactedBecause;
- }
- QString redactionReason() const;
- const QString& transactionId() const { return _txnId; }
-
- /**
- * Sets the transaction id for locally created events. This should be
- * done before the event is exposed to any code using the respective
- * Q_PROPERTY.
- *
- * \param txnId - transaction id, normally obtained from
- * Connection::generateTxnId()
- */
- void setTransactionId(const QString& txnId) { _txnId = txnId; }
-
- /**
- * Sets event id for locally created events
- *
- * When a new event is created locally, it has no server id yet.
- * This function allows to add the id once the confirmation from
- * the server is received. There should be no id set previously
- * in the event. It's the responsibility of the code calling addId()
- * to notify clients that use Q_PROPERTY(id) about its change
- */
- void addId(const QString& newId);
-
- private:
- event_ptr_tt<RedactionEvent> _redactedBecause;
- QString _txnId;
- };
- using RoomEventPtr = event_ptr_tt<RoomEvent>;
- using RoomEvents = EventsArray<RoomEvent>;
- using RoomEventsRange = Range<RoomEvents>;
-
- // === State events ===
-
- class StateEventBase: public RoomEvent
- {
- public:
- using factory_t = EventFactory<StateEventBase>;
-
- using RoomEvent::RoomEvent;
- ~StateEventBase() override = default;
-
- bool isStateEvent() const override { return true; }
- virtual bool repeatsState() const;
- };
- using StateEventPtr = event_ptr_tt<StateEventBase>;
- using StateEvents = EventsArray<StateEventBase>;
-
- template <typename ContentT>
- struct Prev
- {
- template <typename... ContentParamTs>
- explicit Prev(const QJsonObject& unsignedJson,
- ContentParamTs&&... contentParams)
- : senderId(unsignedJson.value("prev_sender"_ls).toString())
- , content(unsignedJson.value(PrevContentKeyL).toObject(),
- std::forward<ContentParamTs>(contentParams)...)
- { }
-
- QString senderId;
- ContentT content;
- };
-
- template <typename ContentT>
- class StateEvent: public StateEventBase
- {
- public:
- using content_type = ContentT;
-
- template <typename... ContentParamTs>
- explicit StateEvent(Type type, const QJsonObject& fullJson,
- ContentParamTs&&... contentParams)
- : StateEventBase(type, fullJson)
- , _content(contentJson(),
- std::forward<ContentParamTs>(contentParams)...)
- {
- const auto& unsignedData = unsignedJson();
- if (unsignedData.contains(PrevContentKeyL))
- _prev = std::make_unique<Prev<ContentT>>(unsignedData,
- std::forward<ContentParamTs>(contentParams)...);
- }
- template <typename... ContentParamTs>
- explicit StateEvent(Type type, event_mtype_t matrixType,
- ContentParamTs&&... contentParams)
- : StateEventBase(type, matrixType)
- , _content(std::forward<ContentParamTs>(contentParams)...)
- {
- editJson().insert(ContentKey, _content.toJson());
- }
-
- const ContentT& content() const { return _content; }
- [[deprecated("Use prevContent instead")]]
- const ContentT* prev_content() const { return prevContent(); }
- const ContentT* prevContent() const
- { return _prev ? &_prev->content : nullptr; }
- QString prevSenderId() const
- { return _prev ? _prev->senderId : QString(); }
-
- protected:
- ContentT _content;
- std::unique_ptr<Prev<ContentT>> _prev;
- };
} // namespace QMatrixClient
Q_DECLARE_METATYPE(QMatrixClient::Event*)
-Q_DECLARE_METATYPE(QMatrixClient::RoomEvent*)
Q_DECLARE_METATYPE(const QMatrixClient::Event*)
-Q_DECLARE_METATYPE(const QMatrixClient::RoomEvent*)
diff --git a/lib/events/eventloader.h b/lib/events/eventloader.h
new file mode 100644
index 00000000..5f1e3b57
--- /dev/null
+++ b/lib/events/eventloader.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* 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
+*/
+
+#pragma once
+
+#include "stateevent.h"
+#include "converters.h"
+
+namespace QMatrixClient {
+ /** Create an event with proper type from a JSON object
+ * Use this factory template to detect the type from the JSON object
+ * contents (the detected event type should derive from the template
+ * parameter type) and create an event object of that type.
+ */
+ template <typename BaseEventT>
+ inline event_ptr_tt<BaseEventT> loadEvent(const QJsonObject& fullJson)
+ {
+ return EventFactory<BaseEventT>
+ ::make(fullJson, fullJson[TypeKeyL].toString());
+ }
+
+ /** Create an event from a type string and content JSON
+ * Use this factory template to resolve the C++ type from the Matrix
+ * type string in \p matrixType and create an event of that type that has
+ * its content part set to \p content.
+ */
+ template <typename BaseEventT>
+ inline event_ptr_tt<BaseEventT> loadEvent(const QString& matrixType,
+ const QJsonObject& content)
+ {
+ return EventFactory<BaseEventT>
+ ::make(basicEventJson(matrixType, content), matrixType);
+ }
+
+ template <typename EventT> struct FromJson<event_ptr_tt<EventT>>
+ {
+ auto operator()(const QJsonValue& jv) const
+ {
+ return loadEvent<EventT>(jv.toObject());
+ }
+ };
+} // namespace QMatrixClient
diff --git a/lib/events/receiptevent.cpp b/lib/events/receiptevent.cpp
index 3451a40e..47e1398c 100644
--- a/lib/events/receiptevent.cpp
+++ b/lib/events/receiptevent.cpp
@@ -35,6 +35,7 @@ Example of a Receipt Event:
#include "receiptevent.h"
+#include "converters.h"
#include "logging.h"
using namespace QMatrixClient;
diff --git a/lib/events/receiptevent.h b/lib/events/receiptevent.h
index 5237ba69..c15a01c2 100644
--- a/lib/events/receiptevent.h
+++ b/lib/events/receiptevent.h
@@ -21,6 +21,7 @@
#include "event.h"
#include <QtCore/QVector>
+#include <QtCore/QDateTime>
namespace QMatrixClient
{
diff --git a/lib/events/roomevent.cpp b/lib/events/roomevent.cpp
new file mode 100644
index 00000000..3d09af8a
--- /dev/null
+++ b/lib/events/roomevent.cpp
@@ -0,0 +1,82 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* 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 "roomevent.h"
+
+#include "redactionevent.h"
+#include "converters.h"
+#include "logging.h"
+
+using namespace QMatrixClient;
+
+[[gnu::unused]] static auto roomEventTypeInitialised =
+ Event::factory_t::chainFactory<RoomEvent>();
+
+RoomEvent::RoomEvent(Type type, event_mtype_t matrixType,
+ const QJsonObject& contentJson)
+ : Event(type, matrixType, contentJson)
+{ }
+
+RoomEvent::RoomEvent(Type type, const QJsonObject& json)
+ : Event(type, json)
+{
+ const auto unsignedData = json[UnsignedKeyL].toObject();
+ const auto redaction = unsignedData[RedactedCauseKeyL];
+ if (redaction.isObject())
+ {
+ _redactedBecause = makeEvent<RedactionEvent>(redaction.toObject());
+ return;
+ }
+
+ _txnId = unsignedData.value("transactionId"_ls).toString();
+ if (!_txnId.isEmpty())
+ qCDebug(EVENTS) << "Event transactionId:" << _txnId;
+}
+
+RoomEvent::~RoomEvent() = default; // Let the smart pointer do its job
+
+QString RoomEvent::id() const
+{
+ return fullJson()[EventIdKeyL].toString();
+}
+
+QDateTime RoomEvent::timestamp() const
+{
+ return QMatrixClient::fromJson<QDateTime>(fullJson()["origin_server_ts"_ls]);
+}
+
+QString RoomEvent::roomId() const
+{
+ return fullJson()["room_id"_ls].toString();
+}
+
+QString RoomEvent::senderId() const
+{
+ return fullJson()["sender"_ls].toString();
+}
+
+QString RoomEvent::redactionReason() const
+{
+ return isRedacted() ? _redactedBecause->reason() : QString{};
+}
+
+void RoomEvent::addId(const QString& newId)
+{
+ Q_ASSERT(id().isEmpty()); Q_ASSERT(!newId.isEmpty());
+ editJson().insert(EventIdKey, newId);
+}
diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h
new file mode 100644
index 00000000..ff50a83d
--- /dev/null
+++ b/lib/events/roomevent.h
@@ -0,0 +1,89 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* 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
+*/
+
+#pragma once
+
+#include "event.h"
+
+namespace QMatrixClient {
+ class RedactionEvent;
+
+ /** This class corresponds to m.room.* events */
+ class RoomEvent : public Event
+ {
+ Q_GADGET
+ Q_PROPERTY(QString id READ id)
+ Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT)
+ Q_PROPERTY(QString roomId READ roomId CONSTANT)
+ Q_PROPERTY(QString senderId READ senderId CONSTANT)
+ Q_PROPERTY(QString redactionReason READ redactionReason)
+ Q_PROPERTY(bool isRedacted READ isRedacted)
+ Q_PROPERTY(QString transactionId READ transactionId)
+ public:
+ using factory_t = EventFactory<RoomEvent>;
+
+ // RedactionEvent is an incomplete type here so we cannot inline
+ // constructors and destructors and we cannot use 'using'.
+ RoomEvent(Type type, event_mtype_t matrixType,
+ const QJsonObject& contentJson = {});
+ RoomEvent(Type type, const QJsonObject& json);
+ ~RoomEvent() override;
+
+ QString id() const;
+ QDateTime timestamp() const;
+ QString roomId() const;
+ QString senderId() const;
+ bool isRedacted() const { return bool(_redactedBecause); }
+ const event_ptr_tt<RedactionEvent>& redactedBecause() const
+ {
+ return _redactedBecause;
+ }
+ QString redactionReason() const;
+ const QString& transactionId() const { return _txnId; }
+
+ /**
+ * Sets the transaction id for locally created events. This should be
+ * done before the event is exposed to any code using the respective
+ * Q_PROPERTY.
+ *
+ * \param txnId - transaction id, normally obtained from
+ * Connection::generateTxnId()
+ */
+ void setTransactionId(const QString& txnId) { _txnId = txnId; }
+
+ /**
+ * Sets event id for locally created events
+ *
+ * When a new event is created locally, it has no server id yet.
+ * This function allows to add the id once the confirmation from
+ * the server is received. There should be no id set previously
+ * in the event. It's the responsibility of the code calling addId()
+ * to notify clients that use Q_PROPERTY(id) about its change
+ */
+ void addId(const QString& newId);
+
+ private:
+ event_ptr_tt<RedactionEvent> _redactedBecause;
+ QString _txnId;
+ };
+ using RoomEventPtr = event_ptr_tt<RoomEvent>;
+ using RoomEvents = EventsArray<RoomEvent>;
+ using RoomEventsRange = Range<RoomEvents>;
+} // namespace QMatrixClient
+Q_DECLARE_METATYPE(QMatrixClient::RoomEvent*)
+Q_DECLARE_METATYPE(const QMatrixClient::RoomEvent*)
diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp
index 3acce7cb..79e4af2d 100644
--- a/lib/events/roommemberevent.cpp
+++ b/lib/events/roommemberevent.cpp
@@ -18,6 +18,7 @@
#include "roommemberevent.h"
+#include "converters.h"
#include "logging.h"
#include <array>
diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h
index 1ecd63d1..f3e4f53a 100644
--- a/lib/events/roommemberevent.h
+++ b/lib/events/roommemberevent.h
@@ -18,8 +18,7 @@
#pragma once
-#include "event.h"
-
+#include "stateevent.h"
#include "eventcontent.h"
namespace QMatrixClient
diff --git a/lib/events/roommessageevent.h b/lib/events/roommessageevent.h
index ccf30f96..4c29a93e 100644
--- a/lib/events/roommessageevent.h
+++ b/lib/events/roommessageevent.h
@@ -18,8 +18,7 @@
#pragma once
-#include "event.h"
-
+#include "roomevent.h"
#include "eventcontent.h"
namespace QMatrixClient
diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h
index afd59478..fa1ca8f4 100644
--- a/lib/events/simplestateevents.h
+++ b/lib/events/simplestateevents.h
@@ -18,7 +18,7 @@
#pragma once
-#include "event.h"
+#include "stateevent.h"
#include "eventcontent.h"
namespace QMatrixClient
diff --git a/lib/events/stateevent.cpp b/lib/events/stateevent.cpp
new file mode 100644
index 00000000..fd5d2642
--- /dev/null
+++ b/lib/events/stateevent.cpp
@@ -0,0 +1,30 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* 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 "stateevent.h"
+
+using namespace QMatrixClient;
+
+[[gnu::unused]] static auto stateEventTypeInitialised =
+ RoomEvent::factory_t::chainFactory<StateEventBase>();
+
+bool StateEventBase::repeatsState() const
+{
+ const auto prevContentJson = unsignedJson().value(PrevContentKeyL);
+ return fullJson().value(ContentKeyL) == prevContentJson;
+}
diff --git a/lib/events/stateevent.h b/lib/events/stateevent.h
new file mode 100644
index 00000000..6032132e
--- /dev/null
+++ b/lib/events/stateevent.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* 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
+*/
+
+#pragma once
+
+#include "roomevent.h"
+
+namespace QMatrixClient {
+ class StateEventBase: public RoomEvent
+ {
+ public:
+ using factory_t = EventFactory<StateEventBase>;
+
+ using RoomEvent::RoomEvent;
+ ~StateEventBase() override = default;
+
+ bool isStateEvent() const override { return true; }
+ virtual bool repeatsState() const;
+ };
+ using StateEventPtr = event_ptr_tt<StateEventBase>;
+ using StateEvents = EventsArray<StateEventBase>;
+
+ template <typename ContentT>
+ struct Prev
+ {
+ template <typename... ContentParamTs>
+ explicit Prev(const QJsonObject& unsignedJson,
+ ContentParamTs&&... contentParams)
+ : senderId(unsignedJson.value("prev_sender"_ls).toString())
+ , content(unsignedJson.value(PrevContentKeyL).toObject(),
+ std::forward<ContentParamTs>(contentParams)...)
+ { }
+
+ QString senderId;
+ ContentT content;
+ };
+
+ template <typename ContentT>
+ class StateEvent: public StateEventBase
+ {
+ public:
+ using content_type = ContentT;
+
+ template <typename... ContentParamTs>
+ explicit StateEvent(Type type, const QJsonObject& fullJson,
+ ContentParamTs&&... contentParams)
+ : StateEventBase(type, fullJson)
+ , _content(contentJson(),
+ std::forward<ContentParamTs>(contentParams)...)
+ {
+ const auto& unsignedData = unsignedJson();
+ if (unsignedData.contains(PrevContentKeyL))
+ _prev = std::make_unique<Prev<ContentT>>(unsignedData,
+ std::forward<ContentParamTs>(contentParams)...);
+ }
+ template <typename... ContentParamTs>
+ explicit StateEvent(Type type, event_mtype_t matrixType,
+ ContentParamTs&&... contentParams)
+ : StateEventBase(type, matrixType)
+ , _content(std::forward<ContentParamTs>(contentParams)...)
+ {
+ editJson().insert(ContentKey, _content.toJson());
+ }
+
+ const ContentT& content() const { return _content; }
+ [[deprecated("Use prevContent instead")]]
+ const ContentT* prev_content() const { return prevContent(); }
+ const ContentT* prevContent() const
+ { return _prev ? &_prev->content : nullptr; }
+ QString prevSenderId() const
+ { return _prev ? _prev->senderId : QString(); }
+
+ protected:
+ ContentT _content;
+ std::unique_ptr<Prev<ContentT>> _prev;
+ };
+} // namespace QMatrixClient
diff --git a/lib/events/typingevent.cpp b/lib/events/typingevent.cpp
index c7b69e33..0d39d1be 100644
--- a/lib/events/typingevent.cpp
+++ b/lib/events/typingevent.cpp
@@ -18,6 +18,8 @@
#include "typingevent.h"
+#include <QtCore/QJsonArray>
+
using namespace QMatrixClient;
TypingEvent::TypingEvent(const QJsonObject& obj)
diff --git a/lib/jobs/syncjob.cpp b/lib/jobs/syncjob.cpp
index 7e5f2e0f..02690e6d 100644
--- a/lib/jobs/syncjob.cpp
+++ b/lib/jobs/syncjob.cpp
@@ -18,6 +18,8 @@
#include "syncjob.h"
+#include "events/eventloader.h"
+
#include <QtCore/QElapsedTimer>
using namespace QMatrixClient;
diff --git a/lib/jobs/syncjob.h b/lib/jobs/syncjob.h
index ca30848e..6b9bedfa 100644
--- a/lib/jobs/syncjob.h
+++ b/lib/jobs/syncjob.h
@@ -21,7 +21,7 @@
#include "basejob.h"
#include "joinstate.h"
-#include "events/event.h"
+#include "events/stateevent.h"
#include "util.h"
namespace QMatrixClient