From f1ffe1e7a3e81c07a07a8416ce307e4413ec8fbc Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 1 Jul 2018 22:48:38 +0900 Subject: Event types system remade to be extensible There were two common points that had to be updated every time a new event is introduced: the EventType enumeration and one of 3 doMakeEvent<> specialisations. The new code has a template class, EventFactory<>, that uses a list of static factory methods to create events instead of typelists used in doMakeEvent<>(); the EventType enumeration is replaced with a namespace populated with constants as necessary. In general, EventType is considered a deprecated mechanism altogether; instead, a set of facilities is provided: is<>() to check if an event has a certain type (to replace comparison against an EventType value) and visit<>() to execute actions based on the event type (replacing switch statements over EventType values). Closes #129. --- lib/connection.cpp | 7 +- lib/converters.h | 6 +- lib/events/accountdataevents.h | 39 ++--- lib/events/directchatevent.cpp | 8 +- lib/events/directchatevent.h | 9 +- lib/events/event.cpp | 140 ++++++---------- lib/events/event.h | 349 ++++++++++++++++++++++++++++------------ lib/events/eventcontent.cpp | 25 +-- lib/events/eventcontent.h | 36 +---- lib/events/receiptevent.cpp | 12 +- lib/events/receiptevent.h | 6 +- lib/events/redactionevent.h | 17 +- lib/events/roomavatarevent.h | 10 +- lib/events/roommemberevent.cpp | 14 +- lib/events/roommemberevent.h | 23 +-- lib/events/roommessageevent.cpp | 88 ++++++---- lib/events/roommessageevent.h | 26 ++- lib/events/simplestateevents.h | 68 ++++++-- lib/events/typingevent.cpp | 8 +- lib/events/typingevent.h | 7 +- lib/jobs/sendeventjob.h | 4 +- lib/room.cpp | 247 +++++++++++++--------------- lib/room.h | 6 +- lib/user.h | 8 + lib/util.h | 41 +++++ 25 files changed, 676 insertions(+), 528 deletions(-) (limited to 'lib') diff --git a/lib/connection.cpp b/lib/connection.cpp index 8fd960b6..339be5b9 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -355,9 +355,9 @@ void Connection::onSyncSuccess(SyncData &&data) { continue; } - d->accountData[accountEvent->jsonType()] = + d->accountData[accountEvent->matrixType()] = fromJson(accountEvent->contentJson()); - emit accountDataChanged(accountEvent->jsonType()); + emit accountDataChanged(accountEvent->matrixType()); } } @@ -603,7 +603,7 @@ SendToDeviceJob* Connection::sendToDevices(const QString& eventType, std::for_each(devicesToEvents.begin(), devicesToEvents.end(), [&jsonUser] (const auto& deviceToEvents) { jsonUser.insert(deviceToEvents.first, - deviceToEvents.second.toJson()); + deviceToEvents.second.contentJson()); }); }); return callApi(BackgroundRequest, @@ -1048,4 +1048,3 @@ void Connection::setCacheState(bool newValue) emit cacheStateChanged(); } } - diff --git a/lib/converters.h b/lib/converters.h index a59809e7..c01d7c8e 100644 --- a/lib/converters.h +++ b/lib/converters.h @@ -18,10 +18,14 @@ #pragma once +#include "util.h" + #include #include // Includes #include #include +#include +#include #include #include @@ -351,7 +355,7 @@ namespace QMatrixClient template inline void addTo(QUrlQuery& q, const QString& k, ValT&& v) - { q.addQueryItem(k, QString("%1").arg(v)); } + { q.addQueryItem(k, QStringLiteral("%1").arg(v)); } // OpenAPI is entirely JSON-based, which means representing bools as // textual true/false, rather than 1/0. diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h index 11667172..6d53d2aa 100644 --- a/lib/events/accountdataevents.h +++ b/lib/events/accountdataevents.h @@ -32,7 +32,7 @@ namespace QMatrixClient { TagRecord (QString order = {}) : order(std::move(order)) { } explicit TagRecord(const QJsonValue& jv) - : order(jv.toObject().value("order").toString()) + : order(jv.toObject().value("order"_ls).toString()) { } QString order; @@ -50,28 +50,29 @@ namespace QMatrixClient using TagsMap = QHash; -#define DEFINE_SIMPLE_EVENT(_Name, _TypeId, _EnumType, _ContentType, _ContentKey) \ +#define DEFINE_SIMPLE_EVENT(_Name, _TypeId, _ContentType, _ContentKey) \ class _Name : public Event \ { \ public: \ - static constexpr const char* typeId() { return _TypeId; } \ - explicit _Name(const QJsonObject& obj) \ - : Event((_EnumType), obj) \ - , _content(contentJson(), QStringLiteral(#_ContentKey)) \ + using content_type = _ContentType; \ + DEFINE_EVENT_TYPEID(_TypeId, _Name) \ + explicit _Name(QJsonObject obj) \ + : Event(typeId(), std::move(obj)) \ { } \ - template \ - explicit _Name(Ts&&... contentArgs) \ - : Event(_EnumType) \ - , _content(QStringLiteral(#_ContentKey), \ - std::forward(contentArgs)...) \ + explicit _Name(_ContentType content) \ + : Event(typeId(), matrixTypeId(), \ + QJsonObject { { QStringLiteral(#_ContentKey), \ + toJson(std::move(content)) } }) \ { } \ - const _ContentType& _ContentKey() const { return _content.value; } \ - QJsonObject toJson() const { return _content.toJson(); } \ - protected: \ - EventContent::SimpleContent<_ContentType> _content; \ - }; + auto _ContentKey() const \ + { return fromJson(contentJson()[#_ContentKey]); } \ + }; // End of macro + + DEFINE_SIMPLE_EVENT(TagEvent, "m.tag", TagsMap, tags) + DEFINE_SIMPLE_EVENT(ReadMarkerEvent, "m.fully_read", QString, event_id) + DEFINE_SIMPLE_EVENT(IgnoredUsersEvent, "m.ignored_user_list", + QSet, ignored_users) - DEFINE_SIMPLE_EVENT(TagEvent, "m.tag", EventType::Tag, TagsMap, tags) - DEFINE_SIMPLE_EVENT(ReadMarkerEvent, "m.fully_read", EventType::ReadMarker, - QString, event_id) + DEFINE_EVENTTYPE_ALIAS(Tag, TagEvent) + DEFINE_EVENTTYPE_ALIAS(ReadMarker, ReadMarkerEvent) } diff --git a/lib/events/directchatevent.cpp b/lib/events/directchatevent.cpp index 63d638a3..6f5d34f2 100644 --- a/lib/events/directchatevent.cpp +++ b/lib/events/directchatevent.cpp @@ -18,18 +18,12 @@ #include "directchatevent.h" -#include "converters.h" - using namespace QMatrixClient; -DirectChatEvent::DirectChatEvent(const QJsonObject& obj) - : Event(Type::DirectChat, obj) -{ } - QMultiHash DirectChatEvent::usersToDirectChats() const { QMultiHash result; - const auto json = contentJson(); + const auto& json = contentJson(); for (auto it = json.begin(); it != json.end(); ++it) { // Beware of range-for's over temporary returned from temporary diff --git a/lib/events/directchatevent.h b/lib/events/directchatevent.h index bd8f2d35..1d366721 100644 --- a/lib/events/directchatevent.h +++ b/lib/events/directchatevent.h @@ -25,10 +25,13 @@ namespace QMatrixClient class DirectChatEvent : public Event { public: - explicit DirectChatEvent(const QJsonObject& obj); + DEFINE_EVENT_TYPEID("m.direct", DirectChatEvent) - QMultiHash usersToDirectChats() const; + explicit DirectChatEvent(const QJsonObject& obj) + : Event(typeId(), obj) + { } - static constexpr const char* typeId() { return "m.direct"; } + QMultiHash usersToDirectChats() const; }; + DEFINE_EVENTTYPE_ALIAS(DirectChat, DirectChatEvent) } diff --git a/lib/events/event.cpp b/lib/events/event.cpp index 576e9426..3f507347 100644 --- a/lib/events/event.cpp +++ b/lib/events/event.cpp @@ -33,117 +33,93 @@ using namespace QMatrixClient; -Event::Event(Type type, const QJsonObject& rep) - : _type(type), _originalJson(rep) +event_type_t EventTypeRegistry::nextTypeId() { - if (!rep.contains("content") && - !rep.value("unsigned").toObject().contains("redacted_because")) + static event_type_t typeIndex = unknownTypeId(); + return ++typeIndex; +} + +Event::Event(Type type, const QJsonObject& json) + : _type(type), _json(json) +{ + if (!json.contains(ContentKeyL) && + !json.value(UnsignedKeyL).toObject().contains(RedactedCauseKeyL)) { qCWarning(EVENTS) << "Event without 'content' node"; - qCWarning(EVENTS) << formatJson << rep; + qCWarning(EVENTS) << formatJson << json; } } +Event::Event(Type type, event_mtype_t matrixType, const QJsonObject& contentJson) + : Event(type, basicEventJson(matrixType, contentJson)) +{ } + Event::~Event() = default; -QString Event::jsonType() const +QString Event::matrixType() const { - return originalJsonObject().value("type").toString(); + return fullJson()[TypeKeyL].toString(); } QByteArray Event::originalJson() const { - return QJsonDocument(_originalJson).toJson(); -} - -QJsonObject Event::originalJsonObject() const -{ - return _originalJson; + return QJsonDocument(_json).toJson(); } const QJsonObject Event::contentJson() const { - return _originalJson["content"].toObject(); -} - -template -inline event_ptr_tt makeIfMatches(const QJsonObject&, const QString&) -{ - return nullptr; + return fullJson()[ContentKeyL].toObject(); } -template -inline event_ptr_tt makeIfMatches(const QJsonObject& o, - const QString& selector) +const QJsonObject Event::unsignedJson() const { - if (selector == EventT::typeId()) - return _impl::create(o); - - return makeIfMatches(o, selector); + return fullJson()[UnsignedKeyL].toObject(); } -template <> -EventPtr _impl::doMakeEvent(const QJsonObject& obj) -{ - // Check more specific event types first - if (auto e = doMakeEvent(obj)) - return ptrCast(move(e)); - - return makeIfMatches( - obj, obj["type"].toString()); -} +[[gnu::unused]] static auto roomEventTypeInitialised = + EventTypeRegistry::chainFactories(); -RoomEvent::RoomEvent(Event::Type type) : Event(type) { } +RoomEvent::RoomEvent(Type type, event_mtype_t matrixType, + const QJsonObject& contentJson) + : Event(type, matrixType, contentJson) +{ } -RoomEvent::RoomEvent(Type type, const QJsonObject& rep) - : Event(type, rep) - , _id(rep["event_id"].toString()) +RoomEvent::RoomEvent(Type type, const QJsonObject& json) + : Event(type, json) { -// 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) << "Can't find server timestamp in a room event"; -// qCWarning(EVENTS) << formatJson << rep; -// } -// if (_senderId.isEmpty()) -// { -// qCWarning(EVENTS) << "Can't find sender in a room event"; -// qCWarning(EVENTS) << formatJson << rep; -// } - auto unsignedData = rep["unsigned"].toObject(); - auto redaction = unsignedData.value("redacted_because"); + const auto unsignedData = json[UnsignedKeyL].toObject(); + const auto redaction = unsignedData[RedactedCauseKeyL]; if (redaction.isObject()) { - _redactedBecause = _impl::create(redaction.toObject()); + _redactedBecause = makeEvent(redaction.toObject()); return; } - _txnId = unsignedData.value("transactionId").toString(); + _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( - originalJsonObject().value("origin_server_ts")); + return QMatrixClient::fromJson(fullJson()["origin_server_ts"_ls]); } QString RoomEvent::roomId() const { - return originalJsonObject().value("room_id").toString(); + return fullJson()["room_id"_ls].toString(); } QString RoomEvent::senderId() const { - return originalJsonObject().value("sender").toString(); + return fullJson()["sender"_ls].toString(); } QString RoomEvent::redactionReason() const @@ -151,37 +127,17 @@ QString RoomEvent::redactionReason() const return isRedacted() ? _redactedBecause->reason() : QString{}; } -void RoomEvent::addId(const QString& id) +void RoomEvent::addId(const QString& newId) { - Q_ASSERT(_id.isEmpty()); Q_ASSERT(!id.isEmpty()); - _id = id; + Q_ASSERT(id().isEmpty()); Q_ASSERT(!newId.isEmpty()); + editJson().insert(EventIdKey, newId); } -template <> -RoomEventPtr _impl::doMakeEvent(const QJsonObject& obj) -{ - // Check more specific event types first - if (auto e = doMakeEvent(obj)) - return ptrCast(move(e)); - - return makeIfMatches(obj, obj["type"].toString()); -} +[[gnu::unused]] static auto stateEventTypeInitialised = + EventTypeRegistry::chainFactories(); bool StateEventBase::repeatsState() const { - auto contentJson = originalJsonObject().value("content"); - auto prevContentJson = originalJsonObject().value("unsigned") - .toObject().value("prev_content"); - return contentJson == prevContentJson; -} - -template<> -StateEventPtr _impl::doMakeEvent(const QJsonObject& obj) -{ - return makeIfMatches(obj, obj["type"].toString()); - + const auto prevContentJson = unsignedJson().value(PrevContentKeyL); + return fullJson().value(ContentKeyL) == prevContentJson; } diff --git a/lib/events/event.h b/lib/events/event.h index cbfa06ac..f8264baf 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -23,6 +23,8 @@ namespace QMatrixClient { + // === event_ptr_tt<> and type casting facilities === + template using event_ptr_tt = std::unique_ptr; @@ -44,106 +46,262 @@ namespace QMatrixClient return unique_ptr_cast(ptr); } - namespace _impl + // === Predefined types and JSON key names + + using event_type_t = uint; + using event_mtype_t = const char*; + + static const auto TypeKey = QStringLiteral("type"); + static const auto ContentKey = QStringLiteral("content"); + static const auto EventIdKey = QStringLiteral("event_id"); + static const auto TypeKeyL = "type"_ls; + static const auto ContentKeyL = "content"_ls; + static const auto EventIdKeyL = "event_id"_ls; + static const auto UnsignedKeyL = "unsigned"_ls; + static const auto RedactedCauseKeyL = "redacted_because"_ls; + static const auto PrevContentKeyL = "prev_content"_ls; + + // === Event factory === + + template + inline event_ptr_tt makeEvent(ArgTs&&... args) { - template - inline event_ptr_tt create(ArgTs&&... args) - { - return std::make_unique(std::forward(args)...); - } + return std::make_unique(std::forward(args)...); + } + + class EventTypeRegistry + { + public: + static constexpr event_type_t unknownTypeId() { return 0; } + static event_type_t nextTypeId(); + + /** Chain two type factories + * Adds the factory class of EventT2 (EventT2::factory_t) to + * the list in factory class of EventT1 (EventT1::factory_t) so + * that when EventT1::factory_t::make() is invoked, types of + * EventT2 factory are looked through as well. This is used + * to include RoomEvent types into the more general Event factory, + * and state event types into the RoomEvent factory. + */ + template + static auto chainFactories() + { + EventT1::factory_t::addFactory(&EventT2::factory_t::make); + return 0; + } + + /** Add a type to its default factory + * Adds a standard factory method (via makeEvent<>) for a given + * type to EventT::factory_t factory class so that it can be + * created dynamically from loadEvent<>(). + * + * \tparam EventT the type to enable dynamic creation of + * \return the registered type id + * \sa loadEvent, Event::type + */ + template + static auto addType() + { + EventT::factory_t::addFactory( + [] (const QJsonObject& json, const QString& jsonMatrixType) + { + return EventT::matrixTypeId() == jsonMatrixType + ? makeEvent(json) : nullptr; + }); + return nextTypeId(); + } + + template + static auto typeId() { return _typeId>; } + + private: + template + static const event_type_t _typeId; + }; + + template + const event_type_t EventTypeRegistry::_typeId = addType(); + + template + class EventFactory + { + public: + template + static void addFactory(FnT&& factory) + { + factories().emplace_back(std::forward(factory)); + } + + static event_ptr_tt make(const QJsonObject& json, + const QString& matrixType) + { + for (const auto& f: factories()) + if (auto e = f(json, matrixType)) + return e; + return makeEvent(EventTypeRegistry::unknownTypeId(), + json); + } + + private: + static auto& factories() + { + using inner_factory_tt = + std::function(const QJsonObject&, + const QString&)>; + static std::vector _factories {}; + return _factories; + } + }; + + template + inline QJsonObject basicEventJson(StrT matrixType, + const QJsonObject& content) + { + return { { TypeKey, std::forward(matrixType) }, + { ContentKey, content } }; + } + + /** 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 + inline event_ptr_tt loadEvent(const QJsonObject& fullJson) + { + return EventFactory + ::make(fullJson, fullJson[TypeKeyL].toString()); + } - template - inline event_ptr_tt doMakeEvent(const QJsonObject& obj) + /** 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 + inline event_ptr_tt loadEvent(const QString& matrixType, + const QJsonObject& content) + { + return EventFactory + ::make(basicEventJson(matrixType, content), matrixType); + } + + template struct FromJson> + { + auto operator()(const QJsonValue& jv) const { - return create(obj); + return loadEvent(jv.toObject()); } - } + }; + + // === Event === class Event { Q_GADGET public: - enum class Type : quint16 - { - Unknown = 0, - Typing, Receipt, Tag, DirectChat, ReadMarker, - RoomEventBase = 0x1000, - RoomMessage = RoomEventBase + 1, - RoomEncryptedMessage, Redaction, - RoomStateEventBase = 0x1800, - RoomName = RoomStateEventBase + 1, - RoomAliases, RoomCanonicalAlias, RoomMember, RoomTopic, - RoomAvatar, RoomEncryption, RoomCreate, RoomJoinRules, - RoomPowerLevels, - Reserved = 0x2000 - }; - - explicit Event(Type type) : _type(type) { } - Event(Type type, const QJsonObject& rep); + using Type = event_type_t; + using factory_t = EventFactory; + + explicit Event(Type type, const QJsonObject& json); + explicit Event(Type type, event_mtype_t matrixType, + const QJsonObject& contentJson = {}); Event(const Event&) = delete; + Event(Event&&) = default; + Event& operator=(const Event&) = delete; + Event& operator=(Event&&) = delete; virtual ~Event(); Type type() const { return _type; } - QString jsonType() const; - bool isStateEvent() const - { - return (quint16(_type) & 0x1800) == 0x1800; - } + QString matrixType() const; QByteArray originalJson() const; - QJsonObject originalJsonObject() const; + QJsonObject originalJsonObject() const { return fullJson(); } + + const QJsonObject& fullJson() const { return _json; } // According to the CS API spec, 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). + // different types, we're implementing it per-event type. const QJsonObject contentJson() const; + const QJsonObject unsignedJson() const; + + virtual bool isStateEvent() const { return false; } + + template + bool is() const + { + const auto eventTypeId = EventTypeRegistry::typeId(); + return _type == eventTypeId; + } - virtual QJsonObject toJson() const { Q_ASSERT(false); return {}; } + protected: + QJsonObject& editJson() { return _json; } private: Type _type; - QJsonObject _originalJson; + QJsonObject _json; - REGISTER_ENUM(Type) Q_PROPERTY(Type type READ type CONSTANT) Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT) }; - using EventType = Event::Type; using EventPtr = event_ptr_tt; - /** 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 - inline event_ptr_tt makeEvent(const QJsonObject& obj) + using EventsArray = std::vector>; + using Events = EventsArray; + + // This macro should be used in a public section of an event class to + // provide matrixTypeId() and typeId(). +#define DEFINE_EVENT_TYPEID(_Id, _Type) \ + static constexpr event_mtype_t matrixTypeId() { return _Id; } \ + static event_type_t typeId() { return EventTypeRegistry::typeId<_Type>(); } + + // This macro should be put after an event class definition to define an + // additional constant that can be used for an event type id. The constant + // will be inside EventType namespace. This is for back-compatibility, + // to support clients checking for EventType::ShortName (previously + // EventType was a typedef for an enumeration). New code should use + // either typeId() for a specific event type, or (better) casting methods + // defined in the very beginning of this file. +#define DEFINE_EVENTTYPE_ALIAS(_Id, _Type) \ + namespace EventType \ + { \ + [[deprecated("Use "#_Type"::typeId(), Event::is<>() or visit<>()")]] \ + static const auto _Id { _Type::typeId() }; \ + } // End of macro + + // === visit<>() === + + template + inline fn_return_t visit(const Event& event, FnT visitor) { - auto e = _impl::doMakeEvent(obj); - if (!e) - e = _impl::create(EventType::Unknown, obj); - return e; + using event_type = fn_arg_t; + if (event.is()) + return visitor(static_cast(event)); + return fn_return_t(); } - namespace _impl + template + inline auto visit(const Event& event, FnT visitor1, FnTs&&... visitors) { - template <> - EventPtr doMakeEvent(const QJsonObject& obj); + using event_type1 = fn_arg_t; + if (event.is()) + return visitor1(static_cast(event)); + + return visit(event, std::forward(visitors)...); } - template struct FromJson> + template + inline auto visit(const event_ptr_tt& eptr, FnTs&&... visitors) { - auto operator()(const QJsonValue& jv) const - { - return makeEvent(jv.toObject()); - } - }; + using return_type = decltype(visit(*eptr, visitors...)); + if (eptr) + return visit(*eptr, visitors...); + return return_type(); + } - template - using EventsArray = std::vector>; - using Events = EventsArray; + // === RoomEvent === class RedactionEvent; @@ -159,13 +317,16 @@ namespace QMatrixClient Q_PROPERTY(bool isRedacted READ isRedacted) Q_PROPERTY(QString transactionId READ transactionId) public: + using factory_t = EventFactory; + // RedactionEvent is an incomplete type here so we cannot inline - // constructors and destructors - explicit RoomEvent(Type type); - RoomEvent(Type type, const QJsonObject& rep); + // 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 { return _id; } + QString id() const; QDateTime timestamp() const; QString roomId() const; QString senderId() const; @@ -196,10 +357,9 @@ namespace QMatrixClient * 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& id); + void addId(const QString& newId); private: - QString _id; event_ptr_tt _redactedBecause; QString _txnId; }; @@ -207,43 +367,30 @@ namespace QMatrixClient using RoomEvents = EventsArray; using RoomEventsRange = Range; - namespace _impl - { - template <> - RoomEventPtr doMakeEvent(const QJsonObject& obj); - } + // === State events === class StateEventBase: public RoomEvent { public: - explicit StateEventBase(Type type, const QJsonObject& obj) - : RoomEvent(obj.contains("state_key") ? type : Type::Unknown, - obj) - { } - explicit StateEventBase(Type type) - : RoomEvent(type) - { } + using factory_t = EventFactory; + + using RoomEvent::RoomEvent; ~StateEventBase() override = default; + bool isStateEvent() const override { return true; } virtual bool repeatsState() const; }; using StateEventPtr = event_ptr_tt; using StateEvents = EventsArray; - namespace _impl - { - template <> - StateEventPtr doMakeEvent(const QJsonObject& obj); - } - template struct Prev { template explicit Prev(const QJsonObject& unsignedJson, ContentParamTs&&... contentParams) - : senderId(unsignedJson.value("prev_sender").toString()) - , content(unsignedJson.value("prev_content").toObject(), + : senderId(unsignedJson.value("prev_sender"_ls).toString()) + , content(unsignedJson.value(PrevContentKeyL).toObject(), std::forward(contentParams)...) { } @@ -258,31 +405,33 @@ namespace QMatrixClient using content_type = ContentT; template - explicit StateEvent(Type type, const QJsonObject& obj, + explicit StateEvent(Type type, const QJsonObject& fullJson, ContentParamTs&&... contentParams) - : StateEventBase(type, obj) + : StateEventBase(type, fullJson) , _content(contentJson(), std::forward(contentParams)...) { - auto unsignedData = obj.value("unsigned").toObject(); - if (unsignedData.contains("prev_content")) + const auto& unsignedData = unsignedJson(); + if (unsignedData.contains(PrevContentKeyL)) _prev = std::make_unique>(unsignedData, - std::forward(contentParams)...); + std::forward(contentParams)...); } template - explicit StateEvent(Type type, ContentParamTs&&... contentParams) - : StateEventBase(type) + explicit StateEvent(Type type, event_mtype_t matrixType, + ContentParamTs&&... contentParams) + : StateEventBase(type, matrixType) , _content(std::forward(contentParams)...) - { } - - QJsonObject toJson() const override { return _content.toJson(); } + { + editJson().insert(ContentKey, _content.toJson()); + } const ContentT& content() const { return _content; } - /** @deprecated Use prevContent instead */ + [[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 prevSenderId() const + { return _prev ? _prev->senderId : QString(); } protected: ContentT _content; diff --git a/lib/events/eventcontent.cpp b/lib/events/eventcontent.cpp index f5974b46..a6b1c763 100644 --- a/lib/events/eventcontent.cpp +++ b/lib/events/eventcontent.cpp @@ -17,8 +17,8 @@ */ #include "eventcontent.h" +#include "util.h" -#include #include using namespace QMatrixClient::EventContent; @@ -39,9 +39,9 @@ FileInfo::FileInfo(const QUrl& u, int payloadSize, const QMimeType& mimeType, FileInfo::FileInfo(const QUrl& u, const QJsonObject& infoJson, const QString& originalFilename) : originalInfoJson(infoJson) - , mimeType(QMimeDatabase().mimeTypeForName(infoJson["mimetype"].toString())) + , mimeType(QMimeDatabase().mimeTypeForName(infoJson["mimetype"_ls].toString())) , url(u) - , payloadSize(infoJson["size"].toInt()) + , payloadSize(infoJson["size"_ls].toInt()) , originalName(originalFilename) { if (!mimeType.isValid()) @@ -51,8 +51,8 @@ FileInfo::FileInfo(const QUrl& u, const QJsonObject& infoJson, void FileInfo::fillInfoJson(QJsonObject* infoJson) const { Q_ASSERT(infoJson); - infoJson->insert("size", payloadSize); - infoJson->insert("mimetype", mimeType.name()); + infoJson->insert(QStringLiteral("size"), payloadSize); + infoJson->insert(QStringLiteral("mimetype"), mimeType.name()); } ImageInfo::ImageInfo(const QUrl& u, int fileSize, QMimeType mimeType, @@ -63,23 +63,24 @@ ImageInfo::ImageInfo(const QUrl& u, int fileSize, QMimeType mimeType, ImageInfo::ImageInfo(const QUrl& u, const QJsonObject& infoJson, const QString& originalFilename) : FileInfo(u, infoJson, originalFilename) - , imageSize(infoJson["w"].toInt(), infoJson["h"].toInt()) + , imageSize(infoJson["w"_ls].toInt(), infoJson["h"_ls].toInt()) { } void ImageInfo::fillInfoJson(QJsonObject* infoJson) const { FileInfo::fillInfoJson(infoJson); - infoJson->insert("w", imageSize.width()); - infoJson->insert("h", imageSize.height()); + infoJson->insert(QStringLiteral("w"), imageSize.width()); + infoJson->insert(QStringLiteral("h"), imageSize.height()); } Thumbnail::Thumbnail(const QJsonObject& infoJson) - : ImageInfo(infoJson["thumbnail_url"].toString(), - infoJson["thumbnail_info"].toObject()) + : ImageInfo(infoJson["thumbnail_url"_ls].toString(), + infoJson["thumbnail_info"_ls].toObject()) { } void Thumbnail::fillInfoJson(QJsonObject* infoJson) const { - infoJson->insert("thumbnail_url", url.toString()); - infoJson->insert("thumbnail_info", toInfoJson(*this)); + infoJson->insert(QStringLiteral("thumbnail_url"), url.toString()); + infoJson->insert(QStringLiteral("thumbnail_info"), + toInfoJson(*this)); } diff --git a/lib/events/eventcontent.h b/lib/events/eventcontent.h index 9d44aec0..91d7a8c8 100644 --- a/lib/events/eventcontent.h +++ b/lib/events/eventcontent.h @@ -21,14 +21,11 @@ // This file contains generic event content definitions, applicable to room // message events as well as other events (e.g., avatars). -#include "converters.h" - +#include #include #include #include -#include - namespace QMatrixClient { namespace EventContent @@ -58,37 +55,6 @@ namespace QMatrixClient virtual void fillJson(QJsonObject* o) const = 0; }; - template - class SimpleContent: public Base - { - public: - using value_type = T; - - // The constructor is templated to enable perfect forwarding - template - SimpleContent(QString keyName, TT&& value) - : value(std::forward(value)), key(std::move(keyName)) - { } - SimpleContent(const QJsonObject& json, QString keyName) - : Base(json) - , value(QMatrixClient::fromJson(json[keyName])) - , key(std::move(keyName)) - { } - - public: - T value; - - protected: - QString key; - - private: - void fillJson(QJsonObject* json) const override - { - Q_ASSERT(json); - json->insert(key, QMatrixClient::toJson(value)); - } - }; - // The below structures fairly follow CS spec 11.2.1.6. The overall // set of attributes for each content types is a superset of the spec // but specific aggregation structure is altered. See doc comments to diff --git a/lib/events/receiptevent.cpp b/lib/events/receiptevent.cpp index a12f4c05..3451a40e 100644 --- a/lib/events/receiptevent.cpp +++ b/lib/events/receiptevent.cpp @@ -35,17 +35,14 @@ Example of a Receipt Event: #include "receiptevent.h" -#include "converters.h" #include "logging.h" using namespace QMatrixClient; ReceiptEvent::ReceiptEvent(const QJsonObject& obj) - : Event(Type::Receipt, obj) + : Event(typeId(), obj) { - Q_ASSERT(obj["type"].toString() == typeId()); - - const QJsonObject contents = contentJson(); + const auto& contents = contentJson(); _eventsWithReceipts.reserve(contents.size()); for( auto eventIt = contents.begin(); eventIt != contents.end(); ++eventIt ) { @@ -55,14 +52,15 @@ ReceiptEvent::ReceiptEvent(const QJsonObject& obj) qCDebug(EPHEMERAL) << "ReceiptEvent content follows:\n" << contents; continue; } - const QJsonObject reads = eventIt.value().toObject().value("m.read").toObject(); + const QJsonObject reads = eventIt.value().toObject() + .value("m.read"_ls).toObject(); QVector receipts; receipts.reserve(reads.size()); for( auto userIt = reads.begin(); userIt != reads.end(); ++userIt ) { const QJsonObject user = userIt.value().toObject(); receipts.push_back({userIt.key(), - QMatrixClient::fromJson(user["ts"])}); + fromJson(user["ts"_ls])}); } _eventsWithReceipts.push_back({eventIt.key(), std::move(receipts)}); } diff --git a/lib/events/receiptevent.h b/lib/events/receiptevent.h index e8d3a65f..10b3f631 100644 --- a/lib/events/receiptevent.h +++ b/lib/events/receiptevent.h @@ -39,14 +39,14 @@ namespace QMatrixClient class ReceiptEvent: public Event { public: + DEFINE_EVENT_TYPEID("m.receipt", ReceiptEvent) explicit ReceiptEvent(const QJsonObject& obj); - EventsWithReceipts eventsWithReceipts() const + const EventsWithReceipts& eventsWithReceipts() const { return _eventsWithReceipts; } - static constexpr const char* typeId() { return "m.receipt"; } - private: EventsWithReceipts _eventsWithReceipts; }; + DEFINE_EVENTTYPE_ALIAS(Receipt, ReceiptEvent) } // namespace QMatrixClient diff --git a/lib/events/redactionevent.h b/lib/events/redactionevent.h index dad54788..8c6cbeff 100644 --- a/lib/events/redactionevent.h +++ b/lib/events/redactionevent.h @@ -25,19 +25,16 @@ namespace QMatrixClient class RedactionEvent : public RoomEvent { public: - static constexpr const char* typeId() { return "m.room.redaction"; } + DEFINE_EVENT_TYPEID("m.room.redaction", RedactionEvent) explicit RedactionEvent(const QJsonObject& obj) - : RoomEvent(Type::Redaction, obj) - , _redactedEvent(obj.value("redacts").toString()) - , _reason(contentJson().value("reason").toString()) + : RoomEvent(typeId(), obj) { } - const QString& redactedEvent() const { return _redactedEvent; } - const QString& reason() const { return _reason; } - - private: - QString _redactedEvent; - QString _reason; + QString redactedEvent() const + { return fullJson()["redacts"_ls].toString(); } + QString reason() const + { return contentJson()["reason"_ls].toString(); } }; + DEFINE_EVENTTYPE_ALIAS(Redaction, RedactionEvent) } // namespace QMatrixClient diff --git a/lib/events/roomavatarevent.h b/lib/events/roomavatarevent.h index 0e44ad7c..fe11807c 100644 --- a/lib/events/roomavatarevent.h +++ b/lib/events/roomavatarevent.h @@ -20,8 +20,6 @@ #include "event.h" -#include - #include "eventcontent.h" namespace QMatrixClient @@ -33,11 +31,11 @@ namespace QMatrixClient // without a thumbnail. But The Spec says there be thumbnails, and // we follow The Spec. public: + DEFINE_EVENT_TYPEID("m.room.avatar", RoomAvatarEvent) explicit RoomAvatarEvent(const QJsonObject& obj) - : StateEvent(Type::RoomAvatar, obj) + : StateEvent(typeId(), obj) { } - - static constexpr const char* typeId() { return "m.room.avatar"; } + QUrl url() const { return content().url; } }; - + DEFINE_EVENTTYPE_ALIAS(RoomAvatar, RoomAvatarEvent) } // namespace QMatrixClient diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp index 76b003c2..3acce7cb 100644 --- a/lib/events/roommemberevent.cpp +++ b/lib/events/roommemberevent.cpp @@ -50,10 +50,10 @@ namespace QMatrixClient } MemberEventContent::MemberEventContent(const QJsonObject& json) - : membership(fromJson(json["membership"])) - , isDirect(json["is_direct"].toBool()) - , displayName(json["displayname"].toString()) - , avatarUrl(json["avatar_url"].toString()) + : membership(fromJson(json["membership"_ls])) + , isDirect(json["is_direct"_ls].toBool()) + , displayName(json["displayname"_ls].toString()) + , avatarUrl(json["avatar_url"_ls].toString()) { } void MemberEventContent::fillJson(QJsonObject* o) const @@ -62,8 +62,8 @@ void MemberEventContent::fillJson(QJsonObject* o) const Q_ASSERT_X(membership != MembershipType::Undefined, __FUNCTION__, "The key 'membership' must be explicit in MemberEventContent"); if (membership != MembershipType::Undefined) - o->insert("membership", membershipStrings[membership]); - o->insert("displayname", displayName); + o->insert(QStringLiteral("membership"), membershipStrings[membership]); + o->insert(QStringLiteral("displayname"), displayName); if (avatarUrl.isValid()) - o->insert("avatar_url", avatarUrl.toString()); + o->insert(QStringLiteral("avatar_url"), avatarUrl.toString()); } diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h index 8e0cc0a4..943d5ac6 100644 --- a/lib/events/roommemberevent.h +++ b/lib/events/roommemberevent.h @@ -22,8 +22,6 @@ #include "eventcontent.h" -#include - namespace QMatrixClient { class MemberEventContent: public EventContent::Base @@ -36,6 +34,9 @@ namespace QMatrixClient : membership(mt) { } explicit MemberEventContent(const QJsonObject& json); + explicit MemberEventContent(const QJsonValue& jv) + : MemberEventContent(jv.toObject()) + { } MembershipType membership; bool isDirect = false; @@ -52,23 +53,26 @@ namespace QMatrixClient { Q_GADGET public: - static constexpr const char* typeId() { return "m.room.member"; } + DEFINE_EVENT_TYPEID("m.room.member", RoomMemberEvent) using MembershipType = MemberEventContent::MembershipType; - explicit RoomMemberEvent(Type type, const QJsonObject& obj) - : StateEvent(type, obj) + explicit RoomMemberEvent(const QJsonObject& obj) + : StateEvent(typeId(), obj) { } RoomMemberEvent(MemberEventContent&& c) - : StateEvent(Type::RoomMember, c) + : StateEvent(typeId(), matrixTypeId(), c.toJson()) { } - explicit RoomMemberEvent(const QJsonObject& obj) - : RoomMemberEvent(Type::RoomMember, obj) + + // This is a special constructor enabling RoomMemberEvent to be + // a base class for more specific member events. + RoomMemberEvent(Type type, const QJsonObject& fullJson) + : StateEvent(type, fullJson) { } MembershipType membership() const { return content().membership; } QString userId() const - { return originalJsonObject().value("state_key").toString(); } + { return fullJson()["state_key"_ls].toString(); } bool isDirect() const { return content().isDirect; } QString displayName() const { return content().displayName; } QUrl avatarUrl() const { return content().avatarUrl; } @@ -76,4 +80,5 @@ namespace QMatrixClient private: REGISTER_ENUM(MembershipType) }; + DEFINE_EVENTTYPE_ALIAS(RoomMember, RoomMemberEvent) } // namespace QMatrixClient diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp index 1a4e74bf..e07054a4 100644 --- a/lib/events/roommessageevent.cpp +++ b/lib/events/roommessageevent.cpp @@ -35,7 +35,7 @@ TypedBase* make(const QJsonObject& json) struct MsgTypeDesc { - QString jsonType; + QString matrixType; MsgType enumType; TypedBase* (*maker)(const QJsonObject&); }; @@ -56,39 +56,56 @@ 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 it->matrixType; return {}; } -MsgType jsonToMsgType(const QString& jsonType) +MsgType jsonToMsgType(const QString& matrixType) { auto it = std::find_if(msgTypes.begin(), msgTypes.end(), - [=](const MsgTypeDesc& mtd) { return mtd.jsonType == jsonType; }); + [=](const MsgTypeDesc& mtd) { return mtd.matrixType == matrixType; }); if (it != msgTypes.end()) return it->enumType; return MsgType::Unknown; } +inline QJsonObject toMsgJson(const QString& plainBody, const QString& jsonMsgType, + TypedBase* content) +{ + auto json = content ? content->toJson() : QJsonObject(); + json.insert(QStringLiteral("msgtype"), jsonMsgType); + json.insert(QStringLiteral("body"), plainBody); + return json; +} + +static const auto MsgTypeKey = "msgtype"_ls; +static const auto BodyKey = "body"_ls; + +RoomMessageEvent::RoomMessageEvent(const QString& plainBody, + const QString& jsonMsgType, TypedBase* content) + : RoomEvent(typeId(), matrixTypeId(), + toMsgJson(plainBody, jsonMsgType, content)) + , _content(content) +{ } + 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) + : RoomEvent(typeId(), obj), _content(nullptr) { if (isRedacted()) return; const QJsonObject content = contentJson(); - if ( content.contains("msgtype") && content.contains("body") ) + if ( content.contains(MsgTypeKey) && content.contains(BodyKey) ) { - _plainBody = content["body"].toString(); - - _msgtype = content["msgtype"].toString(); + auto msgtype = content[MsgTypeKey].toString(); for (const auto& mt: msgTypes) - if (mt.jsonType == _msgtype) + if (mt.matrixType == msgtype) _content.reset(mt.maker(content)); if (!_content) @@ -107,13 +124,25 @@ RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) RoomMessageEvent::MsgType RoomMessageEvent::msgtype() const { - return jsonToMsgType(_msgtype); + return jsonToMsgType(rawMsgtype()); +} + +QString RoomMessageEvent::rawMsgtype() const +{ + return contentJson()[MsgTypeKey].toString(); +} + +QString RoomMessageEvent::plainBody() const +{ + return contentJson()[BodyKey].toString(); } QMimeType RoomMessageEvent::mimeType() const { - return _content ? _content->type() : - QMimeDatabase().mimeTypeForName("text/plain"); + static const auto PlainTextMimeType = + QMimeDatabase().mimeTypeForName("text/plain"); + return _content ? _content->type() : PlainTextMimeType; + ; } bool RoomMessageEvent::hasTextContent() const @@ -133,14 +162,6 @@ 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) { } @@ -148,26 +169,29 @@ TextContent::TextContent(const QString& text, const QString& contentType) TextContent::TextContent(const QJsonObject& json) { QMimeDatabase db; + static const auto PlainTextMimeType = db.mimeTypeForName("text/plain"); + static const auto HtmlMimeType = db.mimeTypeForName("text/html"); // Special-casing the custom matrix.org's (actually, Riot's) way // of sending HTML messages. - if (json["format"].toString() == "org.matrix.custom.html") + if (json["format"_ls].toString() == "org.matrix.custom.html") { - mimeType = db.mimeTypeForName("text/html"); - body = json["formatted_body"].toString(); + mimeType = HtmlMimeType; + body = json["formatted_body"_ls].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(); + mimeType = PlainTextMimeType; + body = json[BodyKey].toString(); } } void TextContent::fillJson(QJsonObject* json) const { Q_ASSERT(json); - json->insert("format", QStringLiteral("org.matrix.custom.html")); - json->insert("formatted_body", body); + json->insert(QStringLiteral("format"), + QStringLiteral("org.matrix.custom.html")); + json->insert(QStringLiteral("formatted_body"), body); } LocationContent::LocationContent(const QString& geoUri, const ImageInfo& thumbnail) @@ -176,8 +200,8 @@ LocationContent::LocationContent(const QString& geoUri, const ImageInfo& thumbna LocationContent::LocationContent(const QJsonObject& json) : TypedBase(json) - , geoUri(json["geo_uri"].toString()) - , thumbnail(json["info"].toObject()) + , geoUri(json["geo_uri"_ls].toString()) + , thumbnail(json["info"_ls].toObject()) { } QMimeType LocationContent::type() const @@ -188,6 +212,6 @@ QMimeType LocationContent::type() const void LocationContent::fillJson(QJsonObject* o) const { Q_ASSERT(o); - o->insert("geo_uri", geoUri); - o->insert("info", toInfoJson(thumbnail)); + o->insert(QStringLiteral("geo_uri"), geoUri); + o->insert(QStringLiteral("info"), toInfoJson(thumbnail)); } diff --git a/lib/events/roommessageevent.h b/lib/events/roommessageevent.h index 075d7188..3f3832d4 100644 --- a/lib/events/roommessageevent.h +++ b/lib/events/roommessageevent.h @@ -37,6 +37,8 @@ namespace QMatrixClient Q_PROPERTY(QMimeType mimeType READ mimeType STORED false CONSTANT) Q_PROPERTY(EventContent::TypedBase* content READ content CONSTANT) public: + DEFINE_EVENT_TYPEID("m.room.message", RoomMessageEvent) + enum class MsgType { Text, Emote, Notice, Image, File, Location, Video, Audio, Unknown @@ -44,18 +46,15 @@ namespace QMatrixClient RoomMessageEvent(const QString& plainBody, const QString& jsonMsgType, - EventContent::TypedBase* content = nullptr) - : RoomEvent(Type::RoomMessage) - , _msgtype(jsonMsgType), _plainBody(plainBody), _content(content) - { } + EventContent::TypedBase* content = nullptr); explicit RoomMessageEvent(const QString& plainBody, MsgType msgType = MsgType::Text, EventContent::TypedBase* content = nullptr); explicit RoomMessageEvent(const QJsonObject& obj); MsgType msgtype() const; - QString rawMsgtype() const { return _msgtype; } - const QString& plainBody() const { return _plainBody; } + QString rawMsgtype() const; + QString plainBody() const; EventContent::TypedBase* content() const { return _content.data(); } QMimeType mimeType() const; @@ -63,17 +62,12 @@ namespace QMatrixClient bool hasFileContent() const; bool hasThumbnail() const; - QJsonObject toJson() const override; - - static constexpr const char* typeId() { return "m.room.message"; } - private: - QString _msgtype; - QString _plainBody; QScopedPointer _content; REGISTER_ENUM(MsgType) }; + DEFINE_EVENTTYPE_ALIAS(RoomMessage, RoomMessageEvent) using MessageEventType = RoomMessageEvent::MsgType; namespace EventContent @@ -140,16 +134,16 @@ namespace QMatrixClient public: PlayableContent(const QJsonObject& json) : ContentT(json) - , duration(ContentT::originalInfoJson["duration"].toInt()) + , duration(ContentT::originalInfoJson["duration"_ls].toInt()) { } protected: void fillJson(QJsonObject* json) const override { ContentT::fillJson(json); - auto infoJson = json->take("info").toObject(); - infoJson.insert("duration", duration); - json->insert("info", infoJson); + auto infoJson = json->take("info"_ls).toObject(); + infoJson.insert(QStringLiteral("duration"), duration); + json->insert(QStringLiteral("info"), infoJson); } public: diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h index d9f403e8..a117efb1 100644 --- a/lib/events/simplestateevents.h +++ b/lib/events/simplestateevents.h @@ -23,31 +23,69 @@ namespace QMatrixClient { -#define DEFINE_SIMPLE_STATE_EVENT(_Name, _TypeId, _EnumType, _ContentType, _ContentKey) \ - class _Name \ - : public StateEvent> \ + namespace EventContent + { + template + class SimpleContent: public Base + { + public: + using value_type = T; + + // The constructor is templated to enable perfect forwarding + template + SimpleContent(QString keyName, TT&& value) + : value(std::forward(value)), key(std::move(keyName)) + { } + SimpleContent(const QJsonObject& json, QString keyName) + : Base(json) + , value(QMatrixClient::fromJson(json[keyName])) + , key(std::move(keyName)) + { } + + public: + T value; + + protected: + QString key; + + private: + void fillJson(QJsonObject* json) const override + { + Q_ASSERT(json); + json->insert(key, QMatrixClient::toJson(value)); + } + }; + } // namespace EventContent + +#define DEFINE_SIMPLE_STATE_EVENT(_Name, _TypeId, _ContentType, _ContentKey) \ + class _Name : public StateEvent> \ { \ public: \ - static constexpr const char* typeId() { return _TypeId; } \ + using content_type = _ContentType; \ + DEFINE_EVENT_TYPEID(_TypeId, _Name) \ explicit _Name(const QJsonObject& obj) \ - : StateEvent(_EnumType, obj, QStringLiteral(#_ContentKey)) \ + : StateEvent(typeId(), obj, QStringLiteral(#_ContentKey)) \ { } \ template \ explicit _Name(T&& value) \ - : StateEvent(_EnumType, QStringLiteral(#_ContentKey), \ + : StateEvent(typeId(), matrixTypeId(), \ + QStringLiteral(#_ContentKey), \ std::forward(value)) \ { } \ - const _ContentType& _ContentKey() const { return content().value; } \ - }; + auto _ContentKey() const { return content().value; } \ + }; // End of macro - DEFINE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", - Event::Type::RoomName, QString, name) + DEFINE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", QString, name) + DEFINE_EVENTTYPE_ALIAS(RoomName, RoomNameEvent) DEFINE_SIMPLE_STATE_EVENT(RoomAliasesEvent, "m.room.aliases", - Event::Type::RoomAliases, QStringList, aliases) + QStringList, aliases) + DEFINE_EVENTTYPE_ALIAS(RoomAliases, RoomAliasesEvent) DEFINE_SIMPLE_STATE_EVENT(RoomCanonicalAliasEvent, "m.room.canonical_alias", - Event::Type::RoomCanonicalAlias, QString, alias) - DEFINE_SIMPLE_STATE_EVENT(RoomTopicEvent, "m.room.topic", - Event::Type::RoomTopic, QString, topic) + QString, alias) + DEFINE_EVENTTYPE_ALIAS(RoomCanonicalAlias, RoomCanonicalAliasEvent) + DEFINE_SIMPLE_STATE_EVENT(RoomTopicEvent, "m.room.topic", QString, topic) + DEFINE_EVENTTYPE_ALIAS(RoomTopic, RoomTopicEvent) DEFINE_SIMPLE_STATE_EVENT(EncryptionEvent, "m.room.encryption", - Event::Type::RoomEncryption, QString, algorithm) + QString, algorithm) + DEFINE_EVENTTYPE_ALIAS(RoomEncryption, EncryptionEvent) } // namespace QMatrixClient diff --git a/lib/events/typingevent.cpp b/lib/events/typingevent.cpp index a4d3bae4..c7b69e33 100644 --- a/lib/events/typingevent.cpp +++ b/lib/events/typingevent.cpp @@ -21,12 +21,10 @@ using namespace QMatrixClient; TypingEvent::TypingEvent(const QJsonObject& obj) - : Event(Type::Typing, obj) + : Event(typeId(), obj) { - QJsonValue result; - result= contentJson()["user_ids"]; - QJsonArray array = result.toArray(); - for( const QJsonValue& user: array ) + const auto& array = contentJson()["user_ids"_ls].toArray(); + for(const auto& user: array ) _users.push_back(user.toString()); } diff --git a/lib/events/typingevent.h b/lib/events/typingevent.h index 6ccbc1c8..0c4b350d 100644 --- a/lib/events/typingevent.h +++ b/lib/events/typingevent.h @@ -20,20 +20,19 @@ #include "event.h" -#include - namespace QMatrixClient { class TypingEvent: public Event { public: - static constexpr const char* typeId() { return "m.typing"; } + DEFINE_EVENT_TYPEID("m.typing", TypingEvent) TypingEvent(const QJsonObject& obj); - QStringList users() const { return _users; } + const QStringList& users() const { return _users; } private: QStringList _users; }; + DEFINE_EVENTTYPE_ALIAS(Typing, TypingEvent) } // namespace QMatrixClient diff --git a/lib/jobs/sendeventjob.h b/lib/jobs/sendeventjob.h index a3e9a291..af81ae26 100644 --- a/lib/jobs/sendeventjob.h +++ b/lib/jobs/sendeventjob.h @@ -32,9 +32,9 @@ namespace QMatrixClient SendEventJob(const QString& roomId, const EvT& event) : BaseJob(HttpVerb::Put, QStringLiteral("SendEventJob"), QStringLiteral("_matrix/client/r0/rooms/%1/send/%2/") - .arg(roomId, EvT::typeId()), // See also beforeStart() + .arg(roomId, EvT::matrixTypeId()), // See also beforeStart() Query(), - Data(event.toJson())) + Data(event.contentJson())) { } /** diff --git a/lib/room.cpp b/lib/room.cpp index 8e1eb8e8..9f4b5a0e 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -110,7 +110,7 @@ class Room::Private QHash lastReadEventIds; QString serverReadMarker; TagsMap tags; - QHash accountData; + std::unordered_map accountData; QString prevBatch; QPointer eventsHistoryJob; @@ -168,7 +168,7 @@ class Room::Private { return !ti->isRedacted() && ti->senderId() != connection->userId() && - ti->type() == EventType::RoomMessage; + ti->is(); } void addNewMessageEvents(RoomEvents&& events); @@ -203,14 +203,14 @@ class Room::Private auto requestSetState(const QString& stateKey, const EvT& event) { return connection->callApi( - id, EvT::typeId(), stateKey, event.toJson()); + id, EvT::matrixTypeId(), stateKey, event.contentJson()); } template auto requestSetState(const EvT& event) { return connection->callApi( - id, EvT::typeId(), event.toJson()); + id, EvT::matrixTypeId(), event.contentJson()); } /** @@ -224,8 +224,8 @@ class Room::Private void broadcastTagUpdates() { connection->callApi( - connection->userId(), id, TagEvent::typeId(), - TagEvent(tags).toJson()); + connection->userId(), id, TagEvent::matrixTypeId(), + TagEvent(tags).fullJson()); emit q->tagsChanged(); } @@ -650,12 +650,14 @@ void Room::resetHighlightCount() bool Room::hasAccountData(const QString& type) const { - return d->accountData.contains(type); + return d->accountData.find(type) != d->accountData.end(); } -Room::AccountDataMap Room::accountData(const QString& type) const +const EventPtr& Room::accountData(const QString& type) const { - return d->accountData.value(type); + static EventPtr NoEventPtr {}; + const auto it = d->accountData.find(type); + return it != d->accountData.end() ? it->second : NoEventPtr; } QStringList Room::tagNames() const @@ -723,8 +725,7 @@ const RoomMessageEvent* Room::Private::getEventWithFile(const QString& eventId) const { auto evtIt = q->findInTimeline(eventId); - if (evtIt != timeline.rend() && - evtIt->event()->type() == EventType::RoomMessage) + if (evtIt != timeline.rend() && evtIt->event()->is()) { auto* event = evtIt->viewAs(); if (event->hasFileContent()) @@ -1274,7 +1275,7 @@ void Room::Private::dropDuplicateEvents(RoomEvents& events) const inline bool isRedaction(const RoomEventPtr& e) { - return e->type() == EventType::Redaction; + return e && e->is(); } void Room::Private::processRedaction(event_ptr_tt&& redaction) @@ -1292,26 +1293,30 @@ void Room::Private::processRedaction(event_ptr_tt&& redaction) // Apply the redaction procedure from chapter 6.5 of The Spec auto originalJson = ti->originalJsonObject(); - if (originalJson.value("unsigned").toObject() - .value("redacted_because").toObject() - .value("event_id") == redaction->id()) + if (originalJson.value(UnsignedKeyL).toObject() + .value(RedactedCauseKeyL).toObject() + .value(EventIdKeyL) == redaction->id()) { qCDebug(MAIN) << "Redaction" << redaction->id() << "of event" << ti.event()->id() << "already done, skipping"; return; } static const QStringList keepKeys = - { "event_id", "type", "room_id", "sender", "state_key", - "prev_content", "content", "origin_server_ts" }; - static const - std::vector> keepContentKeysMap - { { Event::Type::RoomMember, { "membership" } } - , { Event::Type::RoomCreate, { "creator" } } - , { Event::Type::RoomJoinRules, { "join_rule" } } - , { Event::Type::RoomPowerLevels, - { "ban", "events", "events_default", "kick", "redact", - "state_default", "users", "users_default" } } - , { Event::Type::RoomAliases, { "alias" } } + { EventIdKey, TypeKey, QStringLiteral("room_id"), + QStringLiteral("sender"), QStringLiteral("state_key"), + QStringLiteral("prev_content"), ContentKey, + QStringLiteral("origin_server_ts") }; + + std::vector> keepContentKeysMap + { { RoomMemberEvent::typeId(), { QStringLiteral("membership") } } +// , { RoomCreateEvent::typeId(), { QStringLiteral("creator") } } +// , { RoomJoinRules::typeId(), { QStringLiteral("join_rule") } } +// , { RoomPowerLevels::typeId(), +// { QStringLiteral("ban"), QStringLiteral("events"), +// QStringLiteral("events_default"), QStringLiteral("kick"), +// QStringLiteral("redact"), QStringLiteral("state_default"), +// QStringLiteral("users"), QStringLiteral("users_default") } } + , { RoomAliasesEvent::typeId(), { QStringLiteral("alias") } } }; for (auto it = originalJson.begin(); it != originalJson.end();) { @@ -1325,10 +1330,10 @@ void Room::Private::processRedaction(event_ptr_tt&& redaction) [&ti](const auto& t) { return ti->type() == t.first; } ); if (keepContentKeys == keepContentKeysMap.end()) { - originalJson.remove("content"); - originalJson.remove("prev_content"); + originalJson.remove(ContentKeyL); + originalJson.remove(PrevContentKeyL); } else { - auto content = originalJson.take("content").toObject(); + auto content = originalJson.take(ContentKeyL).toObject(); for (auto it = content.begin(); it != content.end(); ) { if (!keepContentKeys->second.contains(it.key())) @@ -1336,16 +1341,15 @@ void Room::Private::processRedaction(event_ptr_tt&& redaction) else ++it; } - originalJson.insert("content", content); + originalJson.insert(ContentKey, content); } - auto unsignedData = originalJson.take("unsigned").toObject(); - unsignedData["redacted_because"] = redaction->originalJsonObject(); - originalJson.insert("unsigned", unsignedData); + auto unsignedData = originalJson.take(UnsignedKeyL).toObject(); + unsignedData[RedactedCauseKeyL] = redaction->originalJsonObject(); + originalJson.insert(QStringLiteral("unsigned"), unsignedData); // Make a new event from the redacted JSON, exchange events, // notify everyone and delete the old event - RoomEventPtr oldEvent - { ti.replaceEvent(makeEvent(originalJson)) }; + auto oldEvent = ti.replaceEvent(loadEvent(originalJson)); q->onRedaction(*oldEvent, *ti.event()); qCDebug(MAIN) << "Redacted" << oldEvent->id() << "with" << redaction->id(); emit q->replacedEvent(ti.event(), rawPtr(oldEvent)); @@ -1442,52 +1446,48 @@ void Room::Private::addHistoricalMessageEvents(RoomEvents&& events) bool Room::processStateEvent(const RoomEvent& e) { - switch (e.type()) - { - case EventType::RoomName: { - d->name = static_cast(e).name(); + return visit(e + , [this] (const RoomNameEvent& evt) { + d->name = evt.name(); qCDebug(MAIN) << "Room name updated:" << d->name; return true; } - case EventType::RoomAliases: { - d->aliases = static_cast(e).aliases(); + , [this] (const RoomAliasesEvent& evt) { + d->aliases = evt.aliases(); qCDebug(MAIN) << "Room aliases updated:" << d->aliases; return true; } - case EventType::RoomCanonicalAlias: { - d->canonicalAlias = - static_cast(e).alias(); + , [this] (const RoomCanonicalAliasEvent& evt) { + d->canonicalAlias = evt.alias(); setObjectName(d->canonicalAlias); - qCDebug(MAIN) << "Room canonical alias updated:" << d->canonicalAlias; + qCDebug(MAIN) << "Room canonical alias updated:" + << d->canonicalAlias; return true; } - case EventType::RoomTopic: { - d->topic = static_cast(e).topic(); + , [this] (const RoomTopicEvent& evt) { + d->topic = evt.topic(); qCDebug(MAIN) << "Room topic updated:" << d->topic; emit topicChanged(); return false; } - case EventType::RoomAvatar: { - const auto& avatarEventContent = - static_cast(e).content(); - if (d->avatar.updateUrl(avatarEventContent.url)) + , [this] (const RoomAvatarEvent& evt) { + if (d->avatar.updateUrl(evt.url())) { qCDebug(MAIN) << "Room avatar URL updated:" - << avatarEventContent.url.toString(); + << evt.url().toString(); emit avatarChanged(); } return false; } - case EventType::RoomMember: { - const auto& memberEvent = static_cast(e); - auto* u = user(memberEvent.userId()); - u->processEvent(memberEvent, this); + , [this] (const RoomMemberEvent& evt) { + auto* u = user(evt.userId()); + u->processEvent(evt, this); if (u == localUser() && memberJoinState(u) == JoinState::Invite - && memberEvent.isDirect()) + && evt.isDirect()) connection()->addToDirectChats(this, - user(memberEvent.senderId())); + user(evt.senderId())); - if( memberEvent.membership() == MembershipType::Join ) + if( evt.membership() == MembershipType::Join ) { if (memberJoinState(u) != JoinState::Join) { @@ -1505,7 +1505,7 @@ bool Room::processStateEvent(const RoomEvent& e) emit userAdded(u); } } - else if( memberEvent.membership() == MembershipType::Leave ) + else if( evt.membership() == MembershipType::Leave ) { if (memberJoinState(u) == JoinState::Join) { @@ -1517,52 +1517,43 @@ bool Room::processStateEvent(const RoomEvent& e) } return false; } - case EventType::RoomEncryption: - { - d->encryptionAlgorithm = - static_cast(e).algorithm(); - qCDebug(MAIN) << "Encryption switched on in" << displayName(); + , [this] (const EncryptionEvent& evt) { + d->encryptionAlgorithm = evt.algorithm(); + qCDebug(MAIN) << "Encryption switched on in room" << id() + << "with algorithm" << d->encryptionAlgorithm; emit encryption(); return false; } - default: - /* Ignore events of other types */ - return false; - } + ); } void Room::processEphemeralEvent(EventPtr&& event) { QElapsedTimer et; et.start(); - switch (event->type()) - { - case EventType::Typing: { - auto typingEvent = ptrCast(move(event)); + visit(event + , [this,et] (const TypingEvent& evt) { d->usersTyping.clear(); - for( const QString& userId: typingEvent->users() ) + for( const QString& userId: qAsConst(evt.users()) ) { auto u = user(userId); if (memberJoinState(u) == JoinState::Join) d->usersTyping.append(u); } - if (!typingEvent->users().isEmpty()) + if (!evt.users().isEmpty()) qCDebug(PROFILER) << "*** Room::processEphemeralEvent(typing):" - << typingEvent->users().size() << "users," << et; + << evt.users().size() << "users," << et; emit typingChanged(); - break; } - case EventType::Receipt: { - auto receiptEvent = ptrCast(move(event)); - for( const auto &p: receiptEvent->eventsWithReceipts() ) + , [this,et] (const ReceiptEvent& evt) { + for( const auto &p: qAsConst(evt.eventsWithReceipts()) ) { { if (p.receipts.size() == 1) qCDebug(EPHEMERAL) << "Marking" << p.evtId - << "as read for" << p.receipts[0].userId; + << "as read for" << p.receipts[0].userId; else qCDebug(EPHEMERAL) << "Marking" << p.evtId - << "as read for" - << p.receipts.size() << "users"; + << "as read for" << p.receipts.size() << "users"; } const auto newMarker = findInTimeline(p.evtId); if (newMarker != timelineEdge()) @@ -1578,7 +1569,7 @@ void Room::processEphemeralEvent(EventPtr&& event) } else { qCDebug(EPHEMERAL) << "Event" << p.evtId - << "not found; saving read receipts anyway"; + << "not found; saving read receipts anyway"; // If the event is not found (most likely, because it's too old // and hasn't been fetched from the server yet), but there is // a previous marker for a user, keep the previous marker. @@ -1594,37 +1585,28 @@ void Room::processEphemeralEvent(EventPtr&& event) } } } - if (!receiptEvent->eventsWithReceipts().isEmpty()) + if (!evt.eventsWithReceipts().isEmpty()) qCDebug(PROFILER) << "*** Room::processEphemeralEvent(receipts):" - << receiptEvent->eventsWithReceipts().size() + << evt.eventsWithReceipts().size() << "events with receipts," << et; - break; } - default: - qCWarning(EPHEMERAL) << "Unexpected event type in 'ephemeral' batch:" - << event->jsonType(); - } + ); } void Room::processAccountDataEvent(EventPtr&& event) { - switch (event->type()) - { - case EventType::Tag: - { - auto newTags = ptrCast(move(event))->tags(); + visit(event + , [this] (const TagEvent& evt) { + auto newTags = evt.tags(); if (newTags == d->tags) - break; + return; d->tags = newTags; qCDebug(MAIN) << "Room" << id() << "is tagged with:" << tagNames().join(", "); emit tagsChanged(); - break; } - case EventType::ReadMarker: - { - auto readEventId = - ptrCast(move(event))->event_id(); + , [this] (const ReadMarkerEvent& evt) { + auto readEventId = evt.event_id(); qCDebug(MAIN) << "Server-side read marker at" << readEventId; d->serverReadMarker = readEventId; const auto newMarker = findInTimeline(readEventId); @@ -1632,12 +1614,18 @@ void Room::processAccountDataEvent(EventPtr&& event) d->markMessagesAsRead(newMarker); else d->setLastReadEvent(localUser(), readEventId); - break; } - default: - d->accountData[event->jsonType()] = - fromJson(event->contentJson()); - emit accountDataChanged(event->jsonType()); + ); + // For all account data events + auto& currentData = d->accountData[event->matrixType()]; + // A polymorphic event-specific comparison might be a bit more + // efficient; maaybe do it another day + if (!currentData || currentData->contentJson() != event->contentJson()) + { + currentData = std::move(event); + qCDebug(MAIN) << "Updated account data of type" + << currentData->matrixType(); + emit accountDataChanged(currentData->matrixType()); } } @@ -1674,8 +1662,8 @@ QString Room::Private::roomNameFromMemberNames(const QList &userlist) co // ii. Two users besides the current one. if (userlist.size() == 3) return tr("%1 and %2") - .arg(q->roomMembername(first_two[0])) - .arg(q->roomMembername(first_two[1])); + .arg(q->roomMembername(first_two[0]), + q->roomMembername(first_two[1])); // iii. More users. if (userlist.size() > 3) @@ -1731,11 +1719,11 @@ void appendStateEvent(QJsonArray& events, const QString& type, const QJsonObject& content, const QString& stateKey = {}) { if (!content.isEmpty() || !stateKey.isEmpty()) - events.append(QJsonObject - { { QStringLiteral("type"), type } - , { QStringLiteral("content"), content } - , { QStringLiteral("state_key"), stateKey } - }); + { + auto json = basicEventJson(type, content); + json.insert(QStringLiteral("state_key"), stateKey); + events.append(json); + } } #define ADD_STATE_EVENT(events, type, name, content) \ @@ -1746,16 +1734,13 @@ void appendEvent(QJsonArray& events, const QString& type, const QJsonObject& content) { if (!content.isEmpty()) - events.append(QJsonObject - { { QStringLiteral("type"), type } - , { QStringLiteral("content"), content } - }); + events.append(basicEventJson(type, content)); } template void appendEvent(QJsonArray& events, const EvtT& event) { - appendEvent(events, EvtT::typeId(), event.toJson()); + appendEvent(events, EvtT::matrixTypeId(), event.toJson()); } QJsonObject Room::Private::toJson() const @@ -1790,29 +1775,23 @@ QJsonObject Room::Private::toJson() const } QJsonArray accountDataEvents; - if (!tags.empty()) - appendEvent(accountDataEvents, TagEvent(tags)); - - if (!serverReadMarker.isEmpty()) - appendEvent(accountDataEvents, ReadMarkerEvent(serverReadMarker)); - if (!accountData.empty()) { - for (auto it = accountData.begin(); it != accountData.end(); ++it) - appendEvent(accountDataEvents, it.key(), - QMatrixClient::toJson(it.value())); + for (const auto& e: accountData) + appendEvent(accountDataEvents, e.first, e.second->contentJson()); } - result.insert("account_data", QJsonObject {{ "events", accountDataEvents }}); + result.insert(QStringLiteral("account_data"), + QJsonObject {{ QStringLiteral("events"), accountDataEvents }}); - QJsonObject unreadNotificationsObj; + QJsonObject unreadNotifObj + { { SyncRoomData::UnreadCountKey, unreadMessages } }; - unreadNotificationsObj.insert(SyncRoomData::UnreadCountKey, unreadMessages); if (highlightCount > 0) - unreadNotificationsObj.insert("highlight_count", highlightCount); + unreadNotifObj.insert(QStringLiteral("highlight_count"), highlightCount); if (notificationCount > 0) - unreadNotificationsObj.insert("notification_count", notificationCount); + unreadNotifObj.insert(QStringLiteral("notification_count"), notificationCount); - result.insert("unread_notifications", unreadNotificationsObj); + result.insert(QStringLiteral("unread_notifications"), unreadNotifObj); if (et.elapsed() > 50) qCDebug(PROFILER) << "Room::toJson() for" << displayname << "took" << et; diff --git a/lib/room.h b/lib/room.h index f2a372e9..21016c38 100644 --- a/lib/room.h +++ b/lib/room.h @@ -129,10 +129,6 @@ namespace QMatrixClient using rev_iter_t = Timeline::const_reverse_iterator; using timeline_iter_t = Timeline::const_iterator; - using AccountDataMap = std::conditional_t< - QT_VERSION >= QT_VERSION_CHECK(5, 5, 0), - QVariantHash, QVariantMap>; - Room(Connection* connection, QString id, JoinState initialJoinState); ~Room() override; @@ -279,7 +275,7 @@ namespace QMatrixClient * stored on the server. Tags and read markers cannot be retrieved * using this method _yet_. */ - AccountDataMap accountData(const QString& type) const; + const EventPtr& accountData(const QString& type) const; QStringList tagNames() const; TagsMap tags() const; diff --git a/lib/user.h b/lib/user.h index 76aa672f..1cf72155 100644 --- a/lib/user.h +++ b/lib/user.h @@ -106,10 +106,18 @@ namespace QMatrixClient void processEvent(const RoomMemberEvent& event, const Room* r); public slots: + /** Set a new name in the global user profile */ void rename(const QString& newName); + /** Set a new name for the user in one room */ void rename(const QString& newName, const Room* r); + /** Upload the file and use it as an avatar */ bool setAvatar(const QString& fileName); + /** Upload contents of the QIODevice and set that as an avatar */ bool setAvatar(QIODevice* source); + /** Create or find a direct chat with this user + * The resulting chat is returned asynchronously via + * Connection::directChatAvailable() + */ void requestDirectChat(); signals: diff --git a/lib/util.h b/lib/util.h index d6e1cef6..28315429 100644 --- a/lib/util.h +++ b/lib/util.h @@ -59,6 +59,42 @@ namespace QMatrixClient return std::unique_ptr(static_cast(p.release())); } + /** Determine traits of an arbitrary function/lambda/functor + * This only works with arity of 1 (1-argument) for now but is extendable + * to other cases. Also, doesn't work with generic lambdas and function + * objects that have operator() overloaded + * \sa https://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda#7943765 + */ + template + struct function_traits : public function_traits + { }; // A generic function object that has (non-overloaded) operator() + + // Specialisation for a function + template + struct function_traits + { + using return_type = ReturnT; + using arg_type = ArgT; + }; + + // Specialisation for a member function + template + struct function_traits + : function_traits + { }; + + // Specialisation for a const member function + template + struct function_traits + : function_traits + { }; + + template + using fn_return_t = typename function_traits::return_type; + + template + using fn_arg_t = typename function_traits::arg_type; + #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) // Copy-pasted from Qt 5.10 template @@ -68,6 +104,11 @@ namespace QMatrixClient static void qAsConst(const T &&) Q_DECL_EQ_DELETE; #endif + inline auto operator"" _ls(const char* s, std::size_t size) + { + return QLatin1String(s, int(size)); + } + /** An abstraction over a pair of iterators * This is a very basic range type over a container with iterators that * are at least ForwardIterators. Inspired by Ranges TS. -- cgit v1.2.3 From bd853f392aaf5b05e0a8023da85a38e91d90a6e0 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 2 Jul 2018 13:19:41 +0900 Subject: TimelineItem::operator*() --- lib/room.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/room.h b/lib/room.h index 21016c38..975e6caf 100644 --- a/lib/room.h +++ b/lib/room.h @@ -48,12 +48,16 @@ namespace QMatrixClient using index_t = int; TimelineItem(RoomEventPtr&& e, index_t number) - : evt(std::move(e)), idx(number) { } + : evt(std::move(e)), idx(number) + { + Q_ASSERT(evt); + } const RoomEvent* event() const { return rawPtr(evt); } template const EventT* viewAs() const { return weakPtrCast(evt); } const RoomEventPtr& operator->() const { return evt; } + const RoomEvent& operator*() const { return *evt; } index_t index() const { return idx; } // Used for event redaction -- cgit v1.2.3 From ed467d27b07781fdd2f7ddef043568954ce50b69 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 2 Jul 2018 13:39:33 +0900 Subject: Events: use a template structure instead of template variables; rearrange code into blocks A template member variable in it seemed to cause internal compiler error in MSVC 2017, let alone MSVC 2015... --- lib/events/accountdataevents.h | 6 +- lib/events/directchatevent.h | 1 + lib/events/event.cpp | 24 ++---- lib/events/event.h | 180 ++++++++++++++++++++++------------------- lib/events/receiptevent.h | 1 + lib/events/redactionevent.h | 1 + lib/events/roomavatarevent.h | 1 + lib/events/roommemberevent.h | 1 + lib/events/roommessageevent.h | 1 + lib/events/simplestateevents.h | 4 +- lib/events/typingevent.h | 1 + lib/room.cpp | 6 +- 12 files changed, 121 insertions(+), 106 deletions(-) (limited to 'lib') diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h index 6d53d2aa..ed4373cd 100644 --- a/lib/events/accountdataevents.h +++ b/lib/events/accountdataevents.h @@ -65,8 +65,10 @@ namespace QMatrixClient toJson(std::move(content)) } }) \ { } \ auto _ContentKey() const \ - { return fromJson(contentJson()[#_ContentKey]); } \ - }; // End of macro + { return fromJson(contentJson()[#_ContentKey##_ls]); } \ + }; \ + REGISTER_EVENT_TYPE(_Name) \ + // End of macro DEFINE_SIMPLE_EVENT(TagEvent, "m.tag", TagsMap, tags) DEFINE_SIMPLE_EVENT(ReadMarkerEvent, "m.fully_read", QString, event_id) diff --git a/lib/events/directchatevent.h b/lib/events/directchatevent.h index 1d366721..7559796b 100644 --- a/lib/events/directchatevent.h +++ b/lib/events/directchatevent.h @@ -33,5 +33,6 @@ namespace QMatrixClient QMultiHash usersToDirectChats() const; }; + REGISTER_EVENT_TYPE(DirectChatEvent) DEFINE_EVENTTYPE_ALIAS(DirectChat, DirectChatEvent) } diff --git a/lib/events/event.cpp b/lib/events/event.cpp index 3f507347..447068af 100644 --- a/lib/events/event.cpp +++ b/lib/events/event.cpp @@ -18,14 +18,6 @@ #include "event.h" -#include "roommessageevent.h" -#include "simplestateevents.h" -#include "roommemberevent.h" -#include "roomavatarevent.h" -#include "typingevent.h" -#include "receiptevent.h" -#include "accountdataevents.h" -#include "directchatevent.h" #include "redactionevent.h" #include "logging.h" @@ -33,12 +25,6 @@ using namespace QMatrixClient; -event_type_t EventTypeRegistry::nextTypeId() -{ - static event_type_t typeIndex = unknownTypeId(); - return ++typeIndex; -} - Event::Event(Type type, const QJsonObject& json) : _type(type), _json(json) { @@ -77,7 +63,7 @@ const QJsonObject Event::unsignedJson() const } [[gnu::unused]] static auto roomEventTypeInitialised = - EventTypeRegistry::chainFactories(); + Event::factory_t::chainFactory(); RoomEvent::RoomEvent(Type type, event_mtype_t matrixType, const QJsonObject& contentJson) @@ -134,10 +120,16 @@ void RoomEvent::addId(const QString& newId) } [[gnu::unused]] static auto stateEventTypeInitialised = - EventTypeRegistry::chainFactories(); + RoomEvent::factory_t::chainFactory(); 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::id; + return ++_id; +} diff --git a/lib/events/event.h b/lib/events/event.h index f8264baf..89ba94ac 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -21,6 +21,8 @@ #include "converters.h" #include "util.h" +#include + namespace QMatrixClient { // === event_ptr_tt<> and type casting facilities === @@ -46,10 +48,7 @@ namespace QMatrixClient return unique_ptr_cast(ptr); } - // === Predefined types and JSON key names - - using event_type_t = uint; - using event_mtype_t = const char*; + // === Standard Matrix key names and basicEventJson() === static const auto TypeKey = QStringLiteral("type"); static const auto ContentKey = QStringLiteral("content"); @@ -61,19 +60,57 @@ namespace QMatrixClient static const auto RedactedCauseKeyL = "redacted_because"_ls; static const auto PrevContentKeyL = "prev_content"_ls; + // Minimal correct Matrix event JSON + template + inline QJsonObject basicEventJson(StrT matrixType, + const QJsonObject& content) + { + return { { TypeKey, std::forward(matrixType) }, + { ContentKey, content } }; + } + // === Event factory === + using event_type_t = size_t; + using event_mtype_t = const char*; + + template + struct EventTypeTraits + { + static const event_type_t id; + }; + + template <> + struct EventTypeTraits + { + static constexpr event_type_t id = 0; + }; + + event_type_t nextTypeId(); + + template + const event_type_t EventTypeTraits::id = nextTypeId(); + + template + inline event_type_t typeId() { return EventTypeTraits>::id; } + + inline event_type_t unknownEventTypeId() { return typeId(); } + template inline event_ptr_tt makeEvent(ArgTs&&... args) { return std::make_unique(std::forward(args)...); } - class EventTypeRegistry + template + class EventFactory { public: - static constexpr event_type_t unknownTypeId() { return 0; } - static event_type_t nextTypeId(); + template + static void addMethod(FnT&& method) + { + factories().emplace_back(std::forward(method)); + } /** Chain two type factories * Adds the factory class of EventT2 (EventT2::factory_t) to @@ -83,53 +120,11 @@ namespace QMatrixClient * to include RoomEvent types into the more general Event factory, * and state event types into the RoomEvent factory. */ - template - static auto chainFactories() - { - EventT1::factory_t::addFactory(&EventT2::factory_t::make); - return 0; - } - - /** Add a type to its default factory - * Adds a standard factory method (via makeEvent<>) for a given - * type to EventT::factory_t factory class so that it can be - * created dynamically from loadEvent<>(). - * - * \tparam EventT the type to enable dynamic creation of - * \return the registered type id - * \sa loadEvent, Event::type - */ template - static auto addType() + static auto chainFactory() { - EventT::factory_t::addFactory( - [] (const QJsonObject& json, const QString& jsonMatrixType) - { - return EventT::matrixTypeId() == jsonMatrixType - ? makeEvent(json) : nullptr; - }); - return nextTypeId(); - } - - template - static auto typeId() { return _typeId>; } - - private: - template - static const event_type_t _typeId; - }; - - template - const event_type_t EventTypeRegistry::_typeId = addType(); - - template - class EventFactory - { - public: - template - static void addFactory(FnT&& factory) - { - factories().emplace_back(std::forward(factory)); + addMethod(&EventT::factory_t::make); + return 0; } static event_ptr_tt make(const QJsonObject& json, @@ -138,8 +133,7 @@ namespace QMatrixClient for (const auto& f: factories()) if (auto e = f(json, matrixType)) return e; - return makeEvent(EventTypeRegistry::unknownTypeId(), - json); + return makeEvent(unknownEventTypeId(), json); } private: @@ -153,12 +147,24 @@ namespace QMatrixClient } }; - template - inline QJsonObject basicEventJson(StrT matrixType, - const QJsonObject& content) + /** Add a type to its default factory + * Adds a standard factory method (via makeEvent<>) for a given + * type to EventT::factory_t factory class so that it can be + * created dynamically from loadEvent<>(). + * + * \tparam EventT the type to enable dynamic creation of + * \return the registered type id + * \sa loadEvent, Event::type + */ + template + inline void setupFactory() { - return { { TypeKey, std::forward(matrixType) }, - { ContentKey, content } }; + EventT::factory_t::addMethod( + [] (const QJsonObject& json, const QString& jsonMatrixType) + { + return EventT::matrixTypeId() == jsonMatrixType + ? makeEvent(json) : nullptr; + }); } /** Create an event with proper type from a JSON object @@ -199,6 +205,8 @@ namespace QMatrixClient class Event { Q_GADGET + Q_PROPERTY(Type type READ type CONSTANT) + Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT) public: using Type = event_type_t; using factory_t = EventFactory; @@ -228,22 +236,12 @@ namespace QMatrixClient virtual bool isStateEvent() const { return false; } - template - bool is() const - { - const auto eventTypeId = EventTypeRegistry::typeId(); - return _type == eventTypeId; - } - protected: QJsonObject& editJson() { return _json; } private: Type _type; QJsonObject _json; - - Q_PROPERTY(Type type READ type CONSTANT) - Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT) }; using EventPtr = event_ptr_tt; @@ -251,33 +249,47 @@ namespace QMatrixClient using EventsArray = std::vector>; using Events = EventsArray; + // === Macros used with event class definitions === + // This macro should be used in a public section of an event class to // provide matrixTypeId() and typeId(). #define DEFINE_EVENT_TYPEID(_Id, _Type) \ static constexpr event_mtype_t matrixTypeId() { return _Id; } \ - static event_type_t typeId() { return EventTypeRegistry::typeId<_Type>(); } - - // This macro should be put after an event class definition to define an - // additional constant that can be used for an event type id. The constant - // will be inside EventType namespace. This is for back-compatibility, - // to support clients checking for EventType::ShortName (previously - // EventType was a typedef for an enumeration). New code should use - // either typeId() for a specific event type, or (better) casting methods - // defined in the very beginning of this file. + static auto typeId() { return QMatrixClient::typeId<_Type>(); } \ + // End of macro + + // This macro should be put after an event class definition (in .h or .cpp) + // to enable its deserialisation from a /sync and other + // polymorphic event arrays +#define REGISTER_EVENT_TYPE(_Type) \ + namespace { \ + [[gnu::unused]] \ + static const auto _factoryAdded##_Type = ( setupFactory<_Type>(), 0); \ + } \ + // End of macro + + // This macro provides constants in EventType:: namespace for + // back-compatibility with libQMatrixClient 0.3 event type system. #define DEFINE_EVENTTYPE_ALIAS(_Id, _Type) \ namespace EventType \ { \ - [[deprecated("Use "#_Type"::typeId(), Event::is<>() or visit<>()")]] \ - static const auto _Id { _Type::typeId() }; \ - } // End of macro + [[deprecated("Use typeId<>(), is<>() or visit<>()")]] \ + static const auto _Id = typeId<_Type>(); \ + } \ + // End of macro + + // === is<>() and visit<>() === + + template + inline bool is(const Event& e) { return e.type() == typeId(); } - // === visit<>() === + inline bool isUnknown(const Event& e) { return e.type() == unknownEventTypeId(); } template inline fn_return_t visit(const Event& event, FnT visitor) { using event_type = fn_arg_t; - if (event.is()) + if (is(event)) return visitor(static_cast(event)); return fn_return_t(); } @@ -286,7 +298,7 @@ namespace QMatrixClient inline auto visit(const Event& event, FnT visitor1, FnTs&&... visitors) { using event_type1 = fn_arg_t; - if (event.is()) + if (is(event)) return visitor1(static_cast(event)); return visit(event, std::forward(visitors)...); diff --git a/lib/events/receiptevent.h b/lib/events/receiptevent.h index 10b3f631..5237ba69 100644 --- a/lib/events/receiptevent.h +++ b/lib/events/receiptevent.h @@ -48,5 +48,6 @@ namespace QMatrixClient private: EventsWithReceipts _eventsWithReceipts; }; + REGISTER_EVENT_TYPE(ReceiptEvent) DEFINE_EVENTTYPE_ALIAS(Receipt, ReceiptEvent) } // namespace QMatrixClient diff --git a/lib/events/redactionevent.h b/lib/events/redactionevent.h index 8c6cbeff..64504d57 100644 --- a/lib/events/redactionevent.h +++ b/lib/events/redactionevent.h @@ -36,5 +36,6 @@ namespace QMatrixClient QString reason() const { return contentJson()["reason"_ls].toString(); } }; + REGISTER_EVENT_TYPE(RedactionEvent) DEFINE_EVENTTYPE_ALIAS(Redaction, RedactionEvent) } // namespace QMatrixClient diff --git a/lib/events/roomavatarevent.h b/lib/events/roomavatarevent.h index fe11807c..491861b1 100644 --- a/lib/events/roomavatarevent.h +++ b/lib/events/roomavatarevent.h @@ -37,5 +37,6 @@ namespace QMatrixClient { } QUrl url() const { return content().url; } }; + REGISTER_EVENT_TYPE(RoomAvatarEvent) DEFINE_EVENTTYPE_ALIAS(RoomAvatar, RoomAvatarEvent) } // namespace QMatrixClient diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h index 943d5ac6..1ecd63d1 100644 --- a/lib/events/roommemberevent.h +++ b/lib/events/roommemberevent.h @@ -80,5 +80,6 @@ namespace QMatrixClient private: REGISTER_ENUM(MembershipType) }; + REGISTER_EVENT_TYPE(RoomMemberEvent) DEFINE_EVENTTYPE_ALIAS(RoomMember, RoomMemberEvent) } // namespace QMatrixClient diff --git a/lib/events/roommessageevent.h b/lib/events/roommessageevent.h index 3f3832d4..ccf30f96 100644 --- a/lib/events/roommessageevent.h +++ b/lib/events/roommessageevent.h @@ -67,6 +67,7 @@ namespace QMatrixClient REGISTER_ENUM(MsgType) }; + REGISTER_EVENT_TYPE(RoomMessageEvent) DEFINE_EVENTTYPE_ALIAS(RoomMessage, RoomMessageEvent) using MessageEventType = RoomMessageEvent::MsgType; diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h index a117efb1..afd59478 100644 --- a/lib/events/simplestateevents.h +++ b/lib/events/simplestateevents.h @@ -73,7 +73,9 @@ namespace QMatrixClient std::forward(value)) \ { } \ auto _ContentKey() const { return content().value; } \ - }; // End of macro + }; \ + REGISTER_EVENT_TYPE(_Name) \ + // End of macro DEFINE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", QString, name) DEFINE_EVENTTYPE_ALIAS(RoomName, RoomNameEvent) diff --git a/lib/events/typingevent.h b/lib/events/typingevent.h index 0c4b350d..27b668b4 100644 --- a/lib/events/typingevent.h +++ b/lib/events/typingevent.h @@ -34,5 +34,6 @@ namespace QMatrixClient private: QStringList _users; }; + REGISTER_EVENT_TYPE(TypingEvent) DEFINE_EVENTTYPE_ALIAS(Typing, TypingEvent) } // namespace QMatrixClient diff --git a/lib/room.cpp b/lib/room.cpp index 9f4b5a0e..080ad30d 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -168,7 +168,7 @@ class Room::Private { return !ti->isRedacted() && ti->senderId() != connection->userId() && - ti->is(); + is(*ti); } void addNewMessageEvents(RoomEvents&& events); @@ -725,7 +725,7 @@ const RoomMessageEvent* Room::Private::getEventWithFile(const QString& eventId) const { auto evtIt = q->findInTimeline(eventId); - if (evtIt != timeline.rend() && evtIt->event()->is()) + if (evtIt != timeline.rend() && is(**evtIt)) { auto* event = evtIt->viewAs(); if (event->hasFileContent()) @@ -1275,7 +1275,7 @@ void Room::Private::dropDuplicateEvents(RoomEvents& events) const inline bool isRedaction(const RoomEventPtr& e) { - return e && e->is(); + return e && is(*e); } void Room::Private::processRedaction(event_ptr_tt&& redaction) -- cgit v1.2.3 From 3dd6b5e6cc50aafce74b21b5a0bf4b26a9fcf6ee Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 2 Jul 2018 17:58:34 +0900 Subject: Use QStringLiteral() and operator"" _ls() in network jobs --- lib/csapi/account-data.cpp | 8 ++- lib/csapi/admin.cpp | 18 +++--- lib/csapi/administrative_contact.cpp | 28 +++++---- lib/csapi/banning.cpp | 14 +++-- lib/csapi/content-repo.cpp | 46 +++++++++------ lib/csapi/create_room.cpp | 40 +++++++------ lib/csapi/definitions/client_device.cpp | 16 ++--- lib/csapi/definitions/device_keys.cpp | 20 +++---- lib/csapi/definitions/event_filter.cpp | 20 +++---- lib/csapi/definitions/push_condition.cpp | 16 ++--- lib/csapi/definitions/push_rule.cpp | 24 ++++---- lib/csapi/definitions/push_ruleset.cpp | 20 +++---- lib/csapi/definitions/room_event_filter.cpp | 12 ++-- lib/csapi/definitions/sync_filter.cpp | 48 +++++++-------- lib/csapi/device_management.cpp | 34 +++++++---- lib/csapi/directory.cpp | 18 ++++-- lib/csapi/event_context.cpp | 18 +++--- lib/csapi/filter.cpp | 14 +++-- lib/csapi/inviting.cpp | 6 +- lib/csapi/joining.cpp | 38 ++++++------ lib/csapi/keys.cpp | 54 +++++++++-------- lib/csapi/kicking.cpp | 8 ++- lib/csapi/leaving.cpp | 8 ++- lib/csapi/list_joined_rooms.cpp | 8 ++- lib/csapi/list_public_rooms.cpp | 92 ++++++++++++++++------------- lib/csapi/login.cpp | 28 +++++---- lib/csapi/logout.cpp | 8 ++- lib/csapi/message_pagination.cpp | 20 ++++--- lib/csapi/notifications.cpp | 28 +++++---- lib/csapi/peeking_events.cpp | 16 ++--- lib/csapi/presence.cpp | 38 +++++++----- lib/csapi/profile.cpp | 32 ++++++---- lib/csapi/pusher.cpp | 48 ++++++++------- lib/csapi/pushrules.cpp | 62 +++++++++++-------- lib/csapi/receipts.cpp | 4 +- lib/csapi/redaction.cpp | 8 ++- lib/csapi/registration.cpp | 64 ++++++++++++-------- lib/csapi/report_content.cpp | 8 ++- lib/csapi/room_send.cpp | 6 +- lib/csapi/room_state.cpp | 12 ++-- lib/csapi/rooms.cpp | 48 +++++++++------ lib/csapi/search.cpp | 76 ++++++++++++------------ lib/csapi/tags.cpp | 14 +++-- lib/csapi/third_party_membership.cpp | 10 ++-- lib/csapi/to_device.cpp | 6 +- lib/csapi/typing.cpp | 8 ++- lib/csapi/users.cpp | 22 +++---- lib/csapi/versions.cpp | 6 +- lib/csapi/voip.cpp | 8 ++- lib/csapi/whoami.cpp | 8 ++- lib/csapi/{{base}}.cpp.mustache | 20 ++++--- lib/jobs/basejob.cpp | 25 ++++---- lib/jobs/sendeventjob.cpp | 2 +- lib/jobs/syncjob.cpp | 45 +++++++------- 54 files changed, 751 insertions(+), 557 deletions(-) (limited to 'lib') diff --git a/lib/csapi/account-data.cpp b/lib/csapi/account-data.cpp index ac45cb85..5021c73a 100644 --- a/lib/csapi/account-data.cpp +++ b/lib/csapi/account-data.cpp @@ -12,15 +12,19 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto SetAccountDataJobName = QStringLiteral("SetAccountDataJob"); + SetAccountDataJob::SetAccountDataJob(const QString& userId, const QString& type, const QJsonObject& content) - : BaseJob(HttpVerb::Put, "SetAccountDataJob", + : BaseJob(HttpVerb::Put, SetAccountDataJobName, basePath % "/user/" % userId % "/account_data/" % type) { setRequestData(Data(toJson(content))); } +static const auto SetAccountDataPerRoomJobName = QStringLiteral("SetAccountDataPerRoomJob"); + SetAccountDataPerRoomJob::SetAccountDataPerRoomJob(const QString& userId, const QString& roomId, const QString& type, const QJsonObject& content) - : BaseJob(HttpVerb::Put, "SetAccountDataPerRoomJob", + : BaseJob(HttpVerb::Put, SetAccountDataPerRoomJobName, basePath % "/user/" % userId % "/rooms/" % roomId % "/account_data/" % type) { setRequestData(Data(toJson(content))); diff --git a/lib/csapi/admin.cpp b/lib/csapi/admin.cpp index a0f7f67f..3effbbc3 100644 --- a/lib/csapi/admin.cpp +++ b/lib/csapi/admin.cpp @@ -23,11 +23,11 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetWhoIsJob::ConnectionInfo result; result.ip = - fromJson(_json.value("ip")); + fromJson(_json.value("ip"_ls)); result.lastSeen = - fromJson(_json.value("last_seen")); + fromJson(_json.value("last_seen"_ls)); result.userAgent = - fromJson(_json.value("user_agent")); + fromJson(_json.value("user_agent"_ls)); return result; } @@ -40,7 +40,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetWhoIsJob::SessionInfo result; result.connections = - fromJson>(_json.value("connections")); + fromJson>(_json.value("connections"_ls)); return result; } @@ -53,7 +53,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetWhoIsJob::DeviceInfo result; result.sessions = - fromJson>(_json.value("sessions")); + fromJson>(_json.value("sessions"_ls)); return result; } @@ -73,8 +73,10 @@ QUrl GetWhoIsJob::makeRequestUrl(QUrl baseUrl, const QString& userId) basePath % "/admin/whois/" % userId); } +static const auto GetWhoIsJobName = QStringLiteral("GetWhoIsJob"); + GetWhoIsJob::GetWhoIsJob(const QString& userId) - : BaseJob(HttpVerb::Get, "GetWhoIsJob", + : BaseJob(HttpVerb::Get, GetWhoIsJobName, basePath % "/admin/whois/" % userId) , d(new Private) { @@ -95,8 +97,8 @@ const QHash& GetWhoIsJob::devices() const BaseJob::Status GetWhoIsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->userId = fromJson(json.value("user_id")); - d->devices = fromJson>(json.value("devices")); + d->userId = fromJson(json.value("user_id"_ls)); + d->devices = fromJson>(json.value("devices"_ls)); return Success; } diff --git a/lib/csapi/administrative_contact.cpp b/lib/csapi/administrative_contact.cpp index e3dee8ed..682a6f05 100644 --- a/lib/csapi/administrative_contact.cpp +++ b/lib/csapi/administrative_contact.cpp @@ -23,9 +23,9 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetAccount3PIDsJob::ThirdPartyIdentifier result; result.medium = - fromJson(_json.value("medium")); + fromJson(_json.value("medium"_ls)); result.address = - fromJson(_json.value("address")); + fromJson(_json.value("address"_ls)); return result; } @@ -44,8 +44,10 @@ QUrl GetAccount3PIDsJob::makeRequestUrl(QUrl baseUrl) basePath % "/account/3pid"); } +static const auto GetAccount3PIDsJobName = QStringLiteral("GetAccount3PIDsJob"); + GetAccount3PIDsJob::GetAccount3PIDsJob() - : BaseJob(HttpVerb::Get, "GetAccount3PIDsJob", + : BaseJob(HttpVerb::Get, GetAccount3PIDsJobName, basePath % "/account/3pid") , d(new Private) { @@ -61,7 +63,7 @@ const QVector& GetAccount3PIDsJob::thr BaseJob::Status GetAccount3PIDsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->threepids = fromJson>(json.value("threepids")); + d->threepids = fromJson>(json.value("threepids"_ls)); return Success; } @@ -72,20 +74,22 @@ namespace QMatrixClient QJsonObject toJson(const Post3PIDsJob::ThreePidCredentials& pod) { QJsonObject _json; - addParam<>(_json, "client_secret", pod.clientSecret); - addParam<>(_json, "id_server", pod.idServer); - addParam<>(_json, "sid", pod.sid); + addParam<>(_json, QStringLiteral("client_secret"), pod.clientSecret); + addParam<>(_json, QStringLiteral("id_server"), pod.idServer); + addParam<>(_json, QStringLiteral("sid"), pod.sid); return _json; } } // namespace QMatrixClient +static const auto Post3PIDsJobName = QStringLiteral("Post3PIDsJob"); + Post3PIDsJob::Post3PIDsJob(const ThreePidCredentials& threePidCreds, bool bind) - : BaseJob(HttpVerb::Post, "Post3PIDsJob", + : BaseJob(HttpVerb::Post, Post3PIDsJobName, basePath % "/account/3pid") { QJsonObject _data; - addParam<>(_data, "three_pid_creds", threePidCreds); - addParam(_data, "bind", bind); + addParam<>(_data, QStringLiteral("three_pid_creds"), threePidCreds); + addParam(_data, QStringLiteral("bind"), bind); setRequestData(_data); } @@ -95,8 +99,10 @@ QUrl RequestTokenTo3PIDJob::makeRequestUrl(QUrl baseUrl) basePath % "/account/3pid/email/requestToken"); } +static const auto RequestTokenTo3PIDJobName = QStringLiteral("RequestTokenTo3PIDJob"); + RequestTokenTo3PIDJob::RequestTokenTo3PIDJob() - : BaseJob(HttpVerb::Post, "RequestTokenTo3PIDJob", + : BaseJob(HttpVerb::Post, RequestTokenTo3PIDJobName, basePath % "/account/3pid/email/requestToken", false) { } diff --git a/lib/csapi/banning.cpp b/lib/csapi/banning.cpp index 4dbd8a7d..4065207b 100644 --- a/lib/csapi/banning.cpp +++ b/lib/csapi/banning.cpp @@ -12,22 +12,26 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto BanJobName = QStringLiteral("BanJob"); + BanJob::BanJob(const QString& roomId, const QString& userId, const QString& reason) - : BaseJob(HttpVerb::Post, "BanJob", + : BaseJob(HttpVerb::Post, BanJobName, basePath % "/rooms/" % roomId % "/ban") { QJsonObject _data; - addParam<>(_data, "user_id", userId); - addParam(_data, "reason", reason); + addParam<>(_data, QStringLiteral("user_id"), userId); + addParam(_data, QStringLiteral("reason"), reason); setRequestData(_data); } +static const auto UnbanJobName = QStringLiteral("UnbanJob"); + UnbanJob::UnbanJob(const QString& roomId, const QString& userId) - : BaseJob(HttpVerb::Post, "UnbanJob", + : BaseJob(HttpVerb::Post, UnbanJobName, basePath % "/rooms/" % roomId % "/unban") { QJsonObject _data; - addParam<>(_data, "user_id", userId); + addParam<>(_data, QStringLiteral("user_id"), userId); setRequestData(_data); } diff --git a/lib/csapi/content-repo.cpp b/lib/csapi/content-repo.cpp index 4ce80d08..9ac226ba 100644 --- a/lib/csapi/content-repo.cpp +++ b/lib/csapi/content-repo.cpp @@ -22,12 +22,14 @@ class UploadContentJob::Private BaseJob::Query queryToUploadContent(const QString& filename) { BaseJob::Query _q; - addParam(_q, "filename", filename); + addParam(_q, QStringLiteral("filename"), filename); return _q; } +static const auto UploadContentJobName = QStringLiteral("UploadContentJob"); + UploadContentJob::UploadContentJob(QIODevice* content, const QString& filename, const QString& contentType) - : BaseJob(HttpVerb::Post, "UploadContentJob", + : BaseJob(HttpVerb::Post, UploadContentJobName, basePath % "/upload", queryToUploadContent(filename)) , d(new Private) @@ -47,10 +49,10 @@ const QString& UploadContentJob::contentUri() const BaseJob::Status UploadContentJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("content_uri")) + if (!json.contains("content_uri"_ls)) return { JsonParseError, "The key 'content_uri' not found in the response" }; - d->contentUri = fromJson(json.value("content_uri")); + d->contentUri = fromJson(json.value("content_uri"_ls)); return Success; } @@ -65,7 +67,7 @@ class GetContentJob::Private BaseJob::Query queryToGetContent(bool allowRemote) { BaseJob::Query _q; - addParam(_q, "allow_remote", allowRemote); + addParam(_q, QStringLiteral("allow_remote"), allowRemote); return _q; } @@ -76,8 +78,10 @@ QUrl GetContentJob::makeRequestUrl(QUrl baseUrl, const QString& serverName, cons queryToGetContent(allowRemote)); } +static const auto GetContentJobName = QStringLiteral("GetContentJob"); + GetContentJob::GetContentJob(const QString& serverName, const QString& mediaId, bool allowRemote) - : BaseJob(HttpVerb::Get, "GetContentJob", + : BaseJob(HttpVerb::Get, GetContentJobName, basePath % "/download/" % serverName % "/" % mediaId, queryToGetContent(allowRemote), {}, false) @@ -122,7 +126,7 @@ class GetContentOverrideNameJob::Private BaseJob::Query queryToGetContentOverrideName(bool allowRemote) { BaseJob::Query _q; - addParam(_q, "allow_remote", allowRemote); + addParam(_q, QStringLiteral("allow_remote"), allowRemote); return _q; } @@ -133,8 +137,10 @@ QUrl GetContentOverrideNameJob::makeRequestUrl(QUrl baseUrl, const QString& serv queryToGetContentOverrideName(allowRemote)); } +static const auto GetContentOverrideNameJobName = QStringLiteral("GetContentOverrideNameJob"); + GetContentOverrideNameJob::GetContentOverrideNameJob(const QString& serverName, const QString& mediaId, const QString& fileName, bool allowRemote) - : BaseJob(HttpVerb::Get, "GetContentOverrideNameJob", + : BaseJob(HttpVerb::Get, GetContentOverrideNameJobName, basePath % "/download/" % serverName % "/" % mediaId % "/" % fileName, queryToGetContentOverrideName(allowRemote), {}, false) @@ -178,10 +184,10 @@ class GetContentThumbnailJob::Private BaseJob::Query queryToGetContentThumbnail(int width, int height, const QString& method, bool allowRemote) { BaseJob::Query _q; - addParam<>(_q, "width", width); - addParam<>(_q, "height", height); - addParam(_q, "method", method); - addParam(_q, "allow_remote", allowRemote); + addParam<>(_q, QStringLiteral("width"), width); + addParam<>(_q, QStringLiteral("height"), height); + addParam(_q, QStringLiteral("method"), method); + addParam(_q, QStringLiteral("allow_remote"), allowRemote); return _q; } @@ -192,8 +198,10 @@ QUrl GetContentThumbnailJob::makeRequestUrl(QUrl baseUrl, const QString& serverN queryToGetContentThumbnail(width, height, method, allowRemote)); } +static const auto GetContentThumbnailJobName = QStringLiteral("GetContentThumbnailJob"); + GetContentThumbnailJob::GetContentThumbnailJob(const QString& serverName, const QString& mediaId, int width, int height, const QString& method, bool allowRemote) - : BaseJob(HttpVerb::Get, "GetContentThumbnailJob", + : BaseJob(HttpVerb::Get, GetContentThumbnailJobName, basePath % "/thumbnail/" % serverName % "/" % mediaId, queryToGetContentThumbnail(width, height, method, allowRemote), {}, false) @@ -231,8 +239,8 @@ class GetUrlPreviewJob::Private BaseJob::Query queryToGetUrlPreview(const QString& url, Omittable ts) { BaseJob::Query _q; - addParam<>(_q, "url", url); - addParam(_q, "ts", ts); + addParam<>(_q, QStringLiteral("url"), url); + addParam(_q, QStringLiteral("ts"), ts); return _q; } @@ -243,8 +251,10 @@ QUrl GetUrlPreviewJob::makeRequestUrl(QUrl baseUrl, const QString& url, Omittabl queryToGetUrlPreview(url, ts)); } +static const auto GetUrlPreviewJobName = QStringLiteral("GetUrlPreviewJob"); + GetUrlPreviewJob::GetUrlPreviewJob(const QString& url, Omittable ts) - : BaseJob(HttpVerb::Get, "GetUrlPreviewJob", + : BaseJob(HttpVerb::Get, GetUrlPreviewJobName, basePath % "/preview_url", queryToGetUrlPreview(url, ts)) , d(new Private) @@ -266,8 +276,8 @@ const QString& GetUrlPreviewJob::ogImage() const BaseJob::Status GetUrlPreviewJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->matrixImageSize = fromJson(json.value("matrix:image:size")); - d->ogImage = fromJson(json.value("og:image")); + d->matrixImageSize = fromJson(json.value("matrix:image:size"_ls)); + d->ogImage = fromJson(json.value("og:image"_ls)); return Success; } diff --git a/lib/csapi/create_room.cpp b/lib/csapi/create_room.cpp index 910210bc..5600e18a 100644 --- a/lib/csapi/create_room.cpp +++ b/lib/csapi/create_room.cpp @@ -19,18 +19,18 @@ namespace QMatrixClient QJsonObject toJson(const CreateRoomJob::Invite3pid& pod) { QJsonObject _json; - addParam<>(_json, "id_server", pod.idServer); - addParam<>(_json, "medium", pod.medium); - addParam<>(_json, "address", pod.address); + addParam<>(_json, QStringLiteral("id_server"), pod.idServer); + addParam<>(_json, QStringLiteral("medium"), pod.medium); + addParam<>(_json, QStringLiteral("address"), pod.address); return _json; } QJsonObject toJson(const CreateRoomJob::StateEvent& pod) { QJsonObject _json; - addParam(_json, "type", pod.type); - addParam(_json, "state_key", pod.stateKey); - addParam(_json, "content", pod.content); + addParam(_json, QStringLiteral("type"), pod.type); + addParam(_json, QStringLiteral("state_key"), pod.stateKey); + addParam(_json, QStringLiteral("content"), pod.content); return _json; } } // namespace QMatrixClient @@ -41,23 +41,25 @@ class CreateRoomJob::Private QString roomId; }; +static const auto CreateRoomJobName = QStringLiteral("CreateRoomJob"); + CreateRoomJob::CreateRoomJob(const QString& visibility, const QString& roomAliasName, const QString& name, const QString& topic, const QStringList& invite, const QVector& invite3pid, const QJsonObject& creationContent, const QVector& initialState, const QString& preset, bool isDirect, bool guestCanJoin) - : BaseJob(HttpVerb::Post, "CreateRoomJob", + : BaseJob(HttpVerb::Post, CreateRoomJobName, basePath % "/createRoom") , d(new Private) { QJsonObject _data; - addParam(_data, "visibility", visibility); - addParam(_data, "room_alias_name", roomAliasName); - addParam(_data, "name", name); - addParam(_data, "topic", topic); - addParam(_data, "invite", invite); - addParam(_data, "invite_3pid", invite3pid); - addParam(_data, "creation_content", creationContent); - addParam(_data, "initial_state", initialState); - addParam(_data, "preset", preset); - addParam(_data, "is_direct", isDirect); - addParam(_data, "guest_can_join", guestCanJoin); + addParam(_data, QStringLiteral("visibility"), visibility); + addParam(_data, QStringLiteral("room_alias_name"), roomAliasName); + addParam(_data, QStringLiteral("name"), name); + addParam(_data, QStringLiteral("topic"), topic); + addParam(_data, QStringLiteral("invite"), invite); + addParam(_data, QStringLiteral("invite_3pid"), invite3pid); + addParam(_data, QStringLiteral("creation_content"), creationContent); + addParam(_data, QStringLiteral("initial_state"), initialState); + addParam(_data, QStringLiteral("preset"), preset); + addParam(_data, QStringLiteral("is_direct"), isDirect); + addParam(_data, QStringLiteral("guest_can_join"), guestCanJoin); setRequestData(_data); } @@ -71,7 +73,7 @@ const QString& CreateRoomJob::roomId() const BaseJob::Status CreateRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->roomId = fromJson(json.value("room_id")); + d->roomId = fromJson(json.value("room_id"_ls)); return Success; } diff --git a/lib/csapi/definitions/client_device.cpp b/lib/csapi/definitions/client_device.cpp index 7c3d7ea6..bd7acd02 100644 --- a/lib/csapi/definitions/client_device.cpp +++ b/lib/csapi/definitions/client_device.cpp @@ -9,10 +9,10 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const Device& pod) { QJsonObject _json; - addParam<>(_json, "device_id", pod.deviceId); - addParam(_json, "display_name", pod.displayName); - addParam(_json, "last_seen_ip", pod.lastSeenIp); - addParam(_json, "last_seen_ts", pod.lastSeenTs); + addParam<>(_json, QStringLiteral("device_id"), pod.deviceId); + addParam(_json, QStringLiteral("display_name"), pod.displayName); + addParam(_json, QStringLiteral("last_seen_ip"), pod.lastSeenIp); + addParam(_json, QStringLiteral("last_seen_ts"), pod.lastSeenTs); return _json; } @@ -21,13 +21,13 @@ Device FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); Device result; result.deviceId = - fromJson(_json.value("device_id")); + fromJson(_json.value("device_id"_ls)); result.displayName = - fromJson(_json.value("display_name")); + fromJson(_json.value("display_name"_ls)); result.lastSeenIp = - fromJson(_json.value("last_seen_ip")); + fromJson(_json.value("last_seen_ip"_ls)); result.lastSeenTs = - fromJson(_json.value("last_seen_ts")); + fromJson(_json.value("last_seen_ts"_ls)); return result; } diff --git a/lib/csapi/definitions/device_keys.cpp b/lib/csapi/definitions/device_keys.cpp index 43cd5d2e..d17f4c12 100644 --- a/lib/csapi/definitions/device_keys.cpp +++ b/lib/csapi/definitions/device_keys.cpp @@ -9,11 +9,11 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const DeviceKeys& pod) { QJsonObject _json; - addParam<>(_json, "user_id", pod.userId); - addParam<>(_json, "device_id", pod.deviceId); - addParam<>(_json, "algorithms", pod.algorithms); - addParam<>(_json, "keys", pod.keys); - addParam<>(_json, "signatures", pod.signatures); + addParam<>(_json, QStringLiteral("user_id"), pod.userId); + addParam<>(_json, QStringLiteral("device_id"), pod.deviceId); + addParam<>(_json, QStringLiteral("algorithms"), pod.algorithms); + addParam<>(_json, QStringLiteral("keys"), pod.keys); + addParam<>(_json, QStringLiteral("signatures"), pod.signatures); return _json; } @@ -22,15 +22,15 @@ DeviceKeys FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); DeviceKeys result; result.userId = - fromJson(_json.value("user_id")); + fromJson(_json.value("user_id"_ls)); result.deviceId = - fromJson(_json.value("device_id")); + fromJson(_json.value("device_id"_ls)); result.algorithms = - fromJson(_json.value("algorithms")); + fromJson(_json.value("algorithms"_ls)); result.keys = - fromJson>(_json.value("keys")); + fromJson>(_json.value("keys"_ls)); result.signatures = - fromJson>>(_json.value("signatures")); + fromJson>>(_json.value("signatures"_ls)); return result; } diff --git a/lib/csapi/definitions/event_filter.cpp b/lib/csapi/definitions/event_filter.cpp index 21ee2b81..336de0dd 100644 --- a/lib/csapi/definitions/event_filter.cpp +++ b/lib/csapi/definitions/event_filter.cpp @@ -9,11 +9,11 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const Filter& pod) { QJsonObject _json; - addParam(_json, "limit", pod.limit); - addParam(_json, "not_senders", pod.notSenders); - addParam(_json, "not_types", pod.notTypes); - addParam(_json, "senders", pod.senders); - addParam(_json, "types", pod.types); + addParam(_json, QStringLiteral("limit"), pod.limit); + addParam(_json, QStringLiteral("not_senders"), pod.notSenders); + addParam(_json, QStringLiteral("not_types"), pod.notTypes); + addParam(_json, QStringLiteral("senders"), pod.senders); + addParam(_json, QStringLiteral("types"), pod.types); return _json; } @@ -22,15 +22,15 @@ Filter FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); Filter result; result.limit = - fromJson(_json.value("limit")); + fromJson(_json.value("limit"_ls)); result.notSenders = - fromJson(_json.value("not_senders")); + fromJson(_json.value("not_senders"_ls)); result.notTypes = - fromJson(_json.value("not_types")); + fromJson(_json.value("not_types"_ls)); result.senders = - fromJson(_json.value("senders")); + fromJson(_json.value("senders"_ls)); result.types = - fromJson(_json.value("types")); + fromJson(_json.value("types"_ls)); return result; } diff --git a/lib/csapi/definitions/push_condition.cpp b/lib/csapi/definitions/push_condition.cpp index b8595ec6..19351ae1 100644 --- a/lib/csapi/definitions/push_condition.cpp +++ b/lib/csapi/definitions/push_condition.cpp @@ -9,10 +9,10 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PushCondition& pod) { QJsonObject _json; - addParam<>(_json, "kind", pod.kind); - addParam(_json, "key", pod.key); - addParam(_json, "pattern", pod.pattern); - addParam(_json, "is", pod.is); + addParam<>(_json, QStringLiteral("kind"), pod.kind); + addParam(_json, QStringLiteral("key"), pod.key); + addParam(_json, QStringLiteral("pattern"), pod.pattern); + addParam(_json, QStringLiteral("is"), pod.is); return _json; } @@ -21,13 +21,13 @@ PushCondition FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); PushCondition result; result.kind = - fromJson(_json.value("kind")); + fromJson(_json.value("kind"_ls)); result.key = - fromJson(_json.value("key")); + fromJson(_json.value("key"_ls)); result.pattern = - fromJson(_json.value("pattern")); + fromJson(_json.value("pattern"_ls)); result.is = - fromJson(_json.value("is")); + fromJson(_json.value("is"_ls)); return result; } diff --git a/lib/csapi/definitions/push_rule.cpp b/lib/csapi/definitions/push_rule.cpp index 98f5d788..833135ec 100644 --- a/lib/csapi/definitions/push_rule.cpp +++ b/lib/csapi/definitions/push_rule.cpp @@ -9,12 +9,12 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PushRule& pod) { QJsonObject _json; - addParam<>(_json, "actions", pod.actions); - addParam<>(_json, "default", pod.isDefault); - addParam<>(_json, "enabled", pod.enabled); - addParam<>(_json, "rule_id", pod.ruleId); - addParam(_json, "conditions", pod.conditions); - addParam(_json, "pattern", pod.pattern); + addParam<>(_json, QStringLiteral("actions"), pod.actions); + addParam<>(_json, QStringLiteral("default"), pod.isDefault); + addParam<>(_json, QStringLiteral("enabled"), pod.enabled); + addParam<>(_json, QStringLiteral("rule_id"), pod.ruleId); + addParam(_json, QStringLiteral("conditions"), pod.conditions); + addParam(_json, QStringLiteral("pattern"), pod.pattern); return _json; } @@ -23,17 +23,17 @@ PushRule FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); PushRule result; result.actions = - fromJson>(_json.value("actions")); + fromJson>(_json.value("actions"_ls)); result.isDefault = - fromJson(_json.value("default")); + fromJson(_json.value("default"_ls)); result.enabled = - fromJson(_json.value("enabled")); + fromJson(_json.value("enabled"_ls)); result.ruleId = - fromJson(_json.value("rule_id")); + fromJson(_json.value("rule_id"_ls)); result.conditions = - fromJson>(_json.value("conditions")); + fromJson>(_json.value("conditions"_ls)); result.pattern = - fromJson(_json.value("pattern")); + fromJson(_json.value("pattern"_ls)); return result; } diff --git a/lib/csapi/definitions/push_ruleset.cpp b/lib/csapi/definitions/push_ruleset.cpp index ca2bbc0d..c424f686 100644 --- a/lib/csapi/definitions/push_ruleset.cpp +++ b/lib/csapi/definitions/push_ruleset.cpp @@ -9,11 +9,11 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PushRuleset& pod) { QJsonObject _json; - addParam(_json, "content", pod.content); - addParam(_json, "override", pod.override); - addParam(_json, "room", pod.room); - addParam(_json, "sender", pod.sender); - addParam(_json, "underride", pod.underride); + addParam(_json, QStringLiteral("content"), pod.content); + addParam(_json, QStringLiteral("override"), pod.override); + addParam(_json, QStringLiteral("room"), pod.room); + addParam(_json, QStringLiteral("sender"), pod.sender); + addParam(_json, QStringLiteral("underride"), pod.underride); return _json; } @@ -22,15 +22,15 @@ PushRuleset FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); PushRuleset result; result.content = - fromJson>(_json.value("content")); + fromJson>(_json.value("content"_ls)); result.override = - fromJson>(_json.value("override")); + fromJson>(_json.value("override"_ls)); result.room = - fromJson>(_json.value("room")); + fromJson>(_json.value("room"_ls)); result.sender = - fromJson>(_json.value("sender")); + fromJson>(_json.value("sender"_ls)); result.underride = - fromJson>(_json.value("underride")); + fromJson>(_json.value("underride"_ls)); return result; } diff --git a/lib/csapi/definitions/room_event_filter.cpp b/lib/csapi/definitions/room_event_filter.cpp index 1702be22..18ce07ec 100644 --- a/lib/csapi/definitions/room_event_filter.cpp +++ b/lib/csapi/definitions/room_event_filter.cpp @@ -9,9 +9,9 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const RoomEventFilter& pod) { QJsonObject _json; - addParam(_json, "not_rooms", pod.notRooms); - addParam(_json, "rooms", pod.rooms); - addParam(_json, "contains_url", pod.containsUrl); + addParam(_json, QStringLiteral("not_rooms"), pod.notRooms); + addParam(_json, QStringLiteral("rooms"), pod.rooms); + addParam(_json, QStringLiteral("contains_url"), pod.containsUrl); return _json; } @@ -20,11 +20,11 @@ RoomEventFilter FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); RoomEventFilter result; result.notRooms = - fromJson(_json.value("not_rooms")); + fromJson(_json.value("not_rooms"_ls)); result.rooms = - fromJson(_json.value("rooms")); + fromJson(_json.value("rooms"_ls)); result.containsUrl = - fromJson(_json.value("contains_url")); + fromJson(_json.value("contains_url"_ls)); return result; } diff --git a/lib/csapi/definitions/sync_filter.cpp b/lib/csapi/definitions/sync_filter.cpp index 2b5cf8be..b42f15f5 100644 --- a/lib/csapi/definitions/sync_filter.cpp +++ b/lib/csapi/definitions/sync_filter.cpp @@ -9,13 +9,13 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const RoomFilter& pod) { QJsonObject _json; - addParam(_json, "not_rooms", pod.notRooms); - addParam(_json, "rooms", pod.rooms); - addParam(_json, "ephemeral", pod.ephemeral); - addParam(_json, "include_leave", pod.includeLeave); - addParam(_json, "state", pod.state); - addParam(_json, "timeline", pod.timeline); - addParam(_json, "account_data", pod.accountData); + addParam(_json, QStringLiteral("not_rooms"), pod.notRooms); + addParam(_json, QStringLiteral("rooms"), pod.rooms); + addParam(_json, QStringLiteral("ephemeral"), pod.ephemeral); + addParam(_json, QStringLiteral("include_leave"), pod.includeLeave); + addParam(_json, QStringLiteral("state"), pod.state); + addParam(_json, QStringLiteral("timeline"), pod.timeline); + addParam(_json, QStringLiteral("account_data"), pod.accountData); return _json; } @@ -24,19 +24,19 @@ RoomFilter FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); RoomFilter result; result.notRooms = - fromJson(_json.value("not_rooms")); + fromJson(_json.value("not_rooms"_ls)); result.rooms = - fromJson(_json.value("rooms")); + fromJson(_json.value("rooms"_ls)); result.ephemeral = - fromJson(_json.value("ephemeral")); + fromJson(_json.value("ephemeral"_ls)); result.includeLeave = - fromJson(_json.value("include_leave")); + fromJson(_json.value("include_leave"_ls)); result.state = - fromJson(_json.value("state")); + fromJson(_json.value("state"_ls)); result.timeline = - fromJson(_json.value("timeline")); + fromJson(_json.value("timeline"_ls)); result.accountData = - fromJson(_json.value("account_data")); + fromJson(_json.value("account_data"_ls)); return result; } @@ -44,11 +44,11 @@ RoomFilter FromJson::operator()(const QJsonValue& jv) QJsonObject QMatrixClient::toJson(const SyncFilter& pod) { QJsonObject _json; - addParam(_json, "event_fields", pod.eventFields); - addParam(_json, "event_format", pod.eventFormat); - addParam(_json, "presence", pod.presence); - addParam(_json, "account_data", pod.accountData); - addParam(_json, "room", pod.room); + addParam(_json, QStringLiteral("event_fields"), pod.eventFields); + addParam(_json, QStringLiteral("event_format"), pod.eventFormat); + addParam(_json, QStringLiteral("presence"), pod.presence); + addParam(_json, QStringLiteral("account_data"), pod.accountData); + addParam(_json, QStringLiteral("room"), pod.room); return _json; } @@ -57,15 +57,15 @@ SyncFilter FromJson::operator()(const QJsonValue& jv) const auto& _json = jv.toObject(); SyncFilter result; result.eventFields = - fromJson(_json.value("event_fields")); + fromJson(_json.value("event_fields"_ls)); result.eventFormat = - fromJson(_json.value("event_format")); + fromJson(_json.value("event_format"_ls)); result.presence = - fromJson(_json.value("presence")); + fromJson(_json.value("presence"_ls)); result.accountData = - fromJson(_json.value("account_data")); + fromJson(_json.value("account_data"_ls)); result.room = - fromJson(_json.value("room")); + fromJson(_json.value("room"_ls)); return result; } diff --git a/lib/csapi/device_management.cpp b/lib/csapi/device_management.cpp index a4b2daae..bbc7e674 100644 --- a/lib/csapi/device_management.cpp +++ b/lib/csapi/device_management.cpp @@ -24,8 +24,10 @@ QUrl GetDevicesJob::makeRequestUrl(QUrl baseUrl) basePath % "/devices"); } +static const auto GetDevicesJobName = QStringLiteral("GetDevicesJob"); + GetDevicesJob::GetDevicesJob() - : BaseJob(HttpVerb::Get, "GetDevicesJob", + : BaseJob(HttpVerb::Get, GetDevicesJobName, basePath % "/devices") , d(new Private) { @@ -41,7 +43,7 @@ const QVector& GetDevicesJob::devices() const BaseJob::Status GetDevicesJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->devices = fromJson>(json.value("devices")); + d->devices = fromJson>(json.value("devices"_ls)); return Success; } @@ -57,8 +59,10 @@ QUrl GetDeviceJob::makeRequestUrl(QUrl baseUrl, const QString& deviceId) basePath % "/devices/" % deviceId); } +static const auto GetDeviceJobName = QStringLiteral("GetDeviceJob"); + GetDeviceJob::GetDeviceJob(const QString& deviceId) - : BaseJob(HttpVerb::Get, "GetDeviceJob", + : BaseJob(HttpVerb::Get, GetDeviceJobName, basePath % "/devices/" % deviceId) , d(new Private) { @@ -74,38 +78,44 @@ const Device& GetDeviceJob::data() const BaseJob::Status GetDeviceJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } +static const auto UpdateDeviceJobName = QStringLiteral("UpdateDeviceJob"); + UpdateDeviceJob::UpdateDeviceJob(const QString& deviceId, const QString& displayName) - : BaseJob(HttpVerb::Put, "UpdateDeviceJob", + : BaseJob(HttpVerb::Put, UpdateDeviceJobName, basePath % "/devices/" % deviceId) { QJsonObject _data; - addParam(_data, "display_name", displayName); + addParam(_data, QStringLiteral("display_name"), displayName); setRequestData(_data); } +static const auto DeleteDeviceJobName = QStringLiteral("DeleteDeviceJob"); + DeleteDeviceJob::DeleteDeviceJob(const QString& deviceId, const QJsonObject& auth) - : BaseJob(HttpVerb::Delete, "DeleteDeviceJob", + : BaseJob(HttpVerb::Delete, DeleteDeviceJobName, basePath % "/devices/" % deviceId) { QJsonObject _data; - addParam(_data, "auth", auth); + addParam(_data, QStringLiteral("auth"), auth); setRequestData(_data); } +static const auto DeleteDevicesJobName = QStringLiteral("DeleteDevicesJob"); + DeleteDevicesJob::DeleteDevicesJob(const QStringList& devices, const QJsonObject& auth) - : BaseJob(HttpVerb::Post, "DeleteDevicesJob", + : BaseJob(HttpVerb::Post, DeleteDevicesJobName, basePath % "/delete_devices") { QJsonObject _data; - addParam<>(_data, "devices", devices); - addParam(_data, "auth", auth); + addParam<>(_data, QStringLiteral("devices"), devices); + addParam(_data, QStringLiteral("auth"), auth); setRequestData(_data); } diff --git a/lib/csapi/directory.cpp b/lib/csapi/directory.cpp index 7e8b87b8..fd3b8839 100644 --- a/lib/csapi/directory.cpp +++ b/lib/csapi/directory.cpp @@ -12,12 +12,14 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0/directory"); +static const auto SetRoomAliasJobName = QStringLiteral("SetRoomAliasJob"); + SetRoomAliasJob::SetRoomAliasJob(const QString& roomAlias, const QString& roomId) - : BaseJob(HttpVerb::Put, "SetRoomAliasJob", + : BaseJob(HttpVerb::Put, SetRoomAliasJobName, basePath % "/room/" % roomAlias) { QJsonObject _data; - addParam(_data, "room_id", roomId); + addParam(_data, QStringLiteral("room_id"), roomId); setRequestData(_data); } @@ -34,8 +36,10 @@ QUrl GetRoomIdByAliasJob::makeRequestUrl(QUrl baseUrl, const QString& roomAlias) basePath % "/room/" % roomAlias); } +static const auto GetRoomIdByAliasJobName = QStringLiteral("GetRoomIdByAliasJob"); + GetRoomIdByAliasJob::GetRoomIdByAliasJob(const QString& roomAlias) - : BaseJob(HttpVerb::Get, "GetRoomIdByAliasJob", + : BaseJob(HttpVerb::Get, GetRoomIdByAliasJobName, basePath % "/room/" % roomAlias, false) , d(new Private) { @@ -56,8 +60,8 @@ const QStringList& GetRoomIdByAliasJob::servers() const BaseJob::Status GetRoomIdByAliasJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->roomId = fromJson(json.value("room_id")); - d->servers = fromJson(json.value("servers")); + d->roomId = fromJson(json.value("room_id"_ls)); + d->servers = fromJson(json.value("servers"_ls)); return Success; } @@ -67,8 +71,10 @@ QUrl DeleteRoomAliasJob::makeRequestUrl(QUrl baseUrl, const QString& roomAlias) basePath % "/room/" % roomAlias); } +static const auto DeleteRoomAliasJobName = QStringLiteral("DeleteRoomAliasJob"); + DeleteRoomAliasJob::DeleteRoomAliasJob(const QString& roomAlias) - : BaseJob(HttpVerb::Delete, "DeleteRoomAliasJob", + : BaseJob(HttpVerb::Delete, DeleteRoomAliasJobName, basePath % "/room/" % roomAlias) { } diff --git a/lib/csapi/event_context.cpp b/lib/csapi/event_context.cpp index 9e4c6963..806c1613 100644 --- a/lib/csapi/event_context.cpp +++ b/lib/csapi/event_context.cpp @@ -26,7 +26,7 @@ class GetEventContextJob::Private BaseJob::Query queryToGetEventContext(Omittable limit) { BaseJob::Query _q; - addParam(_q, "limit", limit); + addParam(_q, QStringLiteral("limit"), limit); return _q; } @@ -37,8 +37,10 @@ QUrl GetEventContextJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, con queryToGetEventContext(limit)); } +static const auto GetEventContextJobName = QStringLiteral("GetEventContextJob"); + GetEventContextJob::GetEventContextJob(const QString& roomId, const QString& eventId, Omittable limit) - : BaseJob(HttpVerb::Get, "GetEventContextJob", + : BaseJob(HttpVerb::Get, GetEventContextJobName, basePath % "/rooms/" % roomId % "/context/" % eventId, queryToGetEventContext(limit)) , d(new Private) @@ -80,12 +82,12 @@ StateEvents&& GetEventContextJob::state() BaseJob::Status GetEventContextJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->begin = fromJson(json.value("start")); - d->end = fromJson(json.value("end")); - d->eventsBefore = fromJson(json.value("events_before")); - d->event = fromJson(json.value("event")); - d->eventsAfter = fromJson(json.value("events_after")); - d->state = fromJson(json.value("state")); + d->begin = fromJson(json.value("start"_ls)); + d->end = fromJson(json.value("end"_ls)); + d->eventsBefore = fromJson(json.value("events_before"_ls)); + d->event = fromJson(json.value("event"_ls)); + d->eventsAfter = fromJson(json.value("events_after"_ls)); + d->state = fromJson(json.value("state"_ls)); return Success; } diff --git a/lib/csapi/filter.cpp b/lib/csapi/filter.cpp index a1546923..51056cc3 100644 --- a/lib/csapi/filter.cpp +++ b/lib/csapi/filter.cpp @@ -18,8 +18,10 @@ class DefineFilterJob::Private QString filterId; }; +static const auto DefineFilterJobName = QStringLiteral("DefineFilterJob"); + DefineFilterJob::DefineFilterJob(const QString& userId, const SyncFilter& filter) - : BaseJob(HttpVerb::Post, "DefineFilterJob", + : BaseJob(HttpVerb::Post, DefineFilterJobName, basePath % "/user/" % userId % "/filter") , d(new Private) { @@ -36,7 +38,7 @@ const QString& DefineFilterJob::filterId() const BaseJob::Status DefineFilterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->filterId = fromJson(json.value("filter_id")); + d->filterId = fromJson(json.value("filter_id"_ls)); return Success; } @@ -52,8 +54,10 @@ QUrl GetFilterJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const QSt basePath % "/user/" % userId % "/filter/" % filterId); } +static const auto GetFilterJobName = QStringLiteral("GetFilterJob"); + GetFilterJob::GetFilterJob(const QString& userId, const QString& filterId) - : BaseJob(HttpVerb::Get, "GetFilterJob", + : BaseJob(HttpVerb::Get, GetFilterJobName, basePath % "/user/" % userId % "/filter/" % filterId) , d(new Private) { @@ -69,10 +73,10 @@ const SyncFilter& GetFilterJob::data() const BaseJob::Status GetFilterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } diff --git a/lib/csapi/inviting.cpp b/lib/csapi/inviting.cpp index 94e0910b..7dc33b18 100644 --- a/lib/csapi/inviting.cpp +++ b/lib/csapi/inviting.cpp @@ -12,12 +12,14 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto InviteUserJobName = QStringLiteral("InviteUserJob"); + InviteUserJob::InviteUserJob(const QString& roomId, const QString& userId) - : BaseJob(HttpVerb::Post, "InviteUserJob", + : BaseJob(HttpVerb::Post, InviteUserJobName, basePath % "/rooms/" % roomId % "/invite") { QJsonObject _data; - addParam<>(_data, "user_id", userId); + addParam<>(_data, QStringLiteral("user_id"), userId); setRequestData(_data); } diff --git a/lib/csapi/joining.cpp b/lib/csapi/joining.cpp index f2d6fbf7..0a4618af 100644 --- a/lib/csapi/joining.cpp +++ b/lib/csapi/joining.cpp @@ -19,10 +19,10 @@ namespace QMatrixClient QJsonObject toJson(const JoinRoomByIdJob::ThirdPartySigned& pod) { QJsonObject _json; - addParam<>(_json, "sender", pod.sender); - addParam<>(_json, "mxid", pod.mxid); - addParam<>(_json, "token", pod.token); - addParam<>(_json, "signatures", pod.signatures); + addParam<>(_json, QStringLiteral("sender"), pod.sender); + addParam<>(_json, QStringLiteral("mxid"), pod.mxid); + addParam<>(_json, QStringLiteral("token"), pod.token); + addParam<>(_json, QStringLiteral("signatures"), pod.signatures); return _json; } } // namespace QMatrixClient @@ -33,13 +33,15 @@ class JoinRoomByIdJob::Private QString roomId; }; +static const auto JoinRoomByIdJobName = QStringLiteral("JoinRoomByIdJob"); + JoinRoomByIdJob::JoinRoomByIdJob(const QString& roomId, const Omittable& thirdPartySigned) - : BaseJob(HttpVerb::Post, "JoinRoomByIdJob", + : BaseJob(HttpVerb::Post, JoinRoomByIdJobName, basePath % "/rooms/" % roomId % "/join") , d(new Private) { QJsonObject _data; - addParam(_data, "third_party_signed", thirdPartySigned); + addParam(_data, QStringLiteral("third_party_signed"), thirdPartySigned); setRequestData(_data); } @@ -53,10 +55,10 @@ const QString& JoinRoomByIdJob::roomId() const BaseJob::Status JoinRoomByIdJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("room_id")) + if (!json.contains("room_id"_ls)) return { JsonParseError, "The key 'room_id' not found in the response" }; - d->roomId = fromJson(json.value("room_id")); + d->roomId = fromJson(json.value("room_id"_ls)); return Success; } @@ -67,17 +69,17 @@ namespace QMatrixClient QJsonObject toJson(const JoinRoomJob::Signed& pod) { QJsonObject _json; - addParam<>(_json, "sender", pod.sender); - addParam<>(_json, "mxid", pod.mxid); - addParam<>(_json, "token", pod.token); - addParam<>(_json, "signatures", pod.signatures); + addParam<>(_json, QStringLiteral("sender"), pod.sender); + addParam<>(_json, QStringLiteral("mxid"), pod.mxid); + addParam<>(_json, QStringLiteral("token"), pod.token); + addParam<>(_json, QStringLiteral("signatures"), pod.signatures); return _json; } QJsonObject toJson(const JoinRoomJob::ThirdPartySigned& pod) { QJsonObject _json; - addParam<>(_json, "signed", pod.signedData); + addParam<>(_json, QStringLiteral("signed"), pod.signedData); return _json; } } // namespace QMatrixClient @@ -88,13 +90,15 @@ class JoinRoomJob::Private QString roomId; }; +static const auto JoinRoomJobName = QStringLiteral("JoinRoomJob"); + JoinRoomJob::JoinRoomJob(const QString& roomIdOrAlias, const Omittable& thirdPartySigned) - : BaseJob(HttpVerb::Post, "JoinRoomJob", + : BaseJob(HttpVerb::Post, JoinRoomJobName, basePath % "/join/" % roomIdOrAlias) , d(new Private) { QJsonObject _data; - addParam(_data, "third_party_signed", thirdPartySigned); + addParam(_data, QStringLiteral("third_party_signed"), thirdPartySigned); setRequestData(_data); } @@ -108,10 +112,10 @@ const QString& JoinRoomJob::roomId() const BaseJob::Status JoinRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("room_id")) + if (!json.contains("room_id"_ls)) return { JsonParseError, "The key 'room_id' not found in the response" }; - d->roomId = fromJson(json.value("room_id")); + d->roomId = fromJson(json.value("room_id"_ls)); return Success; } diff --git a/lib/csapi/keys.cpp b/lib/csapi/keys.cpp index 4a76b7e2..fac811d0 100644 --- a/lib/csapi/keys.cpp +++ b/lib/csapi/keys.cpp @@ -18,14 +18,16 @@ class UploadKeysJob::Private QHash oneTimeKeyCounts; }; +static const auto UploadKeysJobName = QStringLiteral("UploadKeysJob"); + UploadKeysJob::UploadKeysJob(const Omittable& deviceKeys, const QHash& oneTimeKeys) - : BaseJob(HttpVerb::Post, "UploadKeysJob", + : BaseJob(HttpVerb::Post, UploadKeysJobName, basePath % "/keys/upload") , d(new Private) { QJsonObject _data; - addParam(_data, "device_keys", deviceKeys); - addParam(_data, "one_time_keys", oneTimeKeys); + addParam(_data, QStringLiteral("device_keys"), deviceKeys); + addParam(_data, QStringLiteral("one_time_keys"), oneTimeKeys); setRequestData(_data); } @@ -39,10 +41,10 @@ const QHash& UploadKeysJob::oneTimeKeyCounts() const BaseJob::Status UploadKeysJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("one_time_key_counts")) + if (!json.contains("one_time_key_counts"_ls)) return { JsonParseError, "The key 'one_time_key_counts' not found in the response" }; - d->oneTimeKeyCounts = fromJson>(json.value("one_time_key_counts")); + d->oneTimeKeyCounts = fromJson>(json.value("one_time_key_counts"_ls)); return Success; } @@ -57,7 +59,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); QueryKeysJob::UnsignedDeviceInfo result; result.deviceDisplayName = - fromJson(_json.value("device_display_name")); + fromJson(_json.value("device_display_name"_ls)); return result; } @@ -70,7 +72,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); QueryKeysJob::DeviceInformation result; result.unsignedData = - fromJson(_json.value("unsigned")); + fromJson(_json.value("unsigned"_ls)); return result; } @@ -84,15 +86,17 @@ class QueryKeysJob::Private QHash> deviceKeys; }; +static const auto QueryKeysJobName = QStringLiteral("QueryKeysJob"); + QueryKeysJob::QueryKeysJob(const QHash& deviceKeys, Omittable timeout, const QString& token) - : BaseJob(HttpVerb::Post, "QueryKeysJob", + : BaseJob(HttpVerb::Post, QueryKeysJobName, basePath % "/keys/query") , d(new Private) { QJsonObject _data; - addParam(_data, "timeout", timeout); - addParam<>(_data, "device_keys", deviceKeys); - addParam(_data, "token", token); + addParam(_data, QStringLiteral("timeout"), timeout); + addParam<>(_data, QStringLiteral("device_keys"), deviceKeys); + addParam(_data, QStringLiteral("token"), token); setRequestData(_data); } @@ -111,8 +115,8 @@ const QHash>& QueryKeys BaseJob::Status QueryKeysJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->failures = fromJson>(json.value("failures")); - d->deviceKeys = fromJson>>(json.value("device_keys")); + d->failures = fromJson>(json.value("failures"_ls)); + d->deviceKeys = fromJson>>(json.value("device_keys"_ls)); return Success; } @@ -123,14 +127,16 @@ class ClaimKeysJob::Private QHash> oneTimeKeys; }; +static const auto ClaimKeysJobName = QStringLiteral("ClaimKeysJob"); + ClaimKeysJob::ClaimKeysJob(const QHash>& oneTimeKeys, Omittable timeout) - : BaseJob(HttpVerb::Post, "ClaimKeysJob", + : BaseJob(HttpVerb::Post, ClaimKeysJobName, basePath % "/keys/claim") , d(new Private) { QJsonObject _data; - addParam(_data, "timeout", timeout); - addParam<>(_data, "one_time_keys", oneTimeKeys); + addParam(_data, QStringLiteral("timeout"), timeout); + addParam<>(_data, QStringLiteral("one_time_keys"), oneTimeKeys); setRequestData(_data); } @@ -149,8 +155,8 @@ const QHash>& ClaimKeysJob::oneTimeKeys() cons BaseJob::Status ClaimKeysJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->failures = fromJson>(json.value("failures")); - d->oneTimeKeys = fromJson>>(json.value("one_time_keys")); + d->failures = fromJson>(json.value("failures"_ls)); + d->oneTimeKeys = fromJson>>(json.value("one_time_keys"_ls)); return Success; } @@ -164,8 +170,8 @@ class GetKeysChangesJob::Private BaseJob::Query queryToGetKeysChanges(const QString& from, const QString& to) { BaseJob::Query _q; - addParam<>(_q, "from", from); - addParam<>(_q, "to", to); + addParam<>(_q, QStringLiteral("from"), from); + addParam<>(_q, QStringLiteral("to"), to); return _q; } @@ -176,8 +182,10 @@ QUrl GetKeysChangesJob::makeRequestUrl(QUrl baseUrl, const QString& from, const queryToGetKeysChanges(from, to)); } +static const auto GetKeysChangesJobName = QStringLiteral("GetKeysChangesJob"); + GetKeysChangesJob::GetKeysChangesJob(const QString& from, const QString& to) - : BaseJob(HttpVerb::Get, "GetKeysChangesJob", + : BaseJob(HttpVerb::Get, GetKeysChangesJobName, basePath % "/keys/changes", queryToGetKeysChanges(from, to)) , d(new Private) @@ -199,8 +207,8 @@ const QStringList& GetKeysChangesJob::left() const BaseJob::Status GetKeysChangesJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->changed = fromJson(json.value("changed")); - d->left = fromJson(json.value("left")); + d->changed = fromJson(json.value("changed"_ls)); + d->left = fromJson(json.value("left"_ls)); return Success; } diff --git a/lib/csapi/kicking.cpp b/lib/csapi/kicking.cpp index 73ef70ae..1d6d5543 100644 --- a/lib/csapi/kicking.cpp +++ b/lib/csapi/kicking.cpp @@ -12,13 +12,15 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto KickJobName = QStringLiteral("KickJob"); + KickJob::KickJob(const QString& roomId, const QString& userId, const QString& reason) - : BaseJob(HttpVerb::Post, "KickJob", + : BaseJob(HttpVerb::Post, KickJobName, basePath % "/rooms/" % roomId % "/kick") { QJsonObject _data; - addParam<>(_data, "user_id", userId); - addParam(_data, "reason", reason); + addParam<>(_data, QStringLiteral("user_id"), userId); + addParam(_data, QStringLiteral("reason"), reason); setRequestData(_data); } diff --git a/lib/csapi/leaving.cpp b/lib/csapi/leaving.cpp index afc4adbd..09e5f83b 100644 --- a/lib/csapi/leaving.cpp +++ b/lib/csapi/leaving.cpp @@ -18,8 +18,10 @@ QUrl LeaveRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId) basePath % "/rooms/" % roomId % "/leave"); } +static const auto LeaveRoomJobName = QStringLiteral("LeaveRoomJob"); + LeaveRoomJob::LeaveRoomJob(const QString& roomId) - : BaseJob(HttpVerb::Post, "LeaveRoomJob", + : BaseJob(HttpVerb::Post, LeaveRoomJobName, basePath % "/rooms/" % roomId % "/leave") { } @@ -30,8 +32,10 @@ QUrl ForgetRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId) basePath % "/rooms/" % roomId % "/forget"); } +static const auto ForgetRoomJobName = QStringLiteral("ForgetRoomJob"); + ForgetRoomJob::ForgetRoomJob(const QString& roomId) - : BaseJob(HttpVerb::Post, "ForgetRoomJob", + : BaseJob(HttpVerb::Post, ForgetRoomJobName, basePath % "/rooms/" % roomId % "/forget") { } diff --git a/lib/csapi/list_joined_rooms.cpp b/lib/csapi/list_joined_rooms.cpp index 82ec8849..a745dba1 100644 --- a/lib/csapi/list_joined_rooms.cpp +++ b/lib/csapi/list_joined_rooms.cpp @@ -24,8 +24,10 @@ QUrl GetJoinedRoomsJob::makeRequestUrl(QUrl baseUrl) basePath % "/joined_rooms"); } +static const auto GetJoinedRoomsJobName = QStringLiteral("GetJoinedRoomsJob"); + GetJoinedRoomsJob::GetJoinedRoomsJob() - : BaseJob(HttpVerb::Get, "GetJoinedRoomsJob", + : BaseJob(HttpVerb::Get, GetJoinedRoomsJobName, basePath % "/joined_rooms") , d(new Private) { @@ -41,10 +43,10 @@ const QStringList& GetJoinedRoomsJob::joinedRooms() const BaseJob::Status GetJoinedRoomsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("joined_rooms")) + if (!json.contains("joined_rooms"_ls)) return { JsonParseError, "The key 'joined_rooms' not found in the response" }; - d->joinedRooms = fromJson(json.value("joined_rooms")); + d->joinedRooms = fromJson(json.value("joined_rooms"_ls)); return Success; } diff --git a/lib/csapi/list_public_rooms.cpp b/lib/csapi/list_public_rooms.cpp index 5d605bbb..c34af34c 100644 --- a/lib/csapi/list_public_rooms.cpp +++ b/lib/csapi/list_public_rooms.cpp @@ -24,8 +24,10 @@ QUrl GetRoomVisibilityOnDirectoryJob::makeRequestUrl(QUrl baseUrl, const QString basePath % "/directory/list/room/" % roomId); } +static const auto GetRoomVisibilityOnDirectoryJobName = QStringLiteral("GetRoomVisibilityOnDirectoryJob"); + GetRoomVisibilityOnDirectoryJob::GetRoomVisibilityOnDirectoryJob(const QString& roomId) - : BaseJob(HttpVerb::Get, "GetRoomVisibilityOnDirectoryJob", + : BaseJob(HttpVerb::Get, GetRoomVisibilityOnDirectoryJobName, basePath % "/directory/list/room/" % roomId, false) , d(new Private) { @@ -41,16 +43,18 @@ const QString& GetRoomVisibilityOnDirectoryJob::visibility() const BaseJob::Status GetRoomVisibilityOnDirectoryJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->visibility = fromJson(json.value("visibility")); + d->visibility = fromJson(json.value("visibility"_ls)); return Success; } +static const auto SetRoomVisibilityOnDirectoryJobName = QStringLiteral("SetRoomVisibilityOnDirectoryJob"); + SetRoomVisibilityOnDirectoryJob::SetRoomVisibilityOnDirectoryJob(const QString& roomId, const QString& visibility) - : BaseJob(HttpVerb::Put, "SetRoomVisibilityOnDirectoryJob", + : BaseJob(HttpVerb::Put, SetRoomVisibilityOnDirectoryJobName, basePath % "/directory/list/room/" % roomId) { QJsonObject _data; - addParam(_data, "visibility", visibility); + addParam(_data, QStringLiteral("visibility"), visibility); setRequestData(_data); } @@ -65,23 +69,23 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetPublicRoomsJob::PublicRoomsChunk result; result.aliases = - fromJson(_json.value("aliases")); + fromJson(_json.value("aliases"_ls)); result.canonicalAlias = - fromJson(_json.value("canonical_alias")); + fromJson(_json.value("canonical_alias"_ls)); result.name = - fromJson(_json.value("name")); + fromJson(_json.value("name"_ls)); result.numJoinedMembers = - fromJson(_json.value("num_joined_members")); + fromJson(_json.value("num_joined_members"_ls)); result.roomId = - fromJson(_json.value("room_id")); + fromJson(_json.value("room_id"_ls)); result.topic = - fromJson(_json.value("topic")); + fromJson(_json.value("topic"_ls)); result.worldReadable = - fromJson(_json.value("world_readable")); + fromJson(_json.value("world_readable"_ls)); result.guestCanJoin = - fromJson(_json.value("guest_can_join")); + fromJson(_json.value("guest_can_join"_ls)); result.avatarUrl = - fromJson(_json.value("avatar_url")); + fromJson(_json.value("avatar_url"_ls)); return result; } @@ -100,9 +104,9 @@ class GetPublicRoomsJob::Private BaseJob::Query queryToGetPublicRooms(Omittable limit, const QString& since, const QString& server) { BaseJob::Query _q; - addParam(_q, "limit", limit); - addParam(_q, "since", since); - addParam(_q, "server", server); + addParam(_q, QStringLiteral("limit"), limit); + addParam(_q, QStringLiteral("since"), since); + addParam(_q, QStringLiteral("server"), server); return _q; } @@ -113,8 +117,10 @@ QUrl GetPublicRoomsJob::makeRequestUrl(QUrl baseUrl, Omittable limit, const queryToGetPublicRooms(limit, since, server)); } +static const auto GetPublicRoomsJobName = QStringLiteral("GetPublicRoomsJob"); + GetPublicRoomsJob::GetPublicRoomsJob(Omittable limit, const QString& since, const QString& server) - : BaseJob(HttpVerb::Get, "GetPublicRoomsJob", + : BaseJob(HttpVerb::Get, GetPublicRoomsJobName, basePath % "/publicRooms", queryToGetPublicRooms(limit, since, server), {}, false) @@ -147,13 +153,13 @@ Omittable GetPublicRoomsJob::totalRoomCountEstimate() const BaseJob::Status GetPublicRoomsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("chunk")) + if (!json.contains("chunk"_ls)) return { JsonParseError, "The key 'chunk' not found in the response" }; - d->chunk = fromJson>(json.value("chunk")); - d->nextBatch = fromJson(json.value("next_batch")); - d->prevBatch = fromJson(json.value("prev_batch")); - d->totalRoomCountEstimate = fromJson(json.value("total_room_count_estimate")); + d->chunk = fromJson>(json.value("chunk"_ls)); + d->nextBatch = fromJson(json.value("next_batch"_ls)); + d->prevBatch = fromJson(json.value("prev_batch"_ls)); + d->totalRoomCountEstimate = fromJson(json.value("total_room_count_estimate"_ls)); return Success; } @@ -164,7 +170,7 @@ namespace QMatrixClient QJsonObject toJson(const QueryPublicRoomsJob::Filter& pod) { QJsonObject _json; - addParam(_json, "generic_search_term", pod.genericSearchTerm); + addParam(_json, QStringLiteral("generic_search_term"), pod.genericSearchTerm); return _json; } @@ -175,23 +181,23 @@ namespace QMatrixClient const auto& _json = jv.toObject(); QueryPublicRoomsJob::PublicRoomsChunk result; result.aliases = - fromJson(_json.value("aliases")); + fromJson(_json.value("aliases"_ls)); result.canonicalAlias = - fromJson(_json.value("canonical_alias")); + fromJson(_json.value("canonical_alias"_ls)); result.name = - fromJson(_json.value("name")); + fromJson(_json.value("name"_ls)); result.numJoinedMembers = - fromJson(_json.value("num_joined_members")); + fromJson(_json.value("num_joined_members"_ls)); result.roomId = - fromJson(_json.value("room_id")); + fromJson(_json.value("room_id"_ls)); result.topic = - fromJson(_json.value("topic")); + fromJson(_json.value("topic"_ls)); result.worldReadable = - fromJson(_json.value("world_readable")); + fromJson(_json.value("world_readable"_ls)); result.guestCanJoin = - fromJson(_json.value("guest_can_join")); + fromJson(_json.value("guest_can_join"_ls)); result.avatarUrl = - fromJson(_json.value("avatar_url")); + fromJson(_json.value("avatar_url"_ls)); return result; } @@ -210,20 +216,22 @@ class QueryPublicRoomsJob::Private BaseJob::Query queryToQueryPublicRooms(const QString& server) { BaseJob::Query _q; - addParam(_q, "server", server); + addParam(_q, QStringLiteral("server"), server); return _q; } +static const auto QueryPublicRoomsJobName = QStringLiteral("QueryPublicRoomsJob"); + QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable limit, const QString& since, const Omittable& filter) - : BaseJob(HttpVerb::Post, "QueryPublicRoomsJob", + : BaseJob(HttpVerb::Post, QueryPublicRoomsJobName, basePath % "/publicRooms", queryToQueryPublicRooms(server)) , d(new Private) { QJsonObject _data; - addParam(_data, "limit", limit); - addParam(_data, "since", since); - addParam(_data, "filter", filter); + addParam(_data, QStringLiteral("limit"), limit); + addParam(_data, QStringLiteral("since"), since); + addParam(_data, QStringLiteral("filter"), filter); setRequestData(_data); } @@ -252,13 +260,13 @@ Omittable QueryPublicRoomsJob::totalRoomCountEstimate() const BaseJob::Status QueryPublicRoomsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("chunk")) + if (!json.contains("chunk"_ls)) return { JsonParseError, "The key 'chunk' not found in the response" }; - d->chunk = fromJson>(json.value("chunk")); - d->nextBatch = fromJson(json.value("next_batch")); - d->prevBatch = fromJson(json.value("prev_batch")); - d->totalRoomCountEstimate = fromJson(json.value("total_room_count_estimate")); + d->chunk = fromJson>(json.value("chunk"_ls)); + d->nextBatch = fromJson(json.value("next_batch"_ls)); + d->prevBatch = fromJson(json.value("prev_batch"_ls)); + d->totalRoomCountEstimate = fromJson(json.value("total_room_count_estimate"_ls)); return Success; } diff --git a/lib/csapi/login.cpp b/lib/csapi/login.cpp index e0795f8a..b8734d05 100644 --- a/lib/csapi/login.cpp +++ b/lib/csapi/login.cpp @@ -21,20 +21,22 @@ class LoginJob::Private QString deviceId; }; +static const auto LoginJobName = QStringLiteral("LoginJob"); + LoginJob::LoginJob(const QString& type, const QString& user, const QString& medium, const QString& address, const QString& password, const QString& token, const QString& deviceId, const QString& initialDeviceDisplayName) - : BaseJob(HttpVerb::Post, "LoginJob", + : BaseJob(HttpVerb::Post, LoginJobName, basePath % "/login", false) , d(new Private) { QJsonObject _data; - addParam<>(_data, "type", type); - addParam(_data, "user", user); - addParam(_data, "medium", medium); - addParam(_data, "address", address); - addParam(_data, "password", password); - addParam(_data, "token", token); - addParam(_data, "device_id", deviceId); - addParam(_data, "initial_device_display_name", initialDeviceDisplayName); + addParam<>(_data, QStringLiteral("type"), type); + addParam(_data, QStringLiteral("user"), user); + addParam(_data, QStringLiteral("medium"), medium); + addParam(_data, QStringLiteral("address"), address); + addParam(_data, QStringLiteral("password"), password); + addParam(_data, QStringLiteral("token"), token); + addParam(_data, QStringLiteral("device_id"), deviceId); + addParam(_data, QStringLiteral("initial_device_display_name"), initialDeviceDisplayName); setRequestData(_data); } @@ -63,10 +65,10 @@ const QString& LoginJob::deviceId() const BaseJob::Status LoginJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->userId = fromJson(json.value("user_id")); - d->accessToken = fromJson(json.value("access_token")); - d->homeServer = fromJson(json.value("home_server")); - d->deviceId = fromJson(json.value("device_id")); + d->userId = fromJson(json.value("user_id"_ls)); + d->accessToken = fromJson(json.value("access_token"_ls)); + d->homeServer = fromJson(json.value("home_server"_ls)); + d->deviceId = fromJson(json.value("device_id"_ls)); return Success; } diff --git a/lib/csapi/logout.cpp b/lib/csapi/logout.cpp index 42f99bbc..6e209e07 100644 --- a/lib/csapi/logout.cpp +++ b/lib/csapi/logout.cpp @@ -18,8 +18,10 @@ QUrl LogoutJob::makeRequestUrl(QUrl baseUrl) basePath % "/logout"); } +static const auto LogoutJobName = QStringLiteral("LogoutJob"); + LogoutJob::LogoutJob() - : BaseJob(HttpVerb::Post, "LogoutJob", + : BaseJob(HttpVerb::Post, LogoutJobName, basePath % "/logout") { } @@ -30,8 +32,10 @@ QUrl LogoutAllJob::makeRequestUrl(QUrl baseUrl) basePath % "/logout/all"); } +static const auto LogoutAllJobName = QStringLiteral("LogoutAllJob"); + LogoutAllJob::LogoutAllJob() - : BaseJob(HttpVerb::Post, "LogoutAllJob", + : BaseJob(HttpVerb::Post, LogoutAllJobName, basePath % "/logout/all") { } diff --git a/lib/csapi/message_pagination.cpp b/lib/csapi/message_pagination.cpp index 1eb2aa07..c59a51ab 100644 --- a/lib/csapi/message_pagination.cpp +++ b/lib/csapi/message_pagination.cpp @@ -23,11 +23,11 @@ class GetRoomEventsJob::Private BaseJob::Query queryToGetRoomEvents(const QString& from, const QString& to, const QString& dir, Omittable limit, const QString& filter) { BaseJob::Query _q; - addParam<>(_q, "from", from); - addParam(_q, "to", to); - addParam<>(_q, "dir", dir); - addParam(_q, "limit", limit); - addParam(_q, "filter", filter); + addParam<>(_q, QStringLiteral("from"), from); + addParam(_q, QStringLiteral("to"), to); + addParam<>(_q, QStringLiteral("dir"), dir); + addParam(_q, QStringLiteral("limit"), limit); + addParam(_q, QStringLiteral("filter"), filter); return _q; } @@ -38,8 +38,10 @@ QUrl GetRoomEventsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, const queryToGetRoomEvents(from, to, dir, limit, filter)); } +static const auto GetRoomEventsJobName = QStringLiteral("GetRoomEventsJob"); + GetRoomEventsJob::GetRoomEventsJob(const QString& roomId, const QString& from, const QString& dir, const QString& to, Omittable limit, const QString& filter) - : BaseJob(HttpVerb::Get, "GetRoomEventsJob", + : BaseJob(HttpVerb::Get, GetRoomEventsJobName, basePath % "/rooms/" % roomId % "/messages", queryToGetRoomEvents(from, to, dir, limit, filter)) , d(new Private) @@ -66,9 +68,9 @@ RoomEvents&& GetRoomEventsJob::chunk() BaseJob::Status GetRoomEventsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->begin = fromJson(json.value("start")); - d->end = fromJson(json.value("end")); - d->chunk = fromJson(json.value("chunk")); + d->begin = fromJson(json.value("start"_ls)); + d->end = fromJson(json.value("end"_ls)); + d->chunk = fromJson(json.value("chunk"_ls)); return Success; } diff --git a/lib/csapi/notifications.cpp b/lib/csapi/notifications.cpp index 39570991..f98cddd2 100644 --- a/lib/csapi/notifications.cpp +++ b/lib/csapi/notifications.cpp @@ -23,17 +23,17 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetNotificationsJob::Notification result; result.actions = - fromJson>(_json.value("actions")); + fromJson>(_json.value("actions"_ls)); result.event = - fromJson(_json.value("event")); + fromJson(_json.value("event"_ls)); result.profileTag = - fromJson(_json.value("profile_tag")); + fromJson(_json.value("profile_tag"_ls)); result.read = - fromJson(_json.value("read")); + fromJson(_json.value("read"_ls)); result.roomId = - fromJson(_json.value("room_id")); + fromJson(_json.value("room_id"_ls)); result.ts = - fromJson(_json.value("ts")); + fromJson(_json.value("ts"_ls)); return result; } @@ -50,9 +50,9 @@ class GetNotificationsJob::Private BaseJob::Query queryToGetNotifications(const QString& from, Omittable limit, const QString& only) { BaseJob::Query _q; - addParam(_q, "from", from); - addParam(_q, "limit", limit); - addParam(_q, "only", only); + addParam(_q, QStringLiteral("from"), from); + addParam(_q, QStringLiteral("limit"), limit); + addParam(_q, QStringLiteral("only"), only); return _q; } @@ -63,8 +63,10 @@ QUrl GetNotificationsJob::makeRequestUrl(QUrl baseUrl, const QString& from, Omit queryToGetNotifications(from, limit, only)); } +static const auto GetNotificationsJobName = QStringLiteral("GetNotificationsJob"); + GetNotificationsJob::GetNotificationsJob(const QString& from, Omittable limit, const QString& only) - : BaseJob(HttpVerb::Get, "GetNotificationsJob", + : BaseJob(HttpVerb::Get, GetNotificationsJobName, basePath % "/notifications", queryToGetNotifications(from, limit, only)) , d(new Private) @@ -86,11 +88,11 @@ std::vector&& GetNotificationsJob::notificati BaseJob::Status GetNotificationsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->nextToken = fromJson(json.value("next_token")); - if (!json.contains("notifications")) + d->nextToken = fromJson(json.value("next_token"_ls)); + if (!json.contains("notifications"_ls)) return { JsonParseError, "The key 'notifications' not found in the response" }; - d->notifications = fromJson>(json.value("notifications")); + d->notifications = fromJson>(json.value("notifications"_ls)); return Success; } diff --git a/lib/csapi/peeking_events.cpp b/lib/csapi/peeking_events.cpp index b3be7631..e046a62e 100644 --- a/lib/csapi/peeking_events.cpp +++ b/lib/csapi/peeking_events.cpp @@ -23,9 +23,9 @@ class PeekEventsJob::Private BaseJob::Query queryToPeekEvents(const QString& from, Omittable timeout, const QString& roomId) { BaseJob::Query _q; - addParam(_q, "from", from); - addParam(_q, "timeout", timeout); - addParam(_q, "room_id", roomId); + addParam(_q, QStringLiteral("from"), from); + addParam(_q, QStringLiteral("timeout"), timeout); + addParam(_q, QStringLiteral("room_id"), roomId); return _q; } @@ -36,8 +36,10 @@ QUrl PeekEventsJob::makeRequestUrl(QUrl baseUrl, const QString& from, Omittable< queryToPeekEvents(from, timeout, roomId)); } +static const auto PeekEventsJobName = QStringLiteral("PeekEventsJob"); + PeekEventsJob::PeekEventsJob(const QString& from, Omittable timeout, const QString& roomId) - : BaseJob(HttpVerb::Get, "PeekEventsJob", + : BaseJob(HttpVerb::Get, PeekEventsJobName, basePath % "/events", queryToPeekEvents(from, timeout, roomId)) , d(new Private) @@ -64,9 +66,9 @@ RoomEvents&& PeekEventsJob::chunk() BaseJob::Status PeekEventsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->begin = fromJson(json.value("start")); - d->end = fromJson(json.value("end")); - d->chunk = fromJson(json.value("chunk")); + d->begin = fromJson(json.value("start"_ls)); + d->end = fromJson(json.value("end"_ls)); + d->chunk = fromJson(json.value("chunk"_ls)); return Success; } diff --git a/lib/csapi/presence.cpp b/lib/csapi/presence.cpp index 35b2c960..66827163 100644 --- a/lib/csapi/presence.cpp +++ b/lib/csapi/presence.cpp @@ -12,13 +12,15 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto SetPresenceJobName = QStringLiteral("SetPresenceJob"); + SetPresenceJob::SetPresenceJob(const QString& userId, const QString& presence, const QString& statusMsg) - : BaseJob(HttpVerb::Put, "SetPresenceJob", + : BaseJob(HttpVerb::Put, SetPresenceJobName, basePath % "/presence/" % userId % "/status") { QJsonObject _data; - addParam<>(_data, "presence", presence); - addParam(_data, "status_msg", statusMsg); + addParam<>(_data, QStringLiteral("presence"), presence); + addParam(_data, QStringLiteral("status_msg"), statusMsg); setRequestData(_data); } @@ -37,8 +39,10 @@ QUrl GetPresenceJob::makeRequestUrl(QUrl baseUrl, const QString& userId) basePath % "/presence/" % userId % "/status"); } +static const auto GetPresenceJobName = QStringLiteral("GetPresenceJob"); + GetPresenceJob::GetPresenceJob(const QString& userId) - : BaseJob(HttpVerb::Get, "GetPresenceJob", + : BaseJob(HttpVerb::Get, GetPresenceJobName, basePath % "/presence/" % userId % "/status", false) , d(new Private) { @@ -69,23 +73,25 @@ bool GetPresenceJob::currentlyActive() const BaseJob::Status GetPresenceJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("presence")) + if (!json.contains("presence"_ls)) return { JsonParseError, "The key 'presence' not found in the response" }; - d->presence = fromJson(json.value("presence")); - d->lastActiveAgo = fromJson(json.value("last_active_ago")); - d->statusMsg = fromJson(json.value("status_msg")); - d->currentlyActive = fromJson(json.value("currently_active")); + d->presence = fromJson(json.value("presence"_ls)); + d->lastActiveAgo = fromJson(json.value("last_active_ago"_ls)); + d->statusMsg = fromJson(json.value("status_msg"_ls)); + d->currentlyActive = fromJson(json.value("currently_active"_ls)); return Success; } +static const auto ModifyPresenceListJobName = QStringLiteral("ModifyPresenceListJob"); + ModifyPresenceListJob::ModifyPresenceListJob(const QString& userId, const QStringList& invite, const QStringList& drop) - : BaseJob(HttpVerb::Post, "ModifyPresenceListJob", + : BaseJob(HttpVerb::Post, ModifyPresenceListJobName, basePath % "/presence/list/" % userId) { QJsonObject _data; - addParam(_data, "invite", invite); - addParam(_data, "drop", drop); + addParam(_data, QStringLiteral("invite"), invite); + addParam(_data, QStringLiteral("drop"), drop); setRequestData(_data); } @@ -101,8 +107,10 @@ QUrl GetPresenceForListJob::makeRequestUrl(QUrl baseUrl, const QString& userId) basePath % "/presence/list/" % userId); } +static const auto GetPresenceForListJobName = QStringLiteral("GetPresenceForListJob"); + GetPresenceForListJob::GetPresenceForListJob(const QString& userId) - : BaseJob(HttpVerb::Get, "GetPresenceForListJob", + : BaseJob(HttpVerb::Get, GetPresenceForListJobName, basePath % "/presence/list/" % userId, false) , d(new Private) { @@ -118,10 +126,10 @@ Events&& GetPresenceForListJob::data() BaseJob::Status GetPresenceForListJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } diff --git a/lib/csapi/profile.cpp b/lib/csapi/profile.cpp index b08eb970..bb053062 100644 --- a/lib/csapi/profile.cpp +++ b/lib/csapi/profile.cpp @@ -12,12 +12,14 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto SetDisplayNameJobName = QStringLiteral("SetDisplayNameJob"); + SetDisplayNameJob::SetDisplayNameJob(const QString& userId, const QString& displayname) - : BaseJob(HttpVerb::Put, "SetDisplayNameJob", + : BaseJob(HttpVerb::Put, SetDisplayNameJobName, basePath % "/profile/" % userId % "/displayname") { QJsonObject _data; - addParam(_data, "displayname", displayname); + addParam(_data, QStringLiteral("displayname"), displayname); setRequestData(_data); } @@ -33,8 +35,10 @@ QUrl GetDisplayNameJob::makeRequestUrl(QUrl baseUrl, const QString& userId) basePath % "/profile/" % userId % "/displayname"); } +static const auto GetDisplayNameJobName = QStringLiteral("GetDisplayNameJob"); + GetDisplayNameJob::GetDisplayNameJob(const QString& userId) - : BaseJob(HttpVerb::Get, "GetDisplayNameJob", + : BaseJob(HttpVerb::Get, GetDisplayNameJobName, basePath % "/profile/" % userId % "/displayname", false) , d(new Private) { @@ -50,16 +54,18 @@ const QString& GetDisplayNameJob::displayname() const BaseJob::Status GetDisplayNameJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->displayname = fromJson(json.value("displayname")); + d->displayname = fromJson(json.value("displayname"_ls)); return Success; } +static const auto SetAvatarUrlJobName = QStringLiteral("SetAvatarUrlJob"); + SetAvatarUrlJob::SetAvatarUrlJob(const QString& userId, const QString& avatarUrl) - : BaseJob(HttpVerb::Put, "SetAvatarUrlJob", + : BaseJob(HttpVerb::Put, SetAvatarUrlJobName, basePath % "/profile/" % userId % "/avatar_url") { QJsonObject _data; - addParam(_data, "avatar_url", avatarUrl); + addParam(_data, QStringLiteral("avatar_url"), avatarUrl); setRequestData(_data); } @@ -75,8 +81,10 @@ QUrl GetAvatarUrlJob::makeRequestUrl(QUrl baseUrl, const QString& userId) basePath % "/profile/" % userId % "/avatar_url"); } +static const auto GetAvatarUrlJobName = QStringLiteral("GetAvatarUrlJob"); + GetAvatarUrlJob::GetAvatarUrlJob(const QString& userId) - : BaseJob(HttpVerb::Get, "GetAvatarUrlJob", + : BaseJob(HttpVerb::Get, GetAvatarUrlJobName, basePath % "/profile/" % userId % "/avatar_url", false) , d(new Private) { @@ -92,7 +100,7 @@ const QString& GetAvatarUrlJob::avatarUrl() const BaseJob::Status GetAvatarUrlJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->avatarUrl = fromJson(json.value("avatar_url")); + d->avatarUrl = fromJson(json.value("avatar_url"_ls)); return Success; } @@ -109,8 +117,10 @@ QUrl GetUserProfileJob::makeRequestUrl(QUrl baseUrl, const QString& userId) basePath % "/profile/" % userId); } +static const auto GetUserProfileJobName = QStringLiteral("GetUserProfileJob"); + GetUserProfileJob::GetUserProfileJob(const QString& userId) - : BaseJob(HttpVerb::Get, "GetUserProfileJob", + : BaseJob(HttpVerb::Get, GetUserProfileJobName, basePath % "/profile/" % userId, false) , d(new Private) { @@ -131,8 +141,8 @@ const QString& GetUserProfileJob::displayname() const BaseJob::Status GetUserProfileJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->avatarUrl = fromJson(json.value("avatar_url")); - d->displayname = fromJson(json.value("displayname")); + d->avatarUrl = fromJson(json.value("avatar_url"_ls)); + d->displayname = fromJson(json.value("displayname"_ls)); return Success; } diff --git a/lib/csapi/pusher.cpp b/lib/csapi/pusher.cpp index 1a43900b..feecdbc7 100644 --- a/lib/csapi/pusher.cpp +++ b/lib/csapi/pusher.cpp @@ -23,7 +23,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetPushersJob::PusherData result; result.url = - fromJson(_json.value("url")); + fromJson(_json.value("url"_ls)); return result; } @@ -36,21 +36,21 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetPushersJob::Pusher result; result.pushkey = - fromJson(_json.value("pushkey")); + fromJson(_json.value("pushkey"_ls)); result.kind = - fromJson(_json.value("kind")); + fromJson(_json.value("kind"_ls)); result.appId = - fromJson(_json.value("app_id")); + fromJson(_json.value("app_id"_ls)); result.appDisplayName = - fromJson(_json.value("app_display_name")); + fromJson(_json.value("app_display_name"_ls)); result.deviceDisplayName = - fromJson(_json.value("device_display_name")); + fromJson(_json.value("device_display_name"_ls)); result.profileTag = - fromJson(_json.value("profile_tag")); + fromJson(_json.value("profile_tag"_ls)); result.lang = - fromJson(_json.value("lang")); + fromJson(_json.value("lang"_ls)); result.data = - fromJson(_json.value("data")); + fromJson(_json.value("data"_ls)); return result; } @@ -69,8 +69,10 @@ QUrl GetPushersJob::makeRequestUrl(QUrl baseUrl) basePath % "/pushers"); } +static const auto GetPushersJobName = QStringLiteral("GetPushersJob"); + GetPushersJob::GetPushersJob() - : BaseJob(HttpVerb::Get, "GetPushersJob", + : BaseJob(HttpVerb::Get, GetPushersJobName, basePath % "/pushers") , d(new Private) { @@ -86,7 +88,7 @@ const QVector& GetPushersJob::pushers() const BaseJob::Status GetPushersJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->pushers = fromJson>(json.value("pushers")); + d->pushers = fromJson>(json.value("pushers"_ls)); return Success; } @@ -97,25 +99,27 @@ namespace QMatrixClient QJsonObject toJson(const PostPusherJob::PusherData& pod) { QJsonObject _json; - addParam(_json, "url", pod.url); + addParam(_json, QStringLiteral("url"), pod.url); return _json; } } // namespace QMatrixClient +static const auto PostPusherJobName = QStringLiteral("PostPusherJob"); + PostPusherJob::PostPusherJob(const QString& pushkey, const QString& kind, const QString& appId, const QString& appDisplayName, const QString& deviceDisplayName, const QString& lang, const PusherData& data, const QString& profileTag, bool append) - : BaseJob(HttpVerb::Post, "PostPusherJob", + : BaseJob(HttpVerb::Post, PostPusherJobName, basePath % "/pushers/set") { QJsonObject _data; - addParam<>(_data, "pushkey", pushkey); - addParam<>(_data, "kind", kind); - addParam<>(_data, "app_id", appId); - addParam<>(_data, "app_display_name", appDisplayName); - addParam<>(_data, "device_display_name", deviceDisplayName); - addParam(_data, "profile_tag", profileTag); - addParam<>(_data, "lang", lang); - addParam<>(_data, "data", data); - addParam(_data, "append", append); + addParam<>(_data, QStringLiteral("pushkey"), pushkey); + addParam<>(_data, QStringLiteral("kind"), kind); + addParam<>(_data, QStringLiteral("app_id"), appId); + addParam<>(_data, QStringLiteral("app_display_name"), appDisplayName); + addParam<>(_data, QStringLiteral("device_display_name"), deviceDisplayName); + addParam(_data, QStringLiteral("profile_tag"), profileTag); + addParam<>(_data, QStringLiteral("lang"), lang); + addParam<>(_data, QStringLiteral("data"), data); + addParam(_data, QStringLiteral("append"), append); setRequestData(_data); } diff --git a/lib/csapi/pushrules.cpp b/lib/csapi/pushrules.cpp index d7e416dc..22976641 100644 --- a/lib/csapi/pushrules.cpp +++ b/lib/csapi/pushrules.cpp @@ -24,8 +24,10 @@ QUrl GetPushRulesJob::makeRequestUrl(QUrl baseUrl) basePath % "/pushrules"); } +static const auto GetPushRulesJobName = QStringLiteral("GetPushRulesJob"); + GetPushRulesJob::GetPushRulesJob() - : BaseJob(HttpVerb::Get, "GetPushRulesJob", + : BaseJob(HttpVerb::Get, GetPushRulesJobName, basePath % "/pushrules") , d(new Private) { @@ -41,10 +43,10 @@ const PushRuleset& GetPushRulesJob::global() const BaseJob::Status GetPushRulesJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("global")) + if (!json.contains("global"_ls)) return { JsonParseError, "The key 'global' not found in the response" }; - d->global = fromJson(json.value("global")); + d->global = fromJson(json.value("global"_ls)); return Success; } @@ -60,8 +62,10 @@ QUrl GetPushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope, const QS basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId); } +static const auto GetPushRuleJobName = QStringLiteral("GetPushRuleJob"); + GetPushRuleJob::GetPushRuleJob(const QString& scope, const QString& kind, const QString& ruleId) - : BaseJob(HttpVerb::Get, "GetPushRuleJob", + : BaseJob(HttpVerb::Get, GetPushRuleJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId) , d(new Private) { @@ -77,10 +81,10 @@ const PushRule& GetPushRuleJob::data() const BaseJob::Status GetPushRuleJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } @@ -90,8 +94,10 @@ QUrl DeletePushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope, const basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId); } +static const auto DeletePushRuleJobName = QStringLiteral("DeletePushRuleJob"); + DeletePushRuleJob::DeletePushRuleJob(const QString& scope, const QString& kind, const QString& ruleId) - : BaseJob(HttpVerb::Delete, "DeletePushRuleJob", + : BaseJob(HttpVerb::Delete, DeletePushRuleJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId) { } @@ -99,20 +105,22 @@ DeletePushRuleJob::DeletePushRuleJob(const QString& scope, const QString& kind, BaseJob::Query queryToSetPushRule(const QString& before, const QString& after) { BaseJob::Query _q; - addParam(_q, "before", before); - addParam(_q, "after", after); + addParam(_q, QStringLiteral("before"), before); + addParam(_q, QStringLiteral("after"), after); return _q; } +static const auto SetPushRuleJobName = QStringLiteral("SetPushRuleJob"); + SetPushRuleJob::SetPushRuleJob(const QString& scope, const QString& kind, const QString& ruleId, const QStringList& actions, const QString& before, const QString& after, const QVector& conditions, const QString& pattern) - : BaseJob(HttpVerb::Put, "SetPushRuleJob", + : BaseJob(HttpVerb::Put, SetPushRuleJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId, queryToSetPushRule(before, after)) { QJsonObject _data; - addParam<>(_data, "actions", actions); - addParam(_data, "conditions", conditions); - addParam(_data, "pattern", pattern); + addParam<>(_data, QStringLiteral("actions"), actions); + addParam(_data, QStringLiteral("conditions"), conditions); + addParam(_data, QStringLiteral("pattern"), pattern); setRequestData(_data); } @@ -128,8 +136,10 @@ QUrl IsPushRuleEnabledJob::makeRequestUrl(QUrl baseUrl, const QString& scope, co basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId % "/enabled"); } +static const auto IsPushRuleEnabledJobName = QStringLiteral("IsPushRuleEnabledJob"); + IsPushRuleEnabledJob::IsPushRuleEnabledJob(const QString& scope, const QString& kind, const QString& ruleId) - : BaseJob(HttpVerb::Get, "IsPushRuleEnabledJob", + : BaseJob(HttpVerb::Get, IsPushRuleEnabledJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId % "/enabled") , d(new Private) { @@ -145,19 +155,21 @@ bool IsPushRuleEnabledJob::enabled() const BaseJob::Status IsPushRuleEnabledJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("enabled")) + if (!json.contains("enabled"_ls)) return { JsonParseError, "The key 'enabled' not found in the response" }; - d->enabled = fromJson(json.value("enabled")); + d->enabled = fromJson(json.value("enabled"_ls)); return Success; } +static const auto SetPushRuleEnabledJobName = QStringLiteral("SetPushRuleEnabledJob"); + SetPushRuleEnabledJob::SetPushRuleEnabledJob(const QString& scope, const QString& kind, const QString& ruleId, bool enabled) - : BaseJob(HttpVerb::Put, "SetPushRuleEnabledJob", + : BaseJob(HttpVerb::Put, SetPushRuleEnabledJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId % "/enabled") { QJsonObject _data; - addParam<>(_data, "enabled", enabled); + addParam<>(_data, QStringLiteral("enabled"), enabled); setRequestData(_data); } @@ -173,8 +185,10 @@ QUrl GetPushRuleActionsJob::makeRequestUrl(QUrl baseUrl, const QString& scope, c basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId % "/actions"); } +static const auto GetPushRuleActionsJobName = QStringLiteral("GetPushRuleActionsJob"); + GetPushRuleActionsJob::GetPushRuleActionsJob(const QString& scope, const QString& kind, const QString& ruleId) - : BaseJob(HttpVerb::Get, "GetPushRuleActionsJob", + : BaseJob(HttpVerb::Get, GetPushRuleActionsJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId % "/actions") , d(new Private) { @@ -190,19 +204,21 @@ const QStringList& GetPushRuleActionsJob::actions() const BaseJob::Status GetPushRuleActionsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("actions")) + if (!json.contains("actions"_ls)) return { JsonParseError, "The key 'actions' not found in the response" }; - d->actions = fromJson(json.value("actions")); + d->actions = fromJson(json.value("actions"_ls)); return Success; } +static const auto SetPushRuleActionsJobName = QStringLiteral("SetPushRuleActionsJob"); + SetPushRuleActionsJob::SetPushRuleActionsJob(const QString& scope, const QString& kind, const QString& ruleId, const QStringList& actions) - : BaseJob(HttpVerb::Put, "SetPushRuleActionsJob", + : BaseJob(HttpVerb::Put, SetPushRuleActionsJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId % "/actions") { QJsonObject _data; - addParam<>(_data, "actions", actions); + addParam<>(_data, QStringLiteral("actions"), actions); setRequestData(_data); } diff --git a/lib/csapi/receipts.cpp b/lib/csapi/receipts.cpp index 945e8673..b78ba533 100644 --- a/lib/csapi/receipts.cpp +++ b/lib/csapi/receipts.cpp @@ -12,8 +12,10 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto PostReceiptJobName = QStringLiteral("PostReceiptJob"); + PostReceiptJob::PostReceiptJob(const QString& roomId, const QString& receiptType, const QString& eventId, const QJsonObject& receipt) - : BaseJob(HttpVerb::Post, "PostReceiptJob", + : BaseJob(HttpVerb::Post, PostReceiptJobName, basePath % "/rooms/" % roomId % "/receipt/" % receiptType % "/" % eventId) { setRequestData(Data(toJson(receipt))); diff --git a/lib/csapi/redaction.cpp b/lib/csapi/redaction.cpp index 2c73800c..64098670 100644 --- a/lib/csapi/redaction.cpp +++ b/lib/csapi/redaction.cpp @@ -18,13 +18,15 @@ class RedactEventJob::Private QString eventId; }; +static const auto RedactEventJobName = QStringLiteral("RedactEventJob"); + RedactEventJob::RedactEventJob(const QString& roomId, const QString& eventId, const QString& txnId, const QString& reason) - : BaseJob(HttpVerb::Put, "RedactEventJob", + : BaseJob(HttpVerb::Put, RedactEventJobName, basePath % "/rooms/" % roomId % "/redact/" % eventId % "/" % txnId) , d(new Private) { QJsonObject _data; - addParam(_data, "reason", reason); + addParam(_data, QStringLiteral("reason"), reason); setRequestData(_data); } @@ -38,7 +40,7 @@ const QString& RedactEventJob::eventId() const BaseJob::Status RedactEventJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->eventId = fromJson(json.value("event_id")); + d->eventId = fromJson(json.value("event_id"_ls)); return Success; } diff --git a/lib/csapi/registration.cpp b/lib/csapi/registration.cpp index 4345635a..4991829c 100644 --- a/lib/csapi/registration.cpp +++ b/lib/csapi/registration.cpp @@ -24,24 +24,26 @@ class RegisterJob::Private BaseJob::Query queryToRegister(const QString& kind) { BaseJob::Query _q; - addParam(_q, "kind", kind); + addParam(_q, QStringLiteral("kind"), kind); return _q; } +static const auto RegisterJobName = QStringLiteral("RegisterJob"); + RegisterJob::RegisterJob(const QString& kind, const QJsonObject& auth, bool bindEmail, const QString& username, const QString& password, const QString& deviceId, const QString& initialDeviceDisplayName) - : BaseJob(HttpVerb::Post, "RegisterJob", + : BaseJob(HttpVerb::Post, RegisterJobName, basePath % "/register", queryToRegister(kind), {}, false) , d(new Private) { QJsonObject _data; - addParam(_data, "auth", auth); - addParam(_data, "bind_email", bindEmail); - addParam(_data, "username", username); - addParam(_data, "password", password); - addParam(_data, "device_id", deviceId); - addParam(_data, "initial_device_display_name", initialDeviceDisplayName); + addParam(_data, QStringLiteral("auth"), auth); + addParam(_data, QStringLiteral("bind_email"), bindEmail); + addParam(_data, QStringLiteral("username"), username); + addParam(_data, QStringLiteral("password"), password); + addParam(_data, QStringLiteral("device_id"), deviceId); + addParam(_data, QStringLiteral("initial_device_display_name"), initialDeviceDisplayName); setRequestData(_data); } @@ -70,32 +72,36 @@ const QString& RegisterJob::deviceId() const BaseJob::Status RegisterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->userId = fromJson(json.value("user_id")); - d->accessToken = fromJson(json.value("access_token")); - d->homeServer = fromJson(json.value("home_server")); - d->deviceId = fromJson(json.value("device_id")); + d->userId = fromJson(json.value("user_id"_ls)); + d->accessToken = fromJson(json.value("access_token"_ls)); + d->homeServer = fromJson(json.value("home_server"_ls)); + d->deviceId = fromJson(json.value("device_id"_ls)); return Success; } +static const auto RequestTokenToRegisterJobName = QStringLiteral("RequestTokenToRegisterJob"); + RequestTokenToRegisterJob::RequestTokenToRegisterJob(const QString& clientSecret, const QString& email, int sendAttempt, const QString& idServer) - : BaseJob(HttpVerb::Post, "RequestTokenToRegisterJob", + : BaseJob(HttpVerb::Post, RequestTokenToRegisterJobName, basePath % "/register/email/requestToken", false) { QJsonObject _data; - addParam(_data, "id_server", idServer); - addParam<>(_data, "client_secret", clientSecret); - addParam<>(_data, "email", email); - addParam<>(_data, "send_attempt", sendAttempt); + addParam(_data, QStringLiteral("id_server"), idServer); + addParam<>(_data, QStringLiteral("client_secret"), clientSecret); + addParam<>(_data, QStringLiteral("email"), email); + addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); setRequestData(_data); } +static const auto ChangePasswordJobName = QStringLiteral("ChangePasswordJob"); + ChangePasswordJob::ChangePasswordJob(const QString& newPassword, const QJsonObject& auth) - : BaseJob(HttpVerb::Post, "ChangePasswordJob", + : BaseJob(HttpVerb::Post, ChangePasswordJobName, basePath % "/account/password") { QJsonObject _data; - addParam<>(_data, "new_password", newPassword); - addParam(_data, "auth", auth); + addParam<>(_data, QStringLiteral("new_password"), newPassword); + addParam(_data, QStringLiteral("auth"), auth); setRequestData(_data); } @@ -105,18 +111,22 @@ QUrl RequestTokenToResetPasswordJob::makeRequestUrl(QUrl baseUrl) basePath % "/account/password/email/requestToken"); } +static const auto RequestTokenToResetPasswordJobName = QStringLiteral("RequestTokenToResetPasswordJob"); + RequestTokenToResetPasswordJob::RequestTokenToResetPasswordJob() - : BaseJob(HttpVerb::Post, "RequestTokenToResetPasswordJob", + : BaseJob(HttpVerb::Post, RequestTokenToResetPasswordJobName, basePath % "/account/password/email/requestToken", false) { } +static const auto DeactivateAccountJobName = QStringLiteral("DeactivateAccountJob"); + DeactivateAccountJob::DeactivateAccountJob(const QJsonObject& auth) - : BaseJob(HttpVerb::Post, "DeactivateAccountJob", + : BaseJob(HttpVerb::Post, DeactivateAccountJobName, basePath % "/account/deactivate") { QJsonObject _data; - addParam(_data, "auth", auth); + addParam(_data, QStringLiteral("auth"), auth); setRequestData(_data); } @@ -129,7 +139,7 @@ class CheckUsernameAvailabilityJob::Private BaseJob::Query queryToCheckUsernameAvailability(const QString& username) { BaseJob::Query _q; - addParam<>(_q, "username", username); + addParam<>(_q, QStringLiteral("username"), username); return _q; } @@ -140,8 +150,10 @@ QUrl CheckUsernameAvailabilityJob::makeRequestUrl(QUrl baseUrl, const QString& u queryToCheckUsernameAvailability(username)); } +static const auto CheckUsernameAvailabilityJobName = QStringLiteral("CheckUsernameAvailabilityJob"); + CheckUsernameAvailabilityJob::CheckUsernameAvailabilityJob(const QString& username) - : BaseJob(HttpVerb::Get, "CheckUsernameAvailabilityJob", + : BaseJob(HttpVerb::Get, CheckUsernameAvailabilityJobName, basePath % "/register/available", queryToCheckUsernameAvailability(username), {}, false) @@ -159,7 +171,7 @@ bool CheckUsernameAvailabilityJob::available() const BaseJob::Status CheckUsernameAvailabilityJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->available = fromJson(json.value("available")); + d->available = fromJson(json.value("available"_ls)); return Success; } diff --git a/lib/csapi/report_content.cpp b/lib/csapi/report_content.cpp index f1a1d6f2..a79d4dad 100644 --- a/lib/csapi/report_content.cpp +++ b/lib/csapi/report_content.cpp @@ -12,13 +12,15 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto ReportContentJobName = QStringLiteral("ReportContentJob"); + ReportContentJob::ReportContentJob(const QString& roomId, const QString& eventId, int score, const QString& reason) - : BaseJob(HttpVerb::Post, "ReportContentJob", + : BaseJob(HttpVerb::Post, ReportContentJobName, basePath % "/rooms/" % roomId % "/report/" % eventId) { QJsonObject _data; - addParam<>(_data, "score", score); - addParam<>(_data, "reason", reason); + addParam<>(_data, QStringLiteral("score"), score); + addParam<>(_data, QStringLiteral("reason"), reason); setRequestData(_data); } diff --git a/lib/csapi/room_send.cpp b/lib/csapi/room_send.cpp index 9637a205..2b39ede2 100644 --- a/lib/csapi/room_send.cpp +++ b/lib/csapi/room_send.cpp @@ -18,8 +18,10 @@ class SendMessageJob::Private QString eventId; }; +static const auto SendMessageJobName = QStringLiteral("SendMessageJob"); + SendMessageJob::SendMessageJob(const QString& roomId, const QString& eventType, const QString& txnId, const QJsonObject& body) - : BaseJob(HttpVerb::Put, "SendMessageJob", + : BaseJob(HttpVerb::Put, SendMessageJobName, basePath % "/rooms/" % roomId % "/send/" % eventType % "/" % txnId) , d(new Private) { @@ -36,7 +38,7 @@ const QString& SendMessageJob::eventId() const BaseJob::Status SendMessageJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->eventId = fromJson(json.value("event_id")); + d->eventId = fromJson(json.value("event_id"_ls)); return Success; } diff --git a/lib/csapi/room_state.cpp b/lib/csapi/room_state.cpp index 39f36afb..8f87979d 100644 --- a/lib/csapi/room_state.cpp +++ b/lib/csapi/room_state.cpp @@ -18,8 +18,10 @@ class SetRoomStateWithKeyJob::Private QString eventId; }; +static const auto SetRoomStateWithKeyJobName = QStringLiteral("SetRoomStateWithKeyJob"); + SetRoomStateWithKeyJob::SetRoomStateWithKeyJob(const QString& roomId, const QString& eventType, const QString& stateKey, const QJsonObject& body) - : BaseJob(HttpVerb::Put, "SetRoomStateWithKeyJob", + : BaseJob(HttpVerb::Put, SetRoomStateWithKeyJobName, basePath % "/rooms/" % roomId % "/state/" % eventType % "/" % stateKey) , d(new Private) { @@ -36,7 +38,7 @@ const QString& SetRoomStateWithKeyJob::eventId() const BaseJob::Status SetRoomStateWithKeyJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->eventId = fromJson(json.value("event_id")); + d->eventId = fromJson(json.value("event_id"_ls)); return Success; } @@ -46,8 +48,10 @@ class SetRoomStateJob::Private QString eventId; }; +static const auto SetRoomStateJobName = QStringLiteral("SetRoomStateJob"); + SetRoomStateJob::SetRoomStateJob(const QString& roomId, const QString& eventType, const QJsonObject& body) - : BaseJob(HttpVerb::Put, "SetRoomStateJob", + : BaseJob(HttpVerb::Put, SetRoomStateJobName, basePath % "/rooms/" % roomId % "/state/" % eventType) , d(new Private) { @@ -64,7 +68,7 @@ const QString& SetRoomStateJob::eventId() const BaseJob::Status SetRoomStateJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->eventId = fromJson(json.value("event_id")); + d->eventId = fromJson(json.value("event_id"_ls)); return Success; } diff --git a/lib/csapi/rooms.cpp b/lib/csapi/rooms.cpp index 4b66b447..a70d9543 100644 --- a/lib/csapi/rooms.cpp +++ b/lib/csapi/rooms.cpp @@ -24,8 +24,10 @@ QUrl GetOneRoomEventJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, con basePath % "/rooms/" % roomId % "/event/" % eventId); } +static const auto GetOneRoomEventJobName = QStringLiteral("GetOneRoomEventJob"); + GetOneRoomEventJob::GetOneRoomEventJob(const QString& roomId, const QString& eventId) - : BaseJob(HttpVerb::Get, "GetOneRoomEventJob", + : BaseJob(HttpVerb::Get, GetOneRoomEventJobName, basePath % "/rooms/" % roomId % "/event/" % eventId) , d(new Private) { @@ -41,10 +43,10 @@ EventPtr&& GetOneRoomEventJob::data() BaseJob::Status GetOneRoomEventJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } @@ -60,8 +62,10 @@ QUrl GetRoomStateWithKeyJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, basePath % "/rooms/" % roomId % "/state/" % eventType % "/" % stateKey); } +static const auto GetRoomStateWithKeyJobName = QStringLiteral("GetRoomStateWithKeyJob"); + GetRoomStateWithKeyJob::GetRoomStateWithKeyJob(const QString& roomId, const QString& eventType, const QString& stateKey) - : BaseJob(HttpVerb::Get, "GetRoomStateWithKeyJob", + : BaseJob(HttpVerb::Get, GetRoomStateWithKeyJobName, basePath % "/rooms/" % roomId % "/state/" % eventType % "/" % stateKey) , d(new Private) { @@ -77,10 +81,10 @@ StateEventPtr&& GetRoomStateWithKeyJob::data() BaseJob::Status GetRoomStateWithKeyJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } @@ -96,8 +100,10 @@ QUrl GetRoomStateByTypeJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, basePath % "/rooms/" % roomId % "/state/" % eventType); } +static const auto GetRoomStateByTypeJobName = QStringLiteral("GetRoomStateByTypeJob"); + GetRoomStateByTypeJob::GetRoomStateByTypeJob(const QString& roomId, const QString& eventType) - : BaseJob(HttpVerb::Get, "GetRoomStateByTypeJob", + : BaseJob(HttpVerb::Get, GetRoomStateByTypeJobName, basePath % "/rooms/" % roomId % "/state/" % eventType) , d(new Private) { @@ -113,10 +119,10 @@ StateEventPtr&& GetRoomStateByTypeJob::data() BaseJob::Status GetRoomStateByTypeJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } @@ -132,8 +138,10 @@ QUrl GetRoomStateJob::makeRequestUrl(QUrl baseUrl, const QString& roomId) basePath % "/rooms/" % roomId % "/state"); } +static const auto GetRoomStateJobName = QStringLiteral("GetRoomStateJob"); + GetRoomStateJob::GetRoomStateJob(const QString& roomId) - : BaseJob(HttpVerb::Get, "GetRoomStateJob", + : BaseJob(HttpVerb::Get, GetRoomStateJobName, basePath % "/rooms/" % roomId % "/state") , d(new Private) { @@ -149,10 +157,10 @@ StateEvents&& GetRoomStateJob::data() BaseJob::Status GetRoomStateJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } @@ -168,8 +176,10 @@ QUrl GetMembersByRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId) basePath % "/rooms/" % roomId % "/members"); } +static const auto GetMembersByRoomJobName = QStringLiteral("GetMembersByRoomJob"); + GetMembersByRoomJob::GetMembersByRoomJob(const QString& roomId) - : BaseJob(HttpVerb::Get, "GetMembersByRoomJob", + : BaseJob(HttpVerb::Get, GetMembersByRoomJobName, basePath % "/rooms/" % roomId % "/members") , d(new Private) { @@ -185,7 +195,7 @@ EventsArray&& GetMembersByRoomJob::chunk() BaseJob::Status GetMembersByRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->chunk = fromJson>(json.value("chunk")); + d->chunk = fromJson>(json.value("chunk"_ls)); return Success; } @@ -200,9 +210,9 @@ namespace QMatrixClient const auto& _json = jv.toObject(); GetJoinedMembersByRoomJob::RoomMember result; result.displayName = - fromJson(_json.value("display_name")); + fromJson(_json.value("display_name"_ls)); result.avatarUrl = - fromJson(_json.value("avatar_url")); + fromJson(_json.value("avatar_url"_ls)); return result; } @@ -221,8 +231,10 @@ QUrl GetJoinedMembersByRoomJob::makeRequestUrl(QUrl baseUrl, const QString& room basePath % "/rooms/" % roomId % "/joined_members"); } +static const auto GetJoinedMembersByRoomJobName = QStringLiteral("GetJoinedMembersByRoomJob"); + GetJoinedMembersByRoomJob::GetJoinedMembersByRoomJob(const QString& roomId) - : BaseJob(HttpVerb::Get, "GetJoinedMembersByRoomJob", + : BaseJob(HttpVerb::Get, GetJoinedMembersByRoomJobName, basePath % "/rooms/" % roomId % "/joined_members") , d(new Private) { @@ -238,7 +250,7 @@ const QHash& GetJoinedMembersByR BaseJob::Status GetJoinedMembersByRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->joined = fromJson>(json.value("joined")); + d->joined = fromJson>(json.value("joined"_ls)); return Success; } diff --git a/lib/csapi/search.cpp b/lib/csapi/search.cpp index 75748b38..f3adb315 100644 --- a/lib/csapi/search.cpp +++ b/lib/csapi/search.cpp @@ -19,43 +19,43 @@ namespace QMatrixClient QJsonObject toJson(const SearchJob::IncludeEventContext& pod) { QJsonObject _json; - addParam(_json, "before_limit", pod.beforeLimit); - addParam(_json, "after_limit", pod.afterLimit); - addParam(_json, "include_profile", pod.includeProfile); + addParam(_json, QStringLiteral("before_limit"), pod.beforeLimit); + addParam(_json, QStringLiteral("after_limit"), pod.afterLimit); + addParam(_json, QStringLiteral("include_profile"), pod.includeProfile); return _json; } QJsonObject toJson(const SearchJob::Group& pod) { QJsonObject _json; - addParam(_json, "key", pod.key); + addParam(_json, QStringLiteral("key"), pod.key); return _json; } QJsonObject toJson(const SearchJob::Groupings& pod) { QJsonObject _json; - addParam(_json, "group_by", pod.groupBy); + addParam(_json, QStringLiteral("group_by"), pod.groupBy); return _json; } QJsonObject toJson(const SearchJob::RoomEventsCriteria& pod) { QJsonObject _json; - addParam<>(_json, "search_term", pod.searchTerm); - addParam(_json, "keys", pod.keys); - addParam(_json, "filter", pod.filter); - addParam(_json, "order_by", pod.orderBy); - addParam(_json, "event_context", pod.eventContext); - addParam(_json, "include_state", pod.includeState); - addParam(_json, "groupings", pod.groupings); + addParam<>(_json, QStringLiteral("search_term"), pod.searchTerm); + addParam(_json, QStringLiteral("keys"), pod.keys); + addParam(_json, QStringLiteral("filter"), pod.filter); + addParam(_json, QStringLiteral("order_by"), pod.orderBy); + addParam(_json, QStringLiteral("event_context"), pod.eventContext); + addParam(_json, QStringLiteral("include_state"), pod.includeState); + addParam(_json, QStringLiteral("groupings"), pod.groupings); return _json; } QJsonObject toJson(const SearchJob::Categories& pod) { QJsonObject _json; - addParam(_json, "room_events", pod.roomEvents); + addParam(_json, QStringLiteral("room_events"), pod.roomEvents); return _json; } @@ -66,9 +66,9 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchJob::UserProfile result; result.displayname = - fromJson(_json.value("displayname")); + fromJson(_json.value("displayname"_ls)); result.avatarUrl = - fromJson(_json.value("avatar_url")); + fromJson(_json.value("avatar_url"_ls)); return result; } @@ -81,15 +81,15 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchJob::EventContext result; result.begin = - fromJson(_json.value("start")); + fromJson(_json.value("start"_ls)); result.end = - fromJson(_json.value("end")); + fromJson(_json.value("end"_ls)); result.profileInfo = - fromJson>(_json.value("profile_info")); + fromJson>(_json.value("profile_info"_ls)); result.eventsBefore = - fromJson(_json.value("events_before")); + fromJson(_json.value("events_before"_ls)); result.eventsAfter = - fromJson(_json.value("events_after")); + fromJson(_json.value("events_after"_ls)); return result; } @@ -102,11 +102,11 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchJob::Result result; result.rank = - fromJson(_json.value("rank")); + fromJson(_json.value("rank"_ls)); result.result = - fromJson(_json.value("result")); + fromJson(_json.value("result"_ls)); result.context = - fromJson(_json.value("context")); + fromJson(_json.value("context"_ls)); return result; } @@ -119,11 +119,11 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchJob::GroupValue result; result.nextBatch = - fromJson(_json.value("next_batch")); + fromJson(_json.value("next_batch"_ls)); result.order = - fromJson(_json.value("order")); + fromJson(_json.value("order"_ls)); result.results = - fromJson(_json.value("results")); + fromJson(_json.value("results"_ls)); return result; } @@ -136,15 +136,15 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchJob::ResultRoomEvents result; result.count = - fromJson(_json.value("count")); + fromJson(_json.value("count"_ls)); result.results = - fromJson>(_json.value("results")); + fromJson>(_json.value("results"_ls)); result.state = - fromJson>(_json.value("state")); + fromJson>(_json.value("state"_ls)); result.groups = - fromJson>>(_json.value("groups")); + fromJson>>(_json.value("groups"_ls)); result.nextBatch = - fromJson(_json.value("next_batch")); + fromJson(_json.value("next_batch"_ls)); return result; } @@ -157,7 +157,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchJob::ResultCategories result; result.roomEvents = - fromJson(_json.value("room_events")); + fromJson(_json.value("room_events"_ls)); return result; } @@ -173,18 +173,20 @@ class SearchJob::Private BaseJob::Query queryToSearch(const QString& nextBatch) { BaseJob::Query _q; - addParam(_q, "next_batch", nextBatch); + addParam(_q, QStringLiteral("next_batch"), nextBatch); return _q; } +static const auto SearchJobName = QStringLiteral("SearchJob"); + SearchJob::SearchJob(const Categories& searchCategories, const QString& nextBatch) - : BaseJob(HttpVerb::Post, "SearchJob", + : BaseJob(HttpVerb::Post, SearchJobName, basePath % "/search", queryToSearch(nextBatch)) , d(new Private) { QJsonObject _data; - addParam<>(_data, "search_categories", searchCategories); + addParam<>(_data, QStringLiteral("search_categories"), searchCategories); setRequestData(_data); } @@ -198,10 +200,10 @@ const SearchJob::ResultCategories& SearchJob::searchCategories() const BaseJob::Status SearchJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("search_categories")) + if (!json.contains("search_categories"_ls)) return { JsonParseError, "The key 'search_categories' not found in the response" }; - d->searchCategories = fromJson(json.value("search_categories")); + d->searchCategories = fromJson(json.value("search_categories"_ls)); return Success; } diff --git a/lib/csapi/tags.cpp b/lib/csapi/tags.cpp index 9cd78aec..1afc3bfc 100644 --- a/lib/csapi/tags.cpp +++ b/lib/csapi/tags.cpp @@ -24,8 +24,10 @@ QUrl GetRoomTagsJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const Q basePath % "/user/" % userId % "/rooms/" % roomId % "/tags"); } +static const auto GetRoomTagsJobName = QStringLiteral("GetRoomTagsJob"); + GetRoomTagsJob::GetRoomTagsJob(const QString& userId, const QString& roomId) - : BaseJob(HttpVerb::Get, "GetRoomTagsJob", + : BaseJob(HttpVerb::Get, GetRoomTagsJobName, basePath % "/user/" % userId % "/rooms/" % roomId % "/tags") , d(new Private) { @@ -41,12 +43,14 @@ const QJsonObject& GetRoomTagsJob::tags() const BaseJob::Status GetRoomTagsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->tags = fromJson(json.value("tags")); + d->tags = fromJson(json.value("tags"_ls)); return Success; } +static const auto SetRoomTagJobName = QStringLiteral("SetRoomTagJob"); + SetRoomTagJob::SetRoomTagJob(const QString& userId, const QString& roomId, const QString& tag, const QJsonObject& body) - : BaseJob(HttpVerb::Put, "SetRoomTagJob", + : BaseJob(HttpVerb::Put, SetRoomTagJobName, basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" % tag) { setRequestData(Data(toJson(body))); @@ -58,8 +62,10 @@ QUrl DeleteRoomTagJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" % tag); } +static const auto DeleteRoomTagJobName = QStringLiteral("DeleteRoomTagJob"); + DeleteRoomTagJob::DeleteRoomTagJob(const QString& userId, const QString& roomId, const QString& tag) - : BaseJob(HttpVerb::Delete, "DeleteRoomTagJob", + : BaseJob(HttpVerb::Delete, DeleteRoomTagJobName, basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" % tag) { } diff --git a/lib/csapi/third_party_membership.cpp b/lib/csapi/third_party_membership.cpp index 2372f9d7..c1683338 100644 --- a/lib/csapi/third_party_membership.cpp +++ b/lib/csapi/third_party_membership.cpp @@ -12,14 +12,16 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto InviteBy3PIDJobName = QStringLiteral("InviteBy3PIDJob"); + InviteBy3PIDJob::InviteBy3PIDJob(const QString& roomId, const QString& idServer, const QString& medium, const QString& address) - : BaseJob(HttpVerb::Post, "InviteBy3PIDJob", + : BaseJob(HttpVerb::Post, InviteBy3PIDJobName, basePath % "/rooms/" % roomId % "/invite") { QJsonObject _data; - addParam<>(_data, "id_server", idServer); - addParam<>(_data, "medium", medium); - addParam<>(_data, "address", address); + addParam<>(_data, QStringLiteral("id_server"), idServer); + addParam<>(_data, QStringLiteral("medium"), medium); + addParam<>(_data, QStringLiteral("address"), address); setRequestData(_data); } diff --git a/lib/csapi/to_device.cpp b/lib/csapi/to_device.cpp index 1478a679..7c7f495a 100644 --- a/lib/csapi/to_device.cpp +++ b/lib/csapi/to_device.cpp @@ -12,12 +12,14 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto SendToDeviceJobName = QStringLiteral("SendToDeviceJob"); + SendToDeviceJob::SendToDeviceJob(const QString& eventType, const QString& txnId, const QHash>& messages) - : BaseJob(HttpVerb::Put, "SendToDeviceJob", + : BaseJob(HttpVerb::Put, SendToDeviceJobName, basePath % "/sendToDevice/" % eventType % "/" % txnId) { QJsonObject _data; - addParam(_data, "messages", messages); + addParam(_data, QStringLiteral("messages"), messages); setRequestData(_data); } diff --git a/lib/csapi/typing.cpp b/lib/csapi/typing.cpp index 6db522c4..bf10912b 100644 --- a/lib/csapi/typing.cpp +++ b/lib/csapi/typing.cpp @@ -12,13 +12,15 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +static const auto SetTypingJobName = QStringLiteral("SetTypingJob"); + SetTypingJob::SetTypingJob(const QString& userId, const QString& roomId, bool typing, Omittable timeout) - : BaseJob(HttpVerb::Put, "SetTypingJob", + : BaseJob(HttpVerb::Put, SetTypingJobName, basePath % "/rooms/" % roomId % "/typing/" % userId) { QJsonObject _data; - addParam<>(_data, "typing", typing); - addParam(_data, "timeout", timeout); + addParam<>(_data, QStringLiteral("typing"), typing); + addParam(_data, QStringLiteral("timeout"), timeout); setRequestData(_data); } diff --git a/lib/csapi/users.cpp b/lib/csapi/users.cpp index e7f68bda..408a8cad 100644 --- a/lib/csapi/users.cpp +++ b/lib/csapi/users.cpp @@ -23,11 +23,11 @@ namespace QMatrixClient const auto& _json = jv.toObject(); SearchUserDirectoryJob::User result; result.userId = - fromJson(_json.value("user_id")); + fromJson(_json.value("user_id"_ls)); result.displayName = - fromJson(_json.value("display_name")); + fromJson(_json.value("display_name"_ls)); result.avatarUrl = - fromJson(_json.value("avatar_url")); + fromJson(_json.value("avatar_url"_ls)); return result; } @@ -41,14 +41,16 @@ class SearchUserDirectoryJob::Private bool limited; }; +static const auto SearchUserDirectoryJobName = QStringLiteral("SearchUserDirectoryJob"); + SearchUserDirectoryJob::SearchUserDirectoryJob(const QString& searchTerm, Omittable limit) - : BaseJob(HttpVerb::Post, "SearchUserDirectoryJob", + : BaseJob(HttpVerb::Post, SearchUserDirectoryJobName, basePath % "/user_directory/search") , d(new Private) { QJsonObject _data; - addParam<>(_data, "search_term", searchTerm); - addParam(_data, "limit", limit); + addParam<>(_data, QStringLiteral("search_term"), searchTerm); + addParam(_data, QStringLiteral("limit"), limit); setRequestData(_data); } @@ -67,14 +69,14 @@ bool SearchUserDirectoryJob::limited() const BaseJob::Status SearchUserDirectoryJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("results")) + if (!json.contains("results"_ls)) return { JsonParseError, "The key 'results' not found in the response" }; - d->results = fromJson>(json.value("results")); - if (!json.contains("limited")) + d->results = fromJson>(json.value("results"_ls)); + if (!json.contains("limited"_ls)) return { JsonParseError, "The key 'limited' not found in the response" }; - d->limited = fromJson(json.value("limited")); + d->limited = fromJson(json.value("limited"_ls)); return Success; } diff --git a/lib/csapi/versions.cpp b/lib/csapi/versions.cpp index 7b55b94f..128902e2 100644 --- a/lib/csapi/versions.cpp +++ b/lib/csapi/versions.cpp @@ -24,8 +24,10 @@ QUrl GetVersionsJob::makeRequestUrl(QUrl baseUrl) basePath % "/versions"); } +static const auto GetVersionsJobName = QStringLiteral("GetVersionsJob"); + GetVersionsJob::GetVersionsJob() - : BaseJob(HttpVerb::Get, "GetVersionsJob", + : BaseJob(HttpVerb::Get, GetVersionsJobName, basePath % "/versions", false) , d(new Private) { @@ -41,7 +43,7 @@ const QStringList& GetVersionsJob::versions() const BaseJob::Status GetVersionsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->versions = fromJson(json.value("versions")); + d->versions = fromJson(json.value("versions"_ls)); return Success; } diff --git a/lib/csapi/voip.cpp b/lib/csapi/voip.cpp index f84c140d..8ecf92c6 100644 --- a/lib/csapi/voip.cpp +++ b/lib/csapi/voip.cpp @@ -24,8 +24,10 @@ QUrl GetTurnServerJob::makeRequestUrl(QUrl baseUrl) basePath % "/voip/turnServer"); } +static const auto GetTurnServerJobName = QStringLiteral("GetTurnServerJob"); + GetTurnServerJob::GetTurnServerJob() - : BaseJob(HttpVerb::Get, "GetTurnServerJob", + : BaseJob(HttpVerb::Get, GetTurnServerJobName, basePath % "/voip/turnServer") , d(new Private) { @@ -41,10 +43,10 @@ const QJsonObject& GetTurnServerJob::data() const BaseJob::Status GetTurnServerJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("data")) + if (!json.contains("data"_ls)) return { JsonParseError, "The key 'data' not found in the response" }; - d->data = fromJson(json.value("data")); + d->data = fromJson(json.value("data"_ls)); return Success; } diff --git a/lib/csapi/whoami.cpp b/lib/csapi/whoami.cpp index 4c231b5f..cb6439ef 100644 --- a/lib/csapi/whoami.cpp +++ b/lib/csapi/whoami.cpp @@ -24,8 +24,10 @@ QUrl GetTokenOwnerJob::makeRequestUrl(QUrl baseUrl) basePath % "/account/whoami"); } +static const auto GetTokenOwnerJobName = QStringLiteral("GetTokenOwnerJob"); + GetTokenOwnerJob::GetTokenOwnerJob() - : BaseJob(HttpVerb::Get, "GetTokenOwnerJob", + : BaseJob(HttpVerb::Get, GetTokenOwnerJobName, basePath % "/account/whoami") , d(new Private) { @@ -41,10 +43,10 @@ const QString& GetTokenOwnerJob::userId() const BaseJob::Status GetTokenOwnerJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - if (!json.contains("user_id")) + if (!json.contains("user_id"_ls)) return { JsonParseError, "The key 'user_id' not found in the response" }; - d->userId = fromJson(json.value("user_id")); + d->userId = fromJson(json.value("user_id"_ls)); return Success; } diff --git a/lib/csapi/{{base}}.cpp.mustache b/lib/csapi/{{base}}.cpp.mustache index 8b5acd65..d25997ed 100644 --- a/lib/csapi/{{base}}.cpp.mustache +++ b/lib/csapi/{{base}}.cpp.mustache @@ -11,7 +11,7 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const {{qualifiedName}}& pod) { QJsonObject _json;{{#vars}} - addParam<{{^required?}}IfNotEmpty{{/required?}}>(_json, "{{baseName}}", pod.{{nameCamelCase}});{{/vars}} + addParam<{{^required?}}IfNotEmpty{{/required?}}>(_json, QStringLiteral("{{baseName}}"), pod.{{nameCamelCase}});{{/vars}} return _json; } {{/in?}}{{#out?}} @@ -20,7 +20,7 @@ QJsonObject QMatrixClient::toJson(const {{qualifiedName}}& pod) const auto& _json = jv.toObject(); {{qualifiedName}} result; {{#vars}}result.{{nameCamelCase}} = - fromJson<{{dataType.name}}>(_json.value("{{baseName}}")); + fromJson<{{dataType.name}}>(_json.value("{{baseName}}"_ls)); {{/vars}} return result; } @@ -34,7 +34,7 @@ namespace QMatrixClient QJsonObject toJson(const {{qualifiedName}}& pod) { QJsonObject _json;{{#vars}} - addParam<{{^required?}}IfNotEmpty{{/required?}}>(_json, "{{baseName}}", pod.{{nameCamelCase}});{{/vars}} + addParam<{{^required?}}IfNotEmpty{{/required?}}>(_json, QStringLiteral("{{baseName}}"), pod.{{nameCamelCase}});{{/vars}} return _json; } {{/in?}}{{#out?}} @@ -45,7 +45,7 @@ namespace QMatrixClient const auto& _json = jv.toObject(); {{qualifiedName}} result; {{#vars}} result.{{nameCamelCase}} = - fromJson<{{dataType.qualifiedName}}>(_json.value("{{baseName}}")); + fromJson<{{dataType.qualifiedName}}>(_json.value("{{baseName}}"_ls)); {{/vars}} return result; } @@ -61,7 +61,7 @@ class {{camelCaseOperationId}}Job::Private BaseJob::Query queryTo{{camelCaseOperationId}}({{#queryParams}}{{>joinedParamDef}}{{/queryParams}}) { BaseJob::Query _q;{{#queryParams}} - addParam<{{^required?}}IfNotEmpty{{/required?}}>(_q, "{{baseName}}", {{paramName}});{{/queryParams}} + addParam<{{^required?}}IfNotEmpty{{/required?}}>(_q, QStringLiteral("{{baseName}}"), {{paramName}});{{/queryParams}} return _q; } {{/queryParams?}}{{^bodyParams}} @@ -72,8 +72,10 @@ QUrl {{camelCaseOperationId}}Job::makeRequestUrl(QUrl baseUrl{{#allParams?}}, {{ queryTo{{camelCaseOperationId}}({{>passQueryParams}}){{/queryParams?}}); } {{/ bodyParams}} +static const auto {{camelCaseOperationId}}JobName = QStringLiteral("{{camelCaseOperationId}}Job"); + {{camelCaseOperationId}}Job::{{camelCaseOperationId}}Job({{#allParams}}{{>joinedParamDef}}{{/allParams}}) - : BaseJob(HttpVerb::{{#@cap}}{{#@tolower}}{{httpMethod}}{{/@tolower}}{{/@cap}}, "{{camelCaseOperationId}}Job", + : BaseJob(HttpVerb::{{#@cap}}{{#@tolower}}{{httpMethod}}{{/@tolower}}{{/@cap}}, {{camelCaseOperationId}}JobName, basePath{{#pathParts}} % {{_}}{{/pathParts}}{{#queryParams?}}, queryTo{{camelCaseOperationId}}({{>passQueryParams}}){{/queryParams?}}{{#skipAuth}}{{#queryParams?}}, {}{{/queryParams?}}, false{{/skipAuth}}){{#responses}}{{#normalResponse?}}{{#allProperties?}} @@ -87,7 +89,7 @@ QUrl {{camelCaseOperationId}}Job::makeRequestUrl(QUrl baseUrl{{#allParams?}}, {{ }}{{#consumesNonJson?}}{{nameCamelCase}}{{/consumesNonJson? }}{{^consumesNonJson?}}toJson({{nameCamelCase}}){{/consumesNonJson?}}));{{/inlineBody }}{{^inlineBody}} QJsonObject _data;{{#bodyParams}} - addParam<{{^required?}}IfNotEmpty{{/required?}}>(_data, "{{baseName}}", {{paramName}});{{/bodyParams}} + addParam<{{^required?}}IfNotEmpty{{/required?}}>(_data, QStringLiteral("{{baseName}}"), {{paramName}});{{/bodyParams}} setRequestData(_data);{{/inlineBody}} {{/bodyParams?}}{{#producesNonJson?}} setExpectedContentTypes({ {{#produces}}"{{_}}"{{>cjoin}}{{/produces}} }); {{/producesNonJson?}}}{{!<- mind the actual brace}} @@ -108,10 +110,10 @@ BaseJob::Status {{camelCaseOperationId}}Job::parseReply(QNetworkReply* reply) BaseJob::Status {{camelCaseOperationId}}Job::parseJson(const QJsonDocument& data) { auto json = data.object(); - {{# properties}}{{#required?}}if (!json.contains("{{baseName}}")) + {{# properties}}{{#required?}}if (!json.contains("{{baseName}}"_ls)) return { JsonParseError, "The key '{{baseName}}' not found in the response" }; - {{/required?}}d->{{paramName}} = fromJson<{{dataType.name}}>(json.value("{{baseName}}")); + {{/required?}}d->{{paramName}} = fromJson<{{dataType.name}}>(json.value("{{baseName}}"_ls)); {{/ properties}}return Success; }{{/ producesNonJson?}} {{/allProperties?}}{{/normalResponse?}}{{/responses}}{{/operation}}{{/operations}} diff --git a/lib/jobs/basejob.cpp b/lib/jobs/basejob.cpp index 607a6c04..f9628c19 100644 --- a/lib/jobs/basejob.cpp +++ b/lib/jobs/basejob.cpp @@ -19,6 +19,7 @@ #include "basejob.h" #include "connectiondata.h" +#include "util.h" #include #include @@ -196,7 +197,7 @@ void BaseJob::Private::sendRequest(bool inBackground) { makeRequestUrl(connection->baseUrl(), apiEndpoint, requestQuery) }; if (!requestHeaders.contains("Content-Type")) req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - req.setRawHeader(QByteArray("Authorization"), + req.setRawHeader("Authorization", QByteArray("Bearer ") + connection->accessToken()); req.setAttribute(QNetworkRequest::BackgroundRequestAttribute, inBackground); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) @@ -292,11 +293,12 @@ void BaseJob::gotReply() if (jsonBody) { auto json = QJsonDocument::fromJson(d->rawResponse).object(); + const auto errCode = json.value("errcode"_ls).toString(); if (error() == TooManyRequestsError || - json.value("errcode").toString() == "M_LIMIT_EXCEEDED") + errCode == "M_LIMIT_EXCEEDED") { QString msg = tr("Too many requests"); - auto retryInterval = json.value("retry_after_ms").toInt(-1); + auto retryInterval = json.value("retry_after_ms"_ls).toInt(-1); if (retryInterval != -1) msg += tr(", next retry advised after %1 ms") .arg(retryInterval); @@ -313,13 +315,14 @@ void BaseJob::gotReply() emit retryScheduled(d->retriesTaken, retryInterval); return; } - if (json.value("errcode").toString() == "M_CONSENT_NOT_GIVEN") + if (errCode == "M_CONSENT_NOT_GIVEN") { d->status.code = UserConsentRequiredError; - d->errorUrl = json.value("consent_uri").toString(); + d->errorUrl = json.value("consent_uri"_ls).toString(); } - else if (!json.isEmpty()) // FIXME: The below is not localisable - setStatus(IncorrectRequestError, json.value("error").toString()); + else if (!json.isEmpty()) // Not localisable on the client side + setStatus(IncorrectRequestError, + json.value("error"_ls).toString()); } } @@ -366,7 +369,8 @@ BaseJob::Status BaseJob::doCheckReply(QNetworkReply* reply) const return { NetworkError, reply->errorString() }; } - const QString replyState = reply->isRunning() ? "(tentative)" : "(final)"; + const QString replyState = reply->isRunning() ? + QStringLiteral("(tentative)") : QStringLiteral("(final)"); const auto urlString = '|' + d->reply->url().toDisplayString(); const auto httpCode = httpCodeHeader.toInt(); const auto reason = @@ -375,12 +379,11 @@ BaseJob::Status BaseJob::doCheckReply(QNetworkReply* reply) const { qCDebug(d->logCat).noquote().nospace() << this << urlString; qCDebug(d->logCat).noquote() << " " << httpCode << reason << replyState; - if (checkContentType(reply->rawHeader("Content-Type"), + if (!checkContentType(reply->rawHeader("Content-Type"), d->expectedContentTypes)) - return NoError; - else // A warning in the logs might be more proper instead return { UnexpectedResponseTypeWarning, "Unexpected content type of the response" }; + return NoError; } qCWarning(d->logCat).noquote().nospace() << this << urlString; diff --git a/lib/jobs/sendeventjob.cpp b/lib/jobs/sendeventjob.cpp index f5190d4b..e5852c65 100644 --- a/lib/jobs/sendeventjob.cpp +++ b/lib/jobs/sendeventjob.cpp @@ -35,7 +35,7 @@ void SendEventJob::beforeStart(const ConnectionData* connData) BaseJob::Status SendEventJob::parseJson(const QJsonDocument& data) { - _eventId = data.object().value("event_id").toString(); + _eventId = data.object().value("event_id"_ls).toString(); if (!_eventId.isEmpty()) return Success; diff --git a/lib/jobs/syncjob.cpp b/lib/jobs/syncjob.cpp index cbdc37b4..7e5f2e0f 100644 --- a/lib/jobs/syncjob.cpp +++ b/lib/jobs/syncjob.cpp @@ -32,13 +32,13 @@ SyncJob::SyncJob(const QString& since, const QString& filter, int timeout, setLoggingCategory(SYNCJOB); QUrlQuery query; if( !filter.isEmpty() ) - query.addQueryItem("filter", filter); + query.addQueryItem(QStringLiteral("filter"), filter); if( !presence.isEmpty() ) - query.addQueryItem("set_presence", presence); + query.addQueryItem(QStringLiteral("set_presence"), presence); if( timeout >= 0 ) - query.addQueryItem("timeout", QString::number(timeout)); + query.addQueryItem(QStringLiteral("timeout"), QString::number(timeout)); if( !since.isEmpty() ) - query.addQueryItem("since", since); + query.addQueryItem(QStringLiteral("since"), since); setRequestQuery(query); setMaxRetries(std::numeric_limits::max()); @@ -72,7 +72,7 @@ Events&&SyncData::takeToDeviceEvents() template inline EventsArrayT load(const QJsonObject& batches, StrT keyName) { - return fromJson(batches[keyName].toObject().value("events")); + return fromJson(batches[keyName].toObject().value("events"_ls)); } BaseJob::Status SyncJob::parseJson(const QJsonDocument& data) @@ -85,12 +85,12 @@ BaseJob::Status SyncData::parseJson(const QJsonDocument &data) QElapsedTimer et; et.start(); auto json = data.object(); - nextBatch_ = json.value("next_batch").toString(); - presenceData = load(json, "presence"); - accountData = load(json, "account_data"); - toDeviceEvents = load(json, "to_device"); + nextBatch_ = json.value("next_batch"_ls).toString(); + presenceData = load(json, "presence"_ls); + accountData = load(json, "account_data"_ls); + toDeviceEvents = load(json, "to_device"_ls); - QJsonObject rooms = json.value("rooms").toObject(); + auto rooms = json.value("rooms"_ls).toObject(); JoinStates::Int ii = 1; // ii is used to make a JoinState value auto totalRooms = 0; auto totalEvents = 0; @@ -123,30 +123,31 @@ SyncRoomData::SyncRoomData(const QString& roomId_, JoinState joinState_, : roomId(roomId_) , joinState(joinState_) , state(load(room_, - joinState == JoinState::Invite ? "invite_state" : "state")) + joinState == JoinState::Invite ? "invite_state"_ls : "state"_ls)) { switch (joinState) { case JoinState::Join: - ephemeral = load(room_, "ephemeral"); - accountData = load(room_, "account_data"); + ephemeral = load(room_, "ephemeral"_ls); + accountData = load(room_, "account_data"_ls); FALLTHROUGH; case JoinState::Leave: { - timeline = load(room_, "timeline"); - auto timelineJson = room_.value("timeline").toObject(); - timelineLimited = timelineJson.value("limited").toBool(); - timelinePrevBatch = timelineJson.value("prev_batch").toString(); + timeline = load(room_, "timeline"_ls); + const auto timelineJson = room_.value("timeline"_ls).toObject(); + timelineLimited = timelineJson.value("limited"_ls).toBool(); + timelinePrevBatch = timelineJson.value("prev_batch"_ls).toString(); break; } default: /* nothing on top of state */; } - auto unreadJson = room_.value("unread_notifications").toObject(); + const auto unreadJson = room_.value("unread_notifications"_ls).toObject(); unreadCount = unreadJson.value(UnreadCountKey).toInt(-2); - highlightCount = unreadJson.value("highlight_count").toInt(); - notificationCount = unreadJson.value("notification_count").toInt(); + highlightCount = unreadJson.value("highlight_count"_ls).toInt(); + notificationCount = unreadJson.value("notification_count"_ls).toInt(); if (highlightCount > 0 || notificationCount > 0) - qCDebug(SYNCJOB) << "Highlights: " << highlightCount - << " Notifications:" << notificationCount; + qCDebug(SYNCJOB) << "Room" << roomId_ + << "has highlights:" << highlightCount + << "and notifications:" << notificationCount; } -- cgit v1.2.3 From 2cbb2a8c1be8bf08b1b835ffaa7bb0bee823e3a6 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 4 Jul 2018 19:46:08 +0900 Subject: Break down event.* into smaller files We now have event.*, roomevent.*, stateevent.* and eventloader.h. If you only use event leaf-classes (such as RoomMemberEvent) you shouldn't notice anything. --- CMakeLists.txt | 2 + lib/csapi/event_context.h | 2 +- lib/csapi/gtad.yaml | 8 +- lib/csapi/message_pagination.h | 2 +- lib/csapi/notifications.h | 2 +- lib/csapi/peeking_events.h | 2 +- lib/csapi/presence.h | 2 +- lib/csapi/rooms.h | 2 +- lib/csapi/search.h | 6 +- lib/events/accountdataevents.h | 1 + lib/events/directchatevent.cpp | 2 + lib/events/event.cpp | 79 ++----------------- lib/events/event.h | 174 +---------------------------------------- lib/events/eventloader.h | 57 ++++++++++++++ lib/events/receiptevent.cpp | 1 + lib/events/receiptevent.h | 1 + lib/events/roomevent.cpp | 82 +++++++++++++++++++ lib/events/roomevent.h | 89 +++++++++++++++++++++ lib/events/roommemberevent.cpp | 1 + lib/events/roommemberevent.h | 3 +- lib/events/roommessageevent.h | 3 +- lib/events/simplestateevents.h | 2 +- lib/events/stateevent.cpp | 30 +++++++ lib/events/stateevent.h | 92 ++++++++++++++++++++++ lib/events/typingevent.cpp | 2 + lib/jobs/syncjob.cpp | 2 + lib/jobs/syncjob.h | 2 +- libqmatrixclient.pri | 5 ++ 28 files changed, 391 insertions(+), 265 deletions(-) create mode 100644 lib/events/eventloader.h create mode 100644 lib/events/roomevent.cpp create mode 100644 lib/events/roomevent.h create mode 100644 lib/events/stateevent.cpp create mode 100644 lib/events/stateevent.h (limited to 'lib') diff --git a/CMakeLists.txt b/CMakeLists.txt index 54b69457..8b78b831 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,8 @@ set(libqmatrixclient_SRCS lib/converters.cpp lib/util.cpp lib/events/event.cpp + lib/events/roomevent.cpp + lib/events/stateevent.cpp lib/events/eventcontent.cpp lib/events/roommessageevent.cpp lib/events/roommemberevent.cpp 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" 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 #include 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 #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 -#include #include -#include "events/event.h" #include "converters.h" #include +#include +#include +#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 + using namespace QMatrixClient; QMultiHash 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 using namespace QMatrixClient; +event_type_t QMatrixClient::nextTypeId() +{ + static event_type_t _id = EventTypeTraits::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(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(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(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(); - -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::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 +#include 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 - inline event_ptr_tt loadEvent(const QJsonObject& fullJson) - { - return EventFactory - ::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 - inline event_ptr_tt loadEvent(const QString& matrixType, - const QJsonObject& content) - { - return EventFactory - ::make(basicEventJson(matrixType, content), matrixType); - } - - template struct FromJson> - { - auto operator()(const QJsonValue& jv) const - { - return loadEvent(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; - - // 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& 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 _redactedBecause; - QString _txnId; - }; - using RoomEventPtr = event_ptr_tt; - using RoomEvents = EventsArray; - using RoomEventsRange = Range; - - // === State events === - - class StateEventBase: public RoomEvent - { - public: - using factory_t = EventFactory; - - using RoomEvent::RoomEvent; - ~StateEventBase() override = default; - - bool isStateEvent() const override { return true; } - virtual bool repeatsState() const; - }; - using StateEventPtr = event_ptr_tt; - using StateEvents = EventsArray; - - template - struct Prev - { - template - explicit Prev(const QJsonObject& unsignedJson, - ContentParamTs&&... contentParams) - : senderId(unsignedJson.value("prev_sender"_ls).toString()) - , content(unsignedJson.value(PrevContentKeyL).toObject(), - std::forward(contentParams)...) - { } - - QString senderId; - ContentT content; - }; - - template - class StateEvent: public StateEventBase - { - public: - using content_type = ContentT; - - template - explicit StateEvent(Type type, const QJsonObject& fullJson, - ContentParamTs&&... contentParams) - : StateEventBase(type, fullJson) - , _content(contentJson(), - std::forward(contentParams)...) - { - const auto& unsignedData = unsignedJson(); - if (unsignedData.contains(PrevContentKeyL)) - _prev = std::make_unique>(unsignedData, - std::forward(contentParams)...); - } - template - explicit StateEvent(Type type, event_mtype_t matrixType, - ContentParamTs&&... contentParams) - : StateEventBase(type, matrixType) - , _content(std::forward(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; - }; } // 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 +* +* 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 + inline event_ptr_tt loadEvent(const QJsonObject& fullJson) + { + return EventFactory + ::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 + inline event_ptr_tt loadEvent(const QString& matrixType, + const QJsonObject& content) + { + return EventFactory + ::make(basicEventJson(matrixType, content), matrixType); + } + + template struct FromJson> + { + auto operator()(const QJsonValue& jv) const + { + return loadEvent(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 +#include 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 +* +* 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(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(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(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 +* +* 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; + + // 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& 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 _redactedBecause; + QString _txnId; + }; + using RoomEventPtr = event_ptr_tt; + using RoomEvents = EventsArray; + using RoomEventsRange = Range; +} // 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 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 +* +* 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(); + +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 +* +* 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; + + using RoomEvent::RoomEvent; + ~StateEventBase() override = default; + + bool isStateEvent() const override { return true; } + virtual bool repeatsState() const; + }; + using StateEventPtr = event_ptr_tt; + using StateEvents = EventsArray; + + template + struct Prev + { + template + explicit Prev(const QJsonObject& unsignedJson, + ContentParamTs&&... contentParams) + : senderId(unsignedJson.value("prev_sender"_ls).toString()) + , content(unsignedJson.value(PrevContentKeyL).toObject(), + std::forward(contentParams)...) + { } + + QString senderId; + ContentT content; + }; + + template + class StateEvent: public StateEventBase + { + public: + using content_type = ContentT; + + template + explicit StateEvent(Type type, const QJsonObject& fullJson, + ContentParamTs&&... contentParams) + : StateEventBase(type, fullJson) + , _content(contentJson(), + std::forward(contentParams)...) + { + const auto& unsignedData = unsignedJson(); + if (unsignedData.contains(PrevContentKeyL)) + _prev = std::make_unique>(unsignedData, + std::forward(contentParams)...); + } + template + explicit StateEvent(Type type, event_mtype_t matrixType, + ContentParamTs&&... contentParams) + : StateEventBase(type, matrixType) + , _content(std::forward(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; + }; +} // 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 + 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 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 diff --git a/libqmatrixclient.pri b/libqmatrixclient.pri index e61b50c8..4354b3f1 100644 --- a/libqmatrixclient.pri +++ b/libqmatrixclient.pri @@ -18,6 +18,8 @@ HEADERS += \ $$SRCPATH/avatar.h \ $$SRCPATH/util.h \ $$SRCPATH/events/event.h \ + $$SRCPATH/events/roomevent.h \ + $$SRCPATH/events/stateevent.h \ $$SRCPATH/events/eventcontent.h \ $$SRCPATH/events/roommessageevent.h \ $$SRCPATH/events/simplestateevents.h \ @@ -28,6 +30,7 @@ HEADERS += \ $$SRCPATH/events/accountdataevents.h \ $$SRCPATH/events/directchatevent.h \ $$SRCPATH/events/redactionevent.h \ + $$SRCPATH/events/eventloader.h \ $$SRCPATH/jobs/requestdata.h \ $$SRCPATH/jobs/basejob.h \ $$SRCPATH/jobs/sendeventjob.h \ @@ -51,6 +54,8 @@ SOURCES += \ $$SRCPATH/avatar.cpp \ $$SRCPATH/util.cpp \ $$SRCPATH/events/event.cpp \ + $$SRCPATH/events/roomevent.cpp \ + $$SRCPATH/events/stateevent.cpp \ $$SRCPATH/events/eventcontent.cpp \ $$SRCPATH/events/roommessageevent.cpp \ $$SRCPATH/events/roommemberevent.cpp \ -- cgit v1.2.3 From 5d1dd53890611376873f6f959e206d5a56cfff70 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 4 Jul 2018 21:05:20 +0900 Subject: Add #include to fix FTBFS with qmake --- lib/events/roomevent.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index ff50a83d..d2bc6edc 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -20,6 +20,8 @@ #include "event.h" +#include + namespace QMatrixClient { class RedactionEvent; -- cgit v1.2.3