aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/connection.cpp7
-rw-r--r--lib/converters.h6
-rw-r--r--lib/csapi/account-data.cpp8
-rw-r--r--lib/csapi/admin.cpp18
-rw-r--r--lib/csapi/administrative_contact.cpp28
-rw-r--r--lib/csapi/banning.cpp14
-rw-r--r--lib/csapi/content-repo.cpp46
-rw-r--r--lib/csapi/create_room.cpp40
-rw-r--r--lib/csapi/definitions/client_device.cpp16
-rw-r--r--lib/csapi/definitions/device_keys.cpp20
-rw-r--r--lib/csapi/definitions/event_filter.cpp20
-rw-r--r--lib/csapi/definitions/push_condition.cpp16
-rw-r--r--lib/csapi/definitions/push_rule.cpp24
-rw-r--r--lib/csapi/definitions/push_ruleset.cpp20
-rw-r--r--lib/csapi/definitions/room_event_filter.cpp12
-rw-r--r--lib/csapi/definitions/sync_filter.cpp48
-rw-r--r--lib/csapi/device_management.cpp34
-rw-r--r--lib/csapi/directory.cpp18
-rw-r--r--lib/csapi/event_context.cpp18
-rw-r--r--lib/csapi/event_context.h2
-rw-r--r--lib/csapi/filter.cpp14
-rw-r--r--lib/csapi/gtad.yaml8
-rw-r--r--lib/csapi/inviting.cpp6
-rw-r--r--lib/csapi/joining.cpp38
-rw-r--r--lib/csapi/keys.cpp54
-rw-r--r--lib/csapi/kicking.cpp8
-rw-r--r--lib/csapi/leaving.cpp8
-rw-r--r--lib/csapi/list_joined_rooms.cpp8
-rw-r--r--lib/csapi/list_public_rooms.cpp92
-rw-r--r--lib/csapi/login.cpp28
-rw-r--r--lib/csapi/logout.cpp8
-rw-r--r--lib/csapi/message_pagination.cpp20
-rw-r--r--lib/csapi/message_pagination.h2
-rw-r--r--lib/csapi/notifications.cpp28
-rw-r--r--lib/csapi/notifications.h2
-rw-r--r--lib/csapi/peeking_events.cpp16
-rw-r--r--lib/csapi/peeking_events.h2
-rw-r--r--lib/csapi/presence.cpp38
-rw-r--r--lib/csapi/presence.h2
-rw-r--r--lib/csapi/profile.cpp32
-rw-r--r--lib/csapi/pusher.cpp48
-rw-r--r--lib/csapi/pushrules.cpp62
-rw-r--r--lib/csapi/receipts.cpp4
-rw-r--r--lib/csapi/redaction.cpp8
-rw-r--r--lib/csapi/registration.cpp64
-rw-r--r--lib/csapi/report_content.cpp8
-rw-r--r--lib/csapi/room_send.cpp6
-rw-r--r--lib/csapi/room_state.cpp12
-rw-r--r--lib/csapi/rooms.cpp48
-rw-r--r--lib/csapi/rooms.h2
-rw-r--r--lib/csapi/search.cpp76
-rw-r--r--lib/csapi/search.h6
-rw-r--r--lib/csapi/tags.cpp14
-rw-r--r--lib/csapi/third_party_membership.cpp10
-rw-r--r--lib/csapi/to_device.cpp6
-rw-r--r--lib/csapi/typing.cpp8
-rw-r--r--lib/csapi/users.cpp22
-rw-r--r--lib/csapi/versions.cpp6
-rw-r--r--lib/csapi/voip.cpp8
-rw-r--r--lib/csapi/whoami.cpp8
-rw-r--r--lib/csapi/{{base}}.cpp.mustache20
-rw-r--r--lib/events/accountdataevents.h42
-rw-r--r--lib/events/directchatevent.cpp8
-rw-r--r--lib/events/directchatevent.h10
-rw-r--r--lib/events/event.cpp161
-rw-r--r--lib/events/event.h403
-rw-r--r--lib/events/eventcontent.cpp25
-rw-r--r--lib/events/eventcontent.h36
-rw-r--r--lib/events/eventloader.h57
-rw-r--r--lib/events/receiptevent.cpp11
-rw-r--r--lib/events/receiptevent.h8
-rw-r--r--lib/events/redactionevent.h18
-rw-r--r--lib/events/roomavatarevent.h11
-rw-r--r--lib/events/roomevent.cpp82
-rw-r--r--lib/events/roomevent.h91
-rw-r--r--lib/events/roommemberevent.cpp15
-rw-r--r--lib/events/roommemberevent.h27
-rw-r--r--lib/events/roommessageevent.cpp88
-rw-r--r--lib/events/roommessageevent.h30
-rw-r--r--lib/events/simplestateevents.h72
-rw-r--r--lib/events/stateevent.cpp30
-rw-r--r--lib/events/stateevent.h92
-rw-r--r--lib/events/typingevent.cpp10
-rw-r--r--lib/events/typingevent.h8
-rw-r--r--lib/jobs/basejob.cpp25
-rw-r--r--lib/jobs/sendeventjob.cpp2
-rw-r--r--lib/jobs/sendeventjob.h4
-rw-r--r--lib/jobs/syncjob.cpp47
-rw-r--r--lib/jobs/syncjob.h2
-rw-r--r--lib/room.cpp247
-rw-r--r--lib/room.h12
-rw-r--r--lib/user.h8
-rw-r--r--lib/util.h41
93 files changed, 1740 insertions, 1258 deletions
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<AccountDataMap>(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<SendToDeviceJob>(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 <QtCore/QJsonObject>
#include <QtCore/QJsonArray> // Includes <QtCore/QJsonValue>
#include <QtCore/QDate>
#include <QtCore/QUrlQuery>
+#include <QtCore/QSet>
+#include <QtCore/QVector>
#include <unordered_map>
#include <vector>
@@ -351,7 +355,7 @@ namespace QMatrixClient
template <typename ValT>
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/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<QString>(_json.value("ip"));
+ fromJson<QString>(_json.value("ip"_ls));
result.lastSeen =
- fromJson<qint64>(_json.value("last_seen"));
+ fromJson<qint64>(_json.value("last_seen"_ls));
result.userAgent =
- fromJson<QString>(_json.value("user_agent"));
+ fromJson<QString>(_json.value("user_agent"_ls));
return result;
}
@@ -40,7 +40,7 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
GetWhoIsJob::SessionInfo result;
result.connections =
- fromJson<QVector<GetWhoIsJob::ConnectionInfo>>(_json.value("connections"));
+ fromJson<QVector<GetWhoIsJob::ConnectionInfo>>(_json.value("connections"_ls));
return result;
}
@@ -53,7 +53,7 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
GetWhoIsJob::DeviceInfo result;
result.sessions =
- fromJson<QVector<GetWhoIsJob::SessionInfo>>(_json.value("sessions"));
+ fromJson<QVector<GetWhoIsJob::SessionInfo>>(_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<QString, GetWhoIsJob::DeviceInfo>& GetWhoIsJob::devices() const
BaseJob::Status GetWhoIsJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->userId = fromJson<QString>(json.value("user_id"));
- d->devices = fromJson<QHash<QString, DeviceInfo>>(json.value("devices"));
+ d->userId = fromJson<QString>(json.value("user_id"_ls));
+ d->devices = fromJson<QHash<QString, DeviceInfo>>(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<QString>(_json.value("medium"));
+ fromJson<QString>(_json.value("medium"_ls));
result.address =
- fromJson<QString>(_json.value("address"));
+ fromJson<QString>(_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::ThirdPartyIdentifier>& GetAccount3PIDsJob::thr
BaseJob::Status GetAccount3PIDsJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->threepids = fromJson<QVector<ThirdPartyIdentifier>>(json.value("threepids"));
+ d->threepids = fromJson<QVector<ThirdPartyIdentifier>>(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<IfNotEmpty>(_data, "bind", bind);
+ addParam<>(_data, QStringLiteral("three_pid_creds"), threePidCreds);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "reason", reason);
+ addParam<>(_data, QStringLiteral("user_id"), userId);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_q, "filename", filename);
+ addParam<IfNotEmpty>(_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<QString>(json.value("content_uri"));
+ d->contentUri = fromJson<QString>(json.value("content_uri"_ls));
return Success;
}
@@ -65,7 +67,7 @@ class GetContentJob::Private
BaseJob::Query queryToGetContent(bool allowRemote)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "allow_remote", allowRemote);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_q, "allow_remote", allowRemote);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_q, "method", method);
- addParam<IfNotEmpty>(_q, "allow_remote", allowRemote);
+ addParam<>(_q, QStringLiteral("width"), width);
+ addParam<>(_q, QStringLiteral("height"), height);
+ addParam<IfNotEmpty>(_q, QStringLiteral("method"), method);
+ addParam<IfNotEmpty>(_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<qint64> ts)
{
BaseJob::Query _q;
- addParam<>(_q, "url", url);
- addParam<IfNotEmpty>(_q, "ts", ts);
+ addParam<>(_q, QStringLiteral("url"), url);
+ addParam<IfNotEmpty>(_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<qint64> 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<qint64>(json.value("matrix:image:size"));
- d->ogImage = fromJson<QString>(json.value("og:image"));
+ d->matrixImageSize = fromJson<qint64>(json.value("matrix:image:size"_ls));
+ d->ogImage = fromJson<QString>(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<IfNotEmpty>(_json, "type", pod.type);
- addParam<IfNotEmpty>(_json, "state_key", pod.stateKey);
- addParam<IfNotEmpty>(_json, "content", pod.content);
+ addParam<IfNotEmpty>(_json, QStringLiteral("type"), pod.type);
+ addParam<IfNotEmpty>(_json, QStringLiteral("state_key"), pod.stateKey);
+ addParam<IfNotEmpty>(_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>& invite3pid, const QJsonObject& creationContent, const QVector<StateEvent>& initialState, const QString& preset, bool isDirect, bool guestCanJoin)
- : BaseJob(HttpVerb::Post, "CreateRoomJob",
+ : BaseJob(HttpVerb::Post, CreateRoomJobName,
basePath % "/createRoom")
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "visibility", visibility);
- addParam<IfNotEmpty>(_data, "room_alias_name", roomAliasName);
- addParam<IfNotEmpty>(_data, "name", name);
- addParam<IfNotEmpty>(_data, "topic", topic);
- addParam<IfNotEmpty>(_data, "invite", invite);
- addParam<IfNotEmpty>(_data, "invite_3pid", invite3pid);
- addParam<IfNotEmpty>(_data, "creation_content", creationContent);
- addParam<IfNotEmpty>(_data, "initial_state", initialState);
- addParam<IfNotEmpty>(_data, "preset", preset);
- addParam<IfNotEmpty>(_data, "is_direct", isDirect);
- addParam<IfNotEmpty>(_data, "guest_can_join", guestCanJoin);
+ addParam<IfNotEmpty>(_data, QStringLiteral("visibility"), visibility);
+ addParam<IfNotEmpty>(_data, QStringLiteral("room_alias_name"), roomAliasName);
+ addParam<IfNotEmpty>(_data, QStringLiteral("name"), name);
+ addParam<IfNotEmpty>(_data, QStringLiteral("topic"), topic);
+ addParam<IfNotEmpty>(_data, QStringLiteral("invite"), invite);
+ addParam<IfNotEmpty>(_data, QStringLiteral("invite_3pid"), invite3pid);
+ addParam<IfNotEmpty>(_data, QStringLiteral("creation_content"), creationContent);
+ addParam<IfNotEmpty>(_data, QStringLiteral("initial_state"), initialState);
+ addParam<IfNotEmpty>(_data, QStringLiteral("preset"), preset);
+ addParam<IfNotEmpty>(_data, QStringLiteral("is_direct"), isDirect);
+ addParam<IfNotEmpty>(_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<QString>(json.value("room_id"));
+ d->roomId = fromJson<QString>(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<IfNotEmpty>(_json, "display_name", pod.displayName);
- addParam<IfNotEmpty>(_json, "last_seen_ip", pod.lastSeenIp);
- addParam<IfNotEmpty>(_json, "last_seen_ts", pod.lastSeenTs);
+ addParam<>(_json, QStringLiteral("device_id"), pod.deviceId);
+ addParam<IfNotEmpty>(_json, QStringLiteral("display_name"), pod.displayName);
+ addParam<IfNotEmpty>(_json, QStringLiteral("last_seen_ip"), pod.lastSeenIp);
+ addParam<IfNotEmpty>(_json, QStringLiteral("last_seen_ts"), pod.lastSeenTs);
return _json;
}
@@ -21,13 +21,13 @@ Device FromJson<Device>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
Device result;
result.deviceId =
- fromJson<QString>(_json.value("device_id"));
+ fromJson<QString>(_json.value("device_id"_ls));
result.displayName =
- fromJson<QString>(_json.value("display_name"));
+ fromJson<QString>(_json.value("display_name"_ls));
result.lastSeenIp =
- fromJson<QString>(_json.value("last_seen_ip"));
+ fromJson<QString>(_json.value("last_seen_ip"_ls));
result.lastSeenTs =
- fromJson<qint64>(_json.value("last_seen_ts"));
+ fromJson<qint64>(_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<DeviceKeys>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
DeviceKeys result;
result.userId =
- fromJson<QString>(_json.value("user_id"));
+ fromJson<QString>(_json.value("user_id"_ls));
result.deviceId =
- fromJson<QString>(_json.value("device_id"));
+ fromJson<QString>(_json.value("device_id"_ls));
result.algorithms =
- fromJson<QStringList>(_json.value("algorithms"));
+ fromJson<QStringList>(_json.value("algorithms"_ls));
result.keys =
- fromJson<QHash<QString, QString>>(_json.value("keys"));
+ fromJson<QHash<QString, QString>>(_json.value("keys"_ls));
result.signatures =
- fromJson<QHash<QString, QHash<QString, QString>>>(_json.value("signatures"));
+ fromJson<QHash<QString, QHash<QString, QString>>>(_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<IfNotEmpty>(_json, "limit", pod.limit);
- addParam<IfNotEmpty>(_json, "not_senders", pod.notSenders);
- addParam<IfNotEmpty>(_json, "not_types", pod.notTypes);
- addParam<IfNotEmpty>(_json, "senders", pod.senders);
- addParam<IfNotEmpty>(_json, "types", pod.types);
+ addParam<IfNotEmpty>(_json, QStringLiteral("limit"), pod.limit);
+ addParam<IfNotEmpty>(_json, QStringLiteral("not_senders"), pod.notSenders);
+ addParam<IfNotEmpty>(_json, QStringLiteral("not_types"), pod.notTypes);
+ addParam<IfNotEmpty>(_json, QStringLiteral("senders"), pod.senders);
+ addParam<IfNotEmpty>(_json, QStringLiteral("types"), pod.types);
return _json;
}
@@ -22,15 +22,15 @@ Filter FromJson<Filter>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
Filter result;
result.limit =
- fromJson<int>(_json.value("limit"));
+ fromJson<int>(_json.value("limit"_ls));
result.notSenders =
- fromJson<QStringList>(_json.value("not_senders"));
+ fromJson<QStringList>(_json.value("not_senders"_ls));
result.notTypes =
- fromJson<QStringList>(_json.value("not_types"));
+ fromJson<QStringList>(_json.value("not_types"_ls));
result.senders =
- fromJson<QStringList>(_json.value("senders"));
+ fromJson<QStringList>(_json.value("senders"_ls));
result.types =
- fromJson<QStringList>(_json.value("types"));
+ fromJson<QStringList>(_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<IfNotEmpty>(_json, "key", pod.key);
- addParam<IfNotEmpty>(_json, "pattern", pod.pattern);
- addParam<IfNotEmpty>(_json, "is", pod.is);
+ addParam<>(_json, QStringLiteral("kind"), pod.kind);
+ addParam<IfNotEmpty>(_json, QStringLiteral("key"), pod.key);
+ addParam<IfNotEmpty>(_json, QStringLiteral("pattern"), pod.pattern);
+ addParam<IfNotEmpty>(_json, QStringLiteral("is"), pod.is);
return _json;
}
@@ -21,13 +21,13 @@ PushCondition FromJson<PushCondition>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
PushCondition result;
result.kind =
- fromJson<QString>(_json.value("kind"));
+ fromJson<QString>(_json.value("kind"_ls));
result.key =
- fromJson<QString>(_json.value("key"));
+ fromJson<QString>(_json.value("key"_ls));
result.pattern =
- fromJson<QString>(_json.value("pattern"));
+ fromJson<QString>(_json.value("pattern"_ls));
result.is =
- fromJson<QString>(_json.value("is"));
+ fromJson<QString>(_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<IfNotEmpty>(_json, "conditions", pod.conditions);
- addParam<IfNotEmpty>(_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<IfNotEmpty>(_json, QStringLiteral("conditions"), pod.conditions);
+ addParam<IfNotEmpty>(_json, QStringLiteral("pattern"), pod.pattern);
return _json;
}
@@ -23,17 +23,17 @@ PushRule FromJson<PushRule>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
PushRule result;
result.actions =
- fromJson<QVector<QVariant>>(_json.value("actions"));
+ fromJson<QVector<QVariant>>(_json.value("actions"_ls));
result.isDefault =
- fromJson<bool>(_json.value("default"));
+ fromJson<bool>(_json.value("default"_ls));
result.enabled =
- fromJson<bool>(_json.value("enabled"));
+ fromJson<bool>(_json.value("enabled"_ls));
result.ruleId =
- fromJson<QString>(_json.value("rule_id"));
+ fromJson<QString>(_json.value("rule_id"_ls));
result.conditions =
- fromJson<QVector<PushCondition>>(_json.value("conditions"));
+ fromJson<QVector<PushCondition>>(_json.value("conditions"_ls));
result.pattern =
- fromJson<QString>(_json.value("pattern"));
+ fromJson<QString>(_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<IfNotEmpty>(_json, "content", pod.content);
- addParam<IfNotEmpty>(_json, "override", pod.override);
- addParam<IfNotEmpty>(_json, "room", pod.room);
- addParam<IfNotEmpty>(_json, "sender", pod.sender);
- addParam<IfNotEmpty>(_json, "underride", pod.underride);
+ addParam<IfNotEmpty>(_json, QStringLiteral("content"), pod.content);
+ addParam<IfNotEmpty>(_json, QStringLiteral("override"), pod.override);
+ addParam<IfNotEmpty>(_json, QStringLiteral("room"), pod.room);
+ addParam<IfNotEmpty>(_json, QStringLiteral("sender"), pod.sender);
+ addParam<IfNotEmpty>(_json, QStringLiteral("underride"), pod.underride);
return _json;
}
@@ -22,15 +22,15 @@ PushRuleset FromJson<PushRuleset>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
PushRuleset result;
result.content =
- fromJson<QVector<PushRule>>(_json.value("content"));
+ fromJson<QVector<PushRule>>(_json.value("content"_ls));
result.override =
- fromJson<QVector<PushRule>>(_json.value("override"));
+ fromJson<QVector<PushRule>>(_json.value("override"_ls));
result.room =
- fromJson<QVector<PushRule>>(_json.value("room"));
+ fromJson<QVector<PushRule>>(_json.value("room"_ls));
result.sender =
- fromJson<QVector<PushRule>>(_json.value("sender"));
+ fromJson<QVector<PushRule>>(_json.value("sender"_ls));
result.underride =
- fromJson<QVector<PushRule>>(_json.value("underride"));
+ fromJson<QVector<PushRule>>(_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<IfNotEmpty>(_json, "not_rooms", pod.notRooms);
- addParam<IfNotEmpty>(_json, "rooms", pod.rooms);
- addParam<IfNotEmpty>(_json, "contains_url", pod.containsUrl);
+ addParam<IfNotEmpty>(_json, QStringLiteral("not_rooms"), pod.notRooms);
+ addParam<IfNotEmpty>(_json, QStringLiteral("rooms"), pod.rooms);
+ addParam<IfNotEmpty>(_json, QStringLiteral("contains_url"), pod.containsUrl);
return _json;
}
@@ -20,11 +20,11 @@ RoomEventFilter FromJson<RoomEventFilter>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
RoomEventFilter result;
result.notRooms =
- fromJson<QStringList>(_json.value("not_rooms"));
+ fromJson<QStringList>(_json.value("not_rooms"_ls));
result.rooms =
- fromJson<QStringList>(_json.value("rooms"));
+ fromJson<QStringList>(_json.value("rooms"_ls));
result.containsUrl =
- fromJson<bool>(_json.value("contains_url"));
+ fromJson<bool>(_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<IfNotEmpty>(_json, "not_rooms", pod.notRooms);
- addParam<IfNotEmpty>(_json, "rooms", pod.rooms);
- addParam<IfNotEmpty>(_json, "ephemeral", pod.ephemeral);
- addParam<IfNotEmpty>(_json, "include_leave", pod.includeLeave);
- addParam<IfNotEmpty>(_json, "state", pod.state);
- addParam<IfNotEmpty>(_json, "timeline", pod.timeline);
- addParam<IfNotEmpty>(_json, "account_data", pod.accountData);
+ addParam<IfNotEmpty>(_json, QStringLiteral("not_rooms"), pod.notRooms);
+ addParam<IfNotEmpty>(_json, QStringLiteral("rooms"), pod.rooms);
+ addParam<IfNotEmpty>(_json, QStringLiteral("ephemeral"), pod.ephemeral);
+ addParam<IfNotEmpty>(_json, QStringLiteral("include_leave"), pod.includeLeave);
+ addParam<IfNotEmpty>(_json, QStringLiteral("state"), pod.state);
+ addParam<IfNotEmpty>(_json, QStringLiteral("timeline"), pod.timeline);
+ addParam<IfNotEmpty>(_json, QStringLiteral("account_data"), pod.accountData);
return _json;
}
@@ -24,19 +24,19 @@ RoomFilter FromJson<RoomFilter>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
RoomFilter result;
result.notRooms =
- fromJson<QStringList>(_json.value("not_rooms"));
+ fromJson<QStringList>(_json.value("not_rooms"_ls));
result.rooms =
- fromJson<QStringList>(_json.value("rooms"));
+ fromJson<QStringList>(_json.value("rooms"_ls));
result.ephemeral =
- fromJson<RoomEventFilter>(_json.value("ephemeral"));
+ fromJson<RoomEventFilter>(_json.value("ephemeral"_ls));
result.includeLeave =
- fromJson<bool>(_json.value("include_leave"));
+ fromJson<bool>(_json.value("include_leave"_ls));
result.state =
- fromJson<RoomEventFilter>(_json.value("state"));
+ fromJson<RoomEventFilter>(_json.value("state"_ls));
result.timeline =
- fromJson<RoomEventFilter>(_json.value("timeline"));
+ fromJson<RoomEventFilter>(_json.value("timeline"_ls));
result.accountData =
- fromJson<RoomEventFilter>(_json.value("account_data"));
+ fromJson<RoomEventFilter>(_json.value("account_data"_ls));
return result;
}
@@ -44,11 +44,11 @@ RoomFilter FromJson<RoomFilter>::operator()(const QJsonValue& jv)
QJsonObject QMatrixClient::toJson(const SyncFilter& pod)
{
QJsonObject _json;
- addParam<IfNotEmpty>(_json, "event_fields", pod.eventFields);
- addParam<IfNotEmpty>(_json, "event_format", pod.eventFormat);
- addParam<IfNotEmpty>(_json, "presence", pod.presence);
- addParam<IfNotEmpty>(_json, "account_data", pod.accountData);
- addParam<IfNotEmpty>(_json, "room", pod.room);
+ addParam<IfNotEmpty>(_json, QStringLiteral("event_fields"), pod.eventFields);
+ addParam<IfNotEmpty>(_json, QStringLiteral("event_format"), pod.eventFormat);
+ addParam<IfNotEmpty>(_json, QStringLiteral("presence"), pod.presence);
+ addParam<IfNotEmpty>(_json, QStringLiteral("account_data"), pod.accountData);
+ addParam<IfNotEmpty>(_json, QStringLiteral("room"), pod.room);
return _json;
}
@@ -57,15 +57,15 @@ SyncFilter FromJson<SyncFilter>::operator()(const QJsonValue& jv)
const auto& _json = jv.toObject();
SyncFilter result;
result.eventFields =
- fromJson<QStringList>(_json.value("event_fields"));
+ fromJson<QStringList>(_json.value("event_fields"_ls));
result.eventFormat =
- fromJson<QString>(_json.value("event_format"));
+ fromJson<QString>(_json.value("event_format"_ls));
result.presence =
- fromJson<Filter>(_json.value("presence"));
+ fromJson<Filter>(_json.value("presence"_ls));
result.accountData =
- fromJson<Filter>(_json.value("account_data"));
+ fromJson<Filter>(_json.value("account_data"_ls));
result.room =
- fromJson<RoomFilter>(_json.value("room"));
+ fromJson<RoomFilter>(_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<Device>& GetDevicesJob::devices() const
BaseJob::Status GetDevicesJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->devices = fromJson<QVector<Device>>(json.value("devices"));
+ d->devices = fromJson<QVector<Device>>(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<Device>(json.value("data"));
+ d->data = fromJson<Device>(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<IfNotEmpty>(_data, "display_name", displayName);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "auth", auth);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "auth", auth);
+ addParam<>(_data, QStringLiteral("devices"), devices);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "room_id", roomId);
+ addParam<IfNotEmpty>(_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<QString>(json.value("room_id"));
- d->servers = fromJson<QStringList>(json.value("servers"));
+ d->roomId = fromJson<QString>(json.value("room_id"_ls));
+ d->servers = fromJson<QStringList>(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<int> limit)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "limit", limit);
+ addParam<IfNotEmpty>(_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<int> 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<QString>(json.value("start"));
- d->end = fromJson<QString>(json.value("end"));
- d->eventsBefore = fromJson<RoomEvents>(json.value("events_before"));
- d->event = fromJson<RoomEventPtr>(json.value("event"));
- d->eventsAfter = fromJson<RoomEvents>(json.value("events_after"));
- d->state = fromJson<StateEvents>(json.value("state"));
+ d->begin = fromJson<QString>(json.value("start"_ls));
+ d->end = fromJson<QString>(json.value("end"_ls));
+ d->eventsBefore = fromJson<RoomEvents>(json.value("events_before"_ls));
+ d->event = fromJson<RoomEventPtr>(json.value("event"_ls));
+ d->eventsAfter = fromJson<RoomEvents>(json.value("events_after"_ls));
+ d->state = fromJson<StateEvents>(json.value("state"_ls));
return Success;
}
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/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<QString>(json.value("filter_id"));
+ d->filterId = fromJson<QString>(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<SyncFilter>(json.value("data"));
+ d->data = fromJson<SyncFilter>(json.value("data"_ls));
return Success;
}
diff --git a/lib/csapi/gtad.yaml b/lib/csapi/gtad.yaml
index 3d1b7e88..09344be5 100644
--- a/lib/csapi/gtad.yaml
+++ b/lib/csapi/gtad.yaml
@@ -62,11 +62,11 @@ analyzer:
- +set: { moveOnly: }
+on:
- /state_event.yaml$/:
- { type: StateEventPtr, imports: '"events/event.h"' }
+ { type: StateEventPtr, imports: '"events/eventloader.h"' }
- /room_event.yaml$/:
- { type: RoomEventPtr, imports: '"events/event.h"' }
+ { type: RoomEventPtr, imports: '"events/eventloader.h"' }
- /event.yaml$/:
- { type: EventPtr, imports: '"events/event.h"' }
+ { type: EventPtr, imports: '"events/eventloader.h"' }
- /auth_data.yaml$/: *QJsonObject # GTAD 0.6 cannot cope with this one
- /m\.room\.member$/: pass # This $ref is only used in an array, see below
- //: *UseOmittable # Also apply "avoidCopy" to all other ref'ed types
@@ -79,7 +79,7 @@ analyzer:
+on:
- /^Notification|Result$/:
type: "std::vector<{{1}}>"
- imports: '"events/event.h"'
+ imports: '"events/eventloader.h"'
- /m\.room\.member$/:
type: "EventsArray<RoomMemberEvent>"
imports: '"events/roommemberevent.h"'
diff --git a/lib/csapi/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>& thirdPartySigned)
- : BaseJob(HttpVerb::Post, "JoinRoomByIdJob",
+ : BaseJob(HttpVerb::Post, JoinRoomByIdJobName,
basePath % "/rooms/" % roomId % "/join")
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "third_party_signed", thirdPartySigned);
+ addParam<IfNotEmpty>(_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<QString>(json.value("room_id"));
+ d->roomId = fromJson<QString>(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>& thirdPartySigned)
- : BaseJob(HttpVerb::Post, "JoinRoomJob",
+ : BaseJob(HttpVerb::Post, JoinRoomJobName,
basePath % "/join/" % roomIdOrAlias)
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "third_party_signed", thirdPartySigned);
+ addParam<IfNotEmpty>(_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<QString>(json.value("room_id"));
+ d->roomId = fromJson<QString>(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<QString, int> oneTimeKeyCounts;
};
+static const auto UploadKeysJobName = QStringLiteral("UploadKeysJob");
+
UploadKeysJob::UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys, const QHash<QString, QVariant>& oneTimeKeys)
- : BaseJob(HttpVerb::Post, "UploadKeysJob",
+ : BaseJob(HttpVerb::Post, UploadKeysJobName,
basePath % "/keys/upload")
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "device_keys", deviceKeys);
- addParam<IfNotEmpty>(_data, "one_time_keys", oneTimeKeys);
+ addParam<IfNotEmpty>(_data, QStringLiteral("device_keys"), deviceKeys);
+ addParam<IfNotEmpty>(_data, QStringLiteral("one_time_keys"), oneTimeKeys);
setRequestData(_data);
}
@@ -39,10 +41,10 @@ const QHash<QString, int>& 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<QHash<QString, int>>(json.value("one_time_key_counts"));
+ d->oneTimeKeyCounts = fromJson<QHash<QString, int>>(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<QString>(_json.value("device_display_name"));
+ fromJson<QString>(_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<QueryKeysJob::UnsignedDeviceInfo>(_json.value("unsigned"));
+ fromJson<QueryKeysJob::UnsignedDeviceInfo>(_json.value("unsigned"_ls));
return result;
}
@@ -84,15 +86,17 @@ class QueryKeysJob::Private
QHash<QString, QHash<QString, DeviceInformation>> deviceKeys;
};
+static const auto QueryKeysJobName = QStringLiteral("QueryKeysJob");
+
QueryKeysJob::QueryKeysJob(const QHash<QString, QStringList>& deviceKeys, Omittable<int> timeout, const QString& token)
- : BaseJob(HttpVerb::Post, "QueryKeysJob",
+ : BaseJob(HttpVerb::Post, QueryKeysJobName,
basePath % "/keys/query")
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "timeout", timeout);
- addParam<>(_data, "device_keys", deviceKeys);
- addParam<IfNotEmpty>(_data, "token", token);
+ addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout);
+ addParam<>(_data, QStringLiteral("device_keys"), deviceKeys);
+ addParam<IfNotEmpty>(_data, QStringLiteral("token"), token);
setRequestData(_data);
}
@@ -111,8 +115,8 @@ const QHash<QString, QHash<QString, QueryKeysJob::DeviceInformation>>& QueryKeys
BaseJob::Status QueryKeysJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->failures = fromJson<QHash<QString, QJsonObject>>(json.value("failures"));
- d->deviceKeys = fromJson<QHash<QString, QHash<QString, DeviceInformation>>>(json.value("device_keys"));
+ d->failures = fromJson<QHash<QString, QJsonObject>>(json.value("failures"_ls));
+ d->deviceKeys = fromJson<QHash<QString, QHash<QString, DeviceInformation>>>(json.value("device_keys"_ls));
return Success;
}
@@ -123,14 +127,16 @@ class ClaimKeysJob::Private
QHash<QString, QHash<QString, QVariant>> oneTimeKeys;
};
+static const auto ClaimKeysJobName = QStringLiteral("ClaimKeysJob");
+
ClaimKeysJob::ClaimKeysJob(const QHash<QString, QHash<QString, QString>>& oneTimeKeys, Omittable<int> timeout)
- : BaseJob(HttpVerb::Post, "ClaimKeysJob",
+ : BaseJob(HttpVerb::Post, ClaimKeysJobName,
basePath % "/keys/claim")
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "timeout", timeout);
- addParam<>(_data, "one_time_keys", oneTimeKeys);
+ addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout);
+ addParam<>(_data, QStringLiteral("one_time_keys"), oneTimeKeys);
setRequestData(_data);
}
@@ -149,8 +155,8 @@ const QHash<QString, QHash<QString, QVariant>>& ClaimKeysJob::oneTimeKeys() cons
BaseJob::Status ClaimKeysJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->failures = fromJson<QHash<QString, QJsonObject>>(json.value("failures"));
- d->oneTimeKeys = fromJson<QHash<QString, QHash<QString, QVariant>>>(json.value("one_time_keys"));
+ d->failures = fromJson<QHash<QString, QJsonObject>>(json.value("failures"_ls));
+ d->oneTimeKeys = fromJson<QHash<QString, QHash<QString, QVariant>>>(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<QStringList>(json.value("changed"));
- d->left = fromJson<QStringList>(json.value("left"));
+ d->changed = fromJson<QStringList>(json.value("changed"_ls));
+ d->left = fromJson<QStringList>(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<IfNotEmpty>(_data, "reason", reason);
+ addParam<>(_data, QStringLiteral("user_id"), userId);
+ addParam<IfNotEmpty>(_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<QStringList>(json.value("joined_rooms"));
+ d->joinedRooms = fromJson<QStringList>(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<QString>(json.value("visibility"));
+ d->visibility = fromJson<QString>(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<IfNotEmpty>(_data, "visibility", visibility);
+ addParam<IfNotEmpty>(_data, QStringLiteral("visibility"), visibility);
setRequestData(_data);
}
@@ -65,23 +69,23 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
GetPublicRoomsJob::PublicRoomsChunk result;
result.aliases =
- fromJson<QStringList>(_json.value("aliases"));
+ fromJson<QStringList>(_json.value("aliases"_ls));
result.canonicalAlias =
- fromJson<QString>(_json.value("canonical_alias"));
+ fromJson<QString>(_json.value("canonical_alias"_ls));
result.name =
- fromJson<QString>(_json.value("name"));
+ fromJson<QString>(_json.value("name"_ls));
result.numJoinedMembers =
- fromJson<qint64>(_json.value("num_joined_members"));
+ fromJson<qint64>(_json.value("num_joined_members"_ls));
result.roomId =
- fromJson<QString>(_json.value("room_id"));
+ fromJson<QString>(_json.value("room_id"_ls));
result.topic =
- fromJson<QString>(_json.value("topic"));
+ fromJson<QString>(_json.value("topic"_ls));
result.worldReadable =
- fromJson<bool>(_json.value("world_readable"));
+ fromJson<bool>(_json.value("world_readable"_ls));
result.guestCanJoin =
- fromJson<bool>(_json.value("guest_can_join"));
+ fromJson<bool>(_json.value("guest_can_join"_ls));
result.avatarUrl =
- fromJson<QString>(_json.value("avatar_url"));
+ fromJson<QString>(_json.value("avatar_url"_ls));
return result;
}
@@ -100,9 +104,9 @@ class GetPublicRoomsJob::Private
BaseJob::Query queryToGetPublicRooms(Omittable<int> limit, const QString& since, const QString& server)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "limit", limit);
- addParam<IfNotEmpty>(_q, "since", since);
- addParam<IfNotEmpty>(_q, "server", server);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("since"), since);
+ addParam<IfNotEmpty>(_q, QStringLiteral("server"), server);
return _q;
}
@@ -113,8 +117,10 @@ QUrl GetPublicRoomsJob::makeRequestUrl(QUrl baseUrl, Omittable<int> limit, const
queryToGetPublicRooms(limit, since, server));
}
+static const auto GetPublicRoomsJobName = QStringLiteral("GetPublicRoomsJob");
+
GetPublicRoomsJob::GetPublicRoomsJob(Omittable<int> 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<qint64> 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<QVector<PublicRoomsChunk>>(json.value("chunk"));
- d->nextBatch = fromJson<QString>(json.value("next_batch"));
- d->prevBatch = fromJson<QString>(json.value("prev_batch"));
- d->totalRoomCountEstimate = fromJson<qint64>(json.value("total_room_count_estimate"));
+ d->chunk = fromJson<QVector<PublicRoomsChunk>>(json.value("chunk"_ls));
+ d->nextBatch = fromJson<QString>(json.value("next_batch"_ls));
+ d->prevBatch = fromJson<QString>(json.value("prev_batch"_ls));
+ d->totalRoomCountEstimate = fromJson<qint64>(json.value("total_room_count_estimate"_ls));
return Success;
}
@@ -164,7 +170,7 @@ namespace QMatrixClient
QJsonObject toJson(const QueryPublicRoomsJob::Filter& pod)
{
QJsonObject _json;
- addParam<IfNotEmpty>(_json, "generic_search_term", pod.genericSearchTerm);
+ addParam<IfNotEmpty>(_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<QStringList>(_json.value("aliases"));
+ fromJson<QStringList>(_json.value("aliases"_ls));
result.canonicalAlias =
- fromJson<QString>(_json.value("canonical_alias"));
+ fromJson<QString>(_json.value("canonical_alias"_ls));
result.name =
- fromJson<QString>(_json.value("name"));
+ fromJson<QString>(_json.value("name"_ls));
result.numJoinedMembers =
- fromJson<qint64>(_json.value("num_joined_members"));
+ fromJson<qint64>(_json.value("num_joined_members"_ls));
result.roomId =
- fromJson<QString>(_json.value("room_id"));
+ fromJson<QString>(_json.value("room_id"_ls));
result.topic =
- fromJson<QString>(_json.value("topic"));
+ fromJson<QString>(_json.value("topic"_ls));
result.worldReadable =
- fromJson<bool>(_json.value("world_readable"));
+ fromJson<bool>(_json.value("world_readable"_ls));
result.guestCanJoin =
- fromJson<bool>(_json.value("guest_can_join"));
+ fromJson<bool>(_json.value("guest_can_join"_ls));
result.avatarUrl =
- fromJson<QString>(_json.value("avatar_url"));
+ fromJson<QString>(_json.value("avatar_url"_ls));
return result;
}
@@ -210,20 +216,22 @@ class QueryPublicRoomsJob::Private
BaseJob::Query queryToQueryPublicRooms(const QString& server)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "server", server);
+ addParam<IfNotEmpty>(_q, QStringLiteral("server"), server);
return _q;
}
+static const auto QueryPublicRoomsJobName = QStringLiteral("QueryPublicRoomsJob");
+
QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable<int> limit, const QString& since, const Omittable<Filter>& filter)
- : BaseJob(HttpVerb::Post, "QueryPublicRoomsJob",
+ : BaseJob(HttpVerb::Post, QueryPublicRoomsJobName,
basePath % "/publicRooms",
queryToQueryPublicRooms(server))
, d(new Private)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "limit", limit);
- addParam<IfNotEmpty>(_data, "since", since);
- addParam<IfNotEmpty>(_data, "filter", filter);
+ addParam<IfNotEmpty>(_data, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_data, QStringLiteral("since"), since);
+ addParam<IfNotEmpty>(_data, QStringLiteral("filter"), filter);
setRequestData(_data);
}
@@ -252,13 +260,13 @@ Omittable<qint64> 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<QVector<PublicRoomsChunk>>(json.value("chunk"));
- d->nextBatch = fromJson<QString>(json.value("next_batch"));
- d->prevBatch = fromJson<QString>(json.value("prev_batch"));
- d->totalRoomCountEstimate = fromJson<qint64>(json.value("total_room_count_estimate"));
+ d->chunk = fromJson<QVector<PublicRoomsChunk>>(json.value("chunk"_ls));
+ d->nextBatch = fromJson<QString>(json.value("next_batch"_ls));
+ d->prevBatch = fromJson<QString>(json.value("prev_batch"_ls));
+ d->totalRoomCountEstimate = fromJson<qint64>(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<IfNotEmpty>(_data, "user", user);
- addParam<IfNotEmpty>(_data, "medium", medium);
- addParam<IfNotEmpty>(_data, "address", address);
- addParam<IfNotEmpty>(_data, "password", password);
- addParam<IfNotEmpty>(_data, "token", token);
- addParam<IfNotEmpty>(_data, "device_id", deviceId);
- addParam<IfNotEmpty>(_data, "initial_device_display_name", initialDeviceDisplayName);
+ addParam<>(_data, QStringLiteral("type"), type);
+ addParam<IfNotEmpty>(_data, QStringLiteral("user"), user);
+ addParam<IfNotEmpty>(_data, QStringLiteral("medium"), medium);
+ addParam<IfNotEmpty>(_data, QStringLiteral("address"), address);
+ addParam<IfNotEmpty>(_data, QStringLiteral("password"), password);
+ addParam<IfNotEmpty>(_data, QStringLiteral("token"), token);
+ addParam<IfNotEmpty>(_data, QStringLiteral("device_id"), deviceId);
+ addParam<IfNotEmpty>(_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<QString>(json.value("user_id"));
- d->accessToken = fromJson<QString>(json.value("access_token"));
- d->homeServer = fromJson<QString>(json.value("home_server"));
- d->deviceId = fromJson<QString>(json.value("device_id"));
+ d->userId = fromJson<QString>(json.value("user_id"_ls));
+ d->accessToken = fromJson<QString>(json.value("access_token"_ls));
+ d->homeServer = fromJson<QString>(json.value("home_server"_ls));
+ d->deviceId = fromJson<QString>(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<int> limit, const QString& filter)
{
BaseJob::Query _q;
- addParam<>(_q, "from", from);
- addParam<IfNotEmpty>(_q, "to", to);
- addParam<>(_q, "dir", dir);
- addParam<IfNotEmpty>(_q, "limit", limit);
- addParam<IfNotEmpty>(_q, "filter", filter);
+ addParam<>(_q, QStringLiteral("from"), from);
+ addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
+ addParam<>(_q, QStringLiteral("dir"), dir);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_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<int> 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<QString>(json.value("start"));
- d->end = fromJson<QString>(json.value("end"));
- d->chunk = fromJson<RoomEvents>(json.value("chunk"));
+ d->begin = fromJson<QString>(json.value("start"_ls));
+ d->end = fromJson<QString>(json.value("end"_ls));
+ d->chunk = fromJson<RoomEvents>(json.value("chunk"_ls));
return Success;
}
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.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<QVector<QVariant>>(_json.value("actions"));
+ fromJson<QVector<QVariant>>(_json.value("actions"_ls));
result.event =
- fromJson<EventPtr>(_json.value("event"));
+ fromJson<EventPtr>(_json.value("event"_ls));
result.profileTag =
- fromJson<QString>(_json.value("profile_tag"));
+ fromJson<QString>(_json.value("profile_tag"_ls));
result.read =
- fromJson<bool>(_json.value("read"));
+ fromJson<bool>(_json.value("read"_ls));
result.roomId =
- fromJson<QString>(_json.value("room_id"));
+ fromJson<QString>(_json.value("room_id"_ls));
result.ts =
- fromJson<qint64>(_json.value("ts"));
+ fromJson<qint64>(_json.value("ts"_ls));
return result;
}
@@ -50,9 +50,9 @@ class GetNotificationsJob::Private
BaseJob::Query queryToGetNotifications(const QString& from, Omittable<int> limit, const QString& only)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "from", from);
- addParam<IfNotEmpty>(_q, "limit", limit);
- addParam<IfNotEmpty>(_q, "only", only);
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_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<int> 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::Notification>&& GetNotificationsJob::notificati
BaseJob::Status GetNotificationsJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->nextToken = fromJson<QString>(json.value("next_token"));
- if (!json.contains("notifications"))
+ d->nextToken = fromJson<QString>(json.value("next_token"_ls));
+ if (!json.contains("notifications"_ls))
return { JsonParseError,
"The key 'notifications' not found in the response" };
- d->notifications = fromJson<std::vector<Notification>>(json.value("notifications"));
+ d->notifications = fromJson<std::vector<Notification>>(json.value("notifications"_ls));
return Success;
}
diff --git a/lib/csapi/notifications.h b/lib/csapi/notifications.h
index 094fa3af..3698431d 100644
--- a/lib/csapi/notifications.h
+++ b/lib/csapi/notifications.h
@@ -6,7 +6,7 @@
#include "jobs/basejob.h"
-#include "events/event.h"
+#include "events/eventloader.h"
#include "converters.h"
#include <QtCore/QVector>
#include <QtCore/QVariant>
diff --git a/lib/csapi/peeking_events.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<int> timeout, const QString& roomId)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "from", from);
- addParam<IfNotEmpty>(_q, "timeout", timeout);
- addParam<IfNotEmpty>(_q, "room_id", roomId);
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ addParam<IfNotEmpty>(_q, QStringLiteral("timeout"), timeout);
+ addParam<IfNotEmpty>(_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<int> 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<QString>(json.value("start"));
- d->end = fromJson<QString>(json.value("end"));
- d->chunk = fromJson<RoomEvents>(json.value("chunk"));
+ d->begin = fromJson<QString>(json.value("start"_ls));
+ d->end = fromJson<QString>(json.value("end"_ls));
+ d->chunk = fromJson<RoomEvents>(json.value("chunk"_ls));
return Success;
}
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.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<IfNotEmpty>(_data, "status_msg", statusMsg);
+ addParam<>(_data, QStringLiteral("presence"), presence);
+ addParam<IfNotEmpty>(_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<QString>(json.value("presence"));
- d->lastActiveAgo = fromJson<int>(json.value("last_active_ago"));
- d->statusMsg = fromJson<QString>(json.value("status_msg"));
- d->currentlyActive = fromJson<bool>(json.value("currently_active"));
+ d->presence = fromJson<QString>(json.value("presence"_ls));
+ d->lastActiveAgo = fromJson<int>(json.value("last_active_ago"_ls));
+ d->statusMsg = fromJson<QString>(json.value("status_msg"_ls));
+ d->currentlyActive = fromJson<bool>(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<IfNotEmpty>(_data, "invite", invite);
- addParam<IfNotEmpty>(_data, "drop", drop);
+ addParam<IfNotEmpty>(_data, QStringLiteral("invite"), invite);
+ addParam<IfNotEmpty>(_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<Events>(json.value("data"));
+ d->data = fromJson<Events>(json.value("data"_ls));
return Success;
}
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/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<IfNotEmpty>(_data, "displayname", displayname);
+ addParam<IfNotEmpty>(_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<QString>(json.value("displayname"));
+ d->displayname = fromJson<QString>(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<IfNotEmpty>(_data, "avatar_url", avatarUrl);
+ addParam<IfNotEmpty>(_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<QString>(json.value("avatar_url"));
+ d->avatarUrl = fromJson<QString>(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<QString>(json.value("avatar_url"));
- d->displayname = fromJson<QString>(json.value("displayname"));
+ d->avatarUrl = fromJson<QString>(json.value("avatar_url"_ls));
+ d->displayname = fromJson<QString>(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<QString>(_json.value("url"));
+ fromJson<QString>(_json.value("url"_ls));
return result;
}
@@ -36,21 +36,21 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
GetPushersJob::Pusher result;
result.pushkey =
- fromJson<QString>(_json.value("pushkey"));
+ fromJson<QString>(_json.value("pushkey"_ls));
result.kind =
- fromJson<QString>(_json.value("kind"));
+ fromJson<QString>(_json.value("kind"_ls));
result.appId =
- fromJson<QString>(_json.value("app_id"));
+ fromJson<QString>(_json.value("app_id"_ls));
result.appDisplayName =
- fromJson<QString>(_json.value("app_display_name"));
+ fromJson<QString>(_json.value("app_display_name"_ls));
result.deviceDisplayName =
- fromJson<QString>(_json.value("device_display_name"));
+ fromJson<QString>(_json.value("device_display_name"_ls));
result.profileTag =
- fromJson<QString>(_json.value("profile_tag"));
+ fromJson<QString>(_json.value("profile_tag"_ls));
result.lang =
- fromJson<QString>(_json.value("lang"));
+ fromJson<QString>(_json.value("lang"_ls));
result.data =
- fromJson<GetPushersJob::PusherData>(_json.value("data"));
+ fromJson<GetPushersJob::PusherData>(_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::Pusher>& GetPushersJob::pushers() const
BaseJob::Status GetPushersJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->pushers = fromJson<QVector<Pusher>>(json.value("pushers"));
+ d->pushers = fromJson<QVector<Pusher>>(json.value("pushers"_ls));
return Success;
}
@@ -97,25 +99,27 @@ namespace QMatrixClient
QJsonObject toJson(const PostPusherJob::PusherData& pod)
{
QJsonObject _json;
- addParam<IfNotEmpty>(_json, "url", pod.url);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "profile_tag", profileTag);
- addParam<>(_data, "lang", lang);
- addParam<>(_data, "data", data);
- addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, QStringLiteral("profile_tag"), profileTag);
+ addParam<>(_data, QStringLiteral("lang"), lang);
+ addParam<>(_data, QStringLiteral("data"), data);
+ addParam<IfNotEmpty>(_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<PushRuleset>(json.value("global"));
+ d->global = fromJson<PushRuleset>(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<PushRule>(json.value("data"));
+ d->data = fromJson<PushRule>(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<IfNotEmpty>(_q, "before", before);
- addParam<IfNotEmpty>(_q, "after", after);
+ addParam<IfNotEmpty>(_q, QStringLiteral("before"), before);
+ addParam<IfNotEmpty>(_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<PushCondition>& 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<IfNotEmpty>(_data, "conditions", conditions);
- addParam<IfNotEmpty>(_data, "pattern", pattern);
+ addParam<>(_data, QStringLiteral("actions"), actions);
+ addParam<IfNotEmpty>(_data, QStringLiteral("conditions"), conditions);
+ addParam<IfNotEmpty>(_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<bool>(json.value("enabled"));
+ d->enabled = fromJson<bool>(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<QStringList>(json.value("actions"));
+ d->actions = fromJson<QStringList>(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<IfNotEmpty>(_data, "reason", reason);
+ addParam<IfNotEmpty>(_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<QString>(json.value("event_id"));
+ d->eventId = fromJson<QString>(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<IfNotEmpty>(_q, "kind", kind);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "auth", auth);
- addParam<IfNotEmpty>(_data, "bind_email", bindEmail);
- addParam<IfNotEmpty>(_data, "username", username);
- addParam<IfNotEmpty>(_data, "password", password);
- addParam<IfNotEmpty>(_data, "device_id", deviceId);
- addParam<IfNotEmpty>(_data, "initial_device_display_name", initialDeviceDisplayName);
+ addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
+ addParam<IfNotEmpty>(_data, QStringLiteral("bind_email"), bindEmail);
+ addParam<IfNotEmpty>(_data, QStringLiteral("username"), username);
+ addParam<IfNotEmpty>(_data, QStringLiteral("password"), password);
+ addParam<IfNotEmpty>(_data, QStringLiteral("device_id"), deviceId);
+ addParam<IfNotEmpty>(_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<QString>(json.value("user_id"));
- d->accessToken = fromJson<QString>(json.value("access_token"));
- d->homeServer = fromJson<QString>(json.value("home_server"));
- d->deviceId = fromJson<QString>(json.value("device_id"));
+ d->userId = fromJson<QString>(json.value("user_id"_ls));
+ d->accessToken = fromJson<QString>(json.value("access_token"_ls));
+ d->homeServer = fromJson<QString>(json.value("home_server"_ls));
+ d->deviceId = fromJson<QString>(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<IfNotEmpty>(_data, "id_server", idServer);
- addParam<>(_data, "client_secret", clientSecret);
- addParam<>(_data, "email", email);
- addParam<>(_data, "send_attempt", sendAttempt);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "auth", auth);
+ addParam<>(_data, QStringLiteral("new_password"), newPassword);
+ addParam<IfNotEmpty>(_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<IfNotEmpty>(_data, "auth", auth);
+ addParam<IfNotEmpty>(_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<bool>(json.value("available"));
+ d->available = fromJson<bool>(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<QString>(json.value("event_id"));
+ d->eventId = fromJson<QString>(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<QString>(json.value("event_id"));
+ d->eventId = fromJson<QString>(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<QString>(json.value("event_id"));
+ d->eventId = fromJson<QString>(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<EventPtr>(json.value("data"));
+ d->data = fromJson<EventPtr>(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<StateEventPtr>(json.value("data"));
+ d->data = fromJson<StateEventPtr>(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<StateEventPtr>(json.value("data"));
+ d->data = fromJson<StateEventPtr>(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<StateEvents>(json.value("data"));
+ d->data = fromJson<StateEvents>(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<RoomMemberEvent>&& GetMembersByRoomJob::chunk()
BaseJob::Status GetMembersByRoomJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->chunk = fromJson<EventsArray<RoomMemberEvent>>(json.value("chunk"));
+ d->chunk = fromJson<EventsArray<RoomMemberEvent>>(json.value("chunk"_ls));
return Success;
}
@@ -200,9 +210,9 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
GetJoinedMembersByRoomJob::RoomMember result;
result.displayName =
- fromJson<QString>(_json.value("display_name"));
+ fromJson<QString>(_json.value("display_name"_ls));
result.avatarUrl =
- fromJson<QString>(_json.value("avatar_url"));
+ fromJson<QString>(_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<QString, GetJoinedMembersByRoomJob::RoomMember>& GetJoinedMembersByR
BaseJob::Status GetJoinedMembersByRoomJob::parseJson(const QJsonDocument& data)
{
auto json = data.object();
- d->joined = fromJson<QHash<QString, RoomMember>>(json.value("joined"));
+ d->joined = fromJson<QHash<QString, RoomMember>>(json.value("joined"_ls));
return Success;
}
diff --git a/lib/csapi/rooms.h b/lib/csapi/rooms.h
index 459c6ad5..7d690ec8 100644
--- a/lib/csapi/rooms.h
+++ b/lib/csapi/rooms.h
@@ -6,8 +6,8 @@
#include "jobs/basejob.h"
-#include "events/event.h"
#include "events/roommemberevent.h"
+#include "events/eventloader.h"
#include <QtCore/QHash>
#include "converters.h"
diff --git a/lib/csapi/search.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<IfNotEmpty>(_json, "before_limit", pod.beforeLimit);
- addParam<IfNotEmpty>(_json, "after_limit", pod.afterLimit);
- addParam<IfNotEmpty>(_json, "include_profile", pod.includeProfile);
+ addParam<IfNotEmpty>(_json, QStringLiteral("before_limit"), pod.beforeLimit);
+ addParam<IfNotEmpty>(_json, QStringLiteral("after_limit"), pod.afterLimit);
+ addParam<IfNotEmpty>(_json, QStringLiteral("include_profile"), pod.includeProfile);
return _json;
}
QJsonObject toJson(const SearchJob::Group& pod)
{
QJsonObject _json;
- addParam<IfNotEmpty>(_json, "key", pod.key);
+ addParam<IfNotEmpty>(_json, QStringLiteral("key"), pod.key);
return _json;
}
QJsonObject toJson(const SearchJob::Groupings& pod)
{
QJsonObject _json;
- addParam<IfNotEmpty>(_json, "group_by", pod.groupBy);
+ addParam<IfNotEmpty>(_json, QStringLiteral("group_by"), pod.groupBy);
return _json;
}
QJsonObject toJson(const SearchJob::RoomEventsCriteria& pod)
{
QJsonObject _json;
- addParam<>(_json, "search_term", pod.searchTerm);
- addParam<IfNotEmpty>(_json, "keys", pod.keys);
- addParam<IfNotEmpty>(_json, "filter", pod.filter);
- addParam<IfNotEmpty>(_json, "order_by", pod.orderBy);
- addParam<IfNotEmpty>(_json, "event_context", pod.eventContext);
- addParam<IfNotEmpty>(_json, "include_state", pod.includeState);
- addParam<IfNotEmpty>(_json, "groupings", pod.groupings);
+ addParam<>(_json, QStringLiteral("search_term"), pod.searchTerm);
+ addParam<IfNotEmpty>(_json, QStringLiteral("keys"), pod.keys);
+ addParam<IfNotEmpty>(_json, QStringLiteral("filter"), pod.filter);
+ addParam<IfNotEmpty>(_json, QStringLiteral("order_by"), pod.orderBy);
+ addParam<IfNotEmpty>(_json, QStringLiteral("event_context"), pod.eventContext);
+ addParam<IfNotEmpty>(_json, QStringLiteral("include_state"), pod.includeState);
+ addParam<IfNotEmpty>(_json, QStringLiteral("groupings"), pod.groupings);
return _json;
}
QJsonObject toJson(const SearchJob::Categories& pod)
{
QJsonObject _json;
- addParam<IfNotEmpty>(_json, "room_events", pod.roomEvents);
+ addParam<IfNotEmpty>(_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<QString>(_json.value("displayname"));
+ fromJson<QString>(_json.value("displayname"_ls));
result.avatarUrl =
- fromJson<QString>(_json.value("avatar_url"));
+ fromJson<QString>(_json.value("avatar_url"_ls));
return result;
}
@@ -81,15 +81,15 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
SearchJob::EventContext result;
result.begin =
- fromJson<QString>(_json.value("start"));
+ fromJson<QString>(_json.value("start"_ls));
result.end =
- fromJson<QString>(_json.value("end"));
+ fromJson<QString>(_json.value("end"_ls));
result.profileInfo =
- fromJson<QHash<QString, SearchJob::UserProfile>>(_json.value("profile_info"));
+ fromJson<QHash<QString, SearchJob::UserProfile>>(_json.value("profile_info"_ls));
result.eventsBefore =
- fromJson<RoomEvents>(_json.value("events_before"));
+ fromJson<RoomEvents>(_json.value("events_before"_ls));
result.eventsAfter =
- fromJson<RoomEvents>(_json.value("events_after"));
+ fromJson<RoomEvents>(_json.value("events_after"_ls));
return result;
}
@@ -102,11 +102,11 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
SearchJob::Result result;
result.rank =
- fromJson<double>(_json.value("rank"));
+ fromJson<double>(_json.value("rank"_ls));
result.result =
- fromJson<RoomEventPtr>(_json.value("result"));
+ fromJson<RoomEventPtr>(_json.value("result"_ls));
result.context =
- fromJson<SearchJob::EventContext>(_json.value("context"));
+ fromJson<SearchJob::EventContext>(_json.value("context"_ls));
return result;
}
@@ -119,11 +119,11 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
SearchJob::GroupValue result;
result.nextBatch =
- fromJson<QString>(_json.value("next_batch"));
+ fromJson<QString>(_json.value("next_batch"_ls));
result.order =
- fromJson<int>(_json.value("order"));
+ fromJson<int>(_json.value("order"_ls));
result.results =
- fromJson<QStringList>(_json.value("results"));
+ fromJson<QStringList>(_json.value("results"_ls));
return result;
}
@@ -136,15 +136,15 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
SearchJob::ResultRoomEvents result;
result.count =
- fromJson<qint64>(_json.value("count"));
+ fromJson<qint64>(_json.value("count"_ls));
result.results =
- fromJson<std::vector<SearchJob::Result>>(_json.value("results"));
+ fromJson<std::vector<SearchJob::Result>>(_json.value("results"_ls));
result.state =
- fromJson<std::unordered_map<QString, StateEvents>>(_json.value("state"));
+ fromJson<std::unordered_map<QString, StateEvents>>(_json.value("state"_ls));
result.groups =
- fromJson<QHash<QString, QHash<QString, SearchJob::GroupValue>>>(_json.value("groups"));
+ fromJson<QHash<QString, QHash<QString, SearchJob::GroupValue>>>(_json.value("groups"_ls));
result.nextBatch =
- fromJson<QString>(_json.value("next_batch"));
+ fromJson<QString>(_json.value("next_batch"_ls));
return result;
}
@@ -157,7 +157,7 @@ namespace QMatrixClient
const auto& _json = jv.toObject();
SearchJob::ResultCategories result;
result.roomEvents =
- fromJson<SearchJob::ResultRoomEvents>(_json.value("room_events"));
+ fromJson<SearchJob::ResultRoomEvents>(_json.value("room_events"_ls));
return result;
}
@@ -173,18 +173,20 @@ class SearchJob::Private
BaseJob::Query queryToSearch(const QString& nextBatch)
{
BaseJob::Query _q;
- addParam<IfNotEmpty>(_q, "next_batch", nextBatch);
+ addParam<IfNotEmpty>(_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<ResultCategories>(json.value("search_categories"));
+ d->searchCategories = fromJson<ResultCategories>(json.value("search_categories"_ls));
return Success;
}
diff --git a/lib/csapi/search.h b/lib/csapi/search.h
index 206bacca..572ea6af 100644
--- a/lib/csapi/search.h
+++ b/lib/csapi/search.h
@@ -6,12 +6,12 @@
#include "jobs/basejob.h"
-#include <unordered_map>
-#include <QtCore/QHash>
#include <QtCore/QJsonObject>
-#include "events/event.h"
#include "converters.h"
#include <QtCore/QVector>
+#include <unordered_map>
+#include <QtCore/QHash>
+#include "events/eventloader.h"
namespace QMatrixClient
{
diff --git a/lib/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<QJsonObject>(json.value("tags"));
+ d->tags = fromJson<QJsonObject>(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<QString, QHash<QString, QJsonObject>>& messages)
- : BaseJob(HttpVerb::Put, "SendToDeviceJob",
+ : BaseJob(HttpVerb::Put, SendToDeviceJobName,
basePath % "/sendToDevice/" % eventType % "/" % txnId)
{
QJsonObject _data;
- addParam<IfNotEmpty>(_data, "messages", messages);
+ addParam<IfNotEmpty>(_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<int> timeout)
- : BaseJob(HttpVerb::Put, "SetTypingJob",
+ : BaseJob(HttpVerb::Put, SetTypingJobName,
basePath % "/rooms/" % roomId % "/typing/" % userId)
{
QJsonObject _data;
- addParam<>(_data, "typing", typing);
- addParam<IfNotEmpty>(_data, "timeout", timeout);
+ addParam<>(_data, QStringLiteral("typing"), typing);
+ addParam<IfNotEmpty>(_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<QString>(_json.value("user_id"));
+ fromJson<QString>(_json.value("user_id"_ls));
result.displayName =
- fromJson<QString>(_json.value("display_name"));
+ fromJson<QString>(_json.value("display_name"_ls));
result.avatarUrl =
- fromJson<QString>(_json.value("avatar_url"));
+ fromJson<QString>(_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<int> limit)
- : BaseJob(HttpVerb::Post, "SearchUserDirectoryJob",
+ : BaseJob(HttpVerb::Post, SearchUserDirectoryJobName,
basePath % "/user_directory/search")
, d(new Private)
{
QJsonObject _data;
- addParam<>(_data, "search_term", searchTerm);
- addParam<IfNotEmpty>(_data, "limit", limit);
+ addParam<>(_data, QStringLiteral("search_term"), searchTerm);
+ addParam<IfNotEmpty>(_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<QVector<User>>(json.value("results"));
- if (!json.contains("limited"))
+ d->results = fromJson<QVector<User>>(json.value("results"_ls));
+ if (!json.contains("limited"_ls))
return { JsonParseError,
"The key 'limited' not found in the response" };
- d->limited = fromJson<bool>(json.value("limited"));
+ d->limited = fromJson<bool>(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<QStringList>(json.value("versions"));
+ d->versions = fromJson<QStringList>(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<QJsonObject>(json.value("data"));
+ d->data = fromJson<QJsonObject>(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<QString>(json.value("user_id"));
+ d->userId = fromJson<QString>(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/events/accountdataevents.h b/lib/events/accountdataevents.h
index 11667172..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
{
@@ -32,7 +33,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 +51,31 @@ namespace QMatrixClient
using TagsMap = QHash<QString, TagRecord>;
-#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 <typename... Ts> \
- explicit _Name(Ts&&... contentArgs) \
- : Event(_EnumType) \
- , _content(QStringLiteral(#_ContentKey), \
- std::forward<Ts>(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<content_type>(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)
+ DEFINE_SIMPLE_EVENT(IgnoredUsersEvent, "m.ignored_user_list",
+ QSet<QString>, 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..266d60d8 100644
--- a/lib/events/directchatevent.cpp
+++ b/lib/events/directchatevent.cpp
@@ -18,18 +18,14 @@
#include "directchatevent.h"
-#include "converters.h"
+#include <QtCore/QJsonArray>
using namespace QMatrixClient;
-DirectChatEvent::DirectChatEvent(const QJsonObject& obj)
- : Event(Type::DirectChat, obj)
-{ }
-
QMultiHash<QString, QString> DirectChatEvent::usersToDirectChats() const
{
QMultiHash<QString, QString> 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..7559796b 100644
--- a/lib/events/directchatevent.h
+++ b/lib/events/directchatevent.h
@@ -25,10 +25,14 @@ namespace QMatrixClient
class DirectChatEvent : public Event
{
public:
- explicit DirectChatEvent(const QJsonObject& obj);
+ DEFINE_EVENT_TYPEID("m.direct", DirectChatEvent)
- QMultiHash<QString, QString> usersToDirectChats() const;
+ explicit DirectChatEvent(const QJsonObject& obj)
+ : Event(typeId(), obj)
+ { }
- static constexpr const char* typeId() { return "m.direct"; }
+ QMultiHash<QString, QString> usersToDirectChats() const;
};
+ REGISTER_EVENT_TYPE(DirectChatEvent)
+ DEFINE_EVENTTYPE_ALIAS(DirectChat, DirectChatEvent)
}
diff --git a/lib/events/event.cpp b/lib/events/event.cpp
index 576e9426..44bf79a1 100644
--- a/lib/events/event.cpp
+++ b/lib/events/event.cpp
@@ -18,170 +18,51 @@
#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"
#include <QtCore/QJsonDocument>
using namespace QMatrixClient;
-Event::Event(Type type, const QJsonObject& rep)
- : _type(type), _originalJson(rep)
+event_type_t QMatrixClient::nextTypeId()
{
- if (!rep.contains("content") &&
- !rep.value("unsigned").toObject().contains("redacted_because"))
- {
- qCWarning(EVENTS) << "Event without 'content' node";
- qCWarning(EVENTS) << formatJson << rep;
- }
+ static event_type_t _id = EventTypeTraits<void>::id;
+ return ++_id;
}
-Event::~Event() = default;
-
-QString Event::jsonType() const
+Event::Event(Type type, const QJsonObject& json)
+ : _type(type), _json(json)
{
- return originalJsonObject().value("type").toString();
-}
-
-QByteArray Event::originalJson() const
-{
- return QJsonDocument(_originalJson).toJson();
-}
-
-QJsonObject Event::originalJsonObject() const
-{
- return _originalJson;
-}
-
-const QJsonObject Event::contentJson() const
-{
- return _originalJson["content"].toObject();
-}
-
-template <typename BaseEventT>
-inline event_ptr_tt<BaseEventT> makeIfMatches(const QJsonObject&, const QString&)
-{
- return nullptr;
-}
-
-template <typename BaseEventT, typename EventT, typename... EventTs>
-inline event_ptr_tt<BaseEventT> makeIfMatches(const QJsonObject& o,
- const QString& selector)
-{
- if (selector == EventT::typeId())
- return _impl::create<EventT>(o);
-
- return makeIfMatches<BaseEventT, EventTs...>(o, selector);
-}
-
-template <>
-EventPtr _impl::doMakeEvent<Event>(const QJsonObject& obj)
-{
- // Check more specific event types first
- if (auto e = doMakeEvent<RoomEvent>(obj))
- return ptrCast<Event>(move(e));
-
- return makeIfMatches<Event,
- TypingEvent, ReceiptEvent, TagEvent, ReadMarkerEvent, DirectChatEvent>(
- obj, obj["type"].toString());
-}
-
-RoomEvent::RoomEvent(Event::Type type) : Event(type) { }
-
-RoomEvent::RoomEvent(Type type, const QJsonObject& rep)
- : Event(type, rep)
- , _id(rep["event_id"].toString())
-{
-// 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");
- if (redaction.isObject())
+ if (!json.contains(ContentKeyL) &&
+ !json.value(UnsignedKeyL).toObject().contains(RedactedCauseKeyL))
{
- _redactedBecause = _impl::create<RedactionEvent>(redaction.toObject());
- return;
+ qCWarning(EVENTS) << "Event without 'content' node";
+ qCWarning(EVENTS) << formatJson << json;
}
-
- _txnId = unsignedData.value("transactionId").toString();
- if (!_txnId.isEmpty())
- qCDebug(EVENTS) << "Event transactionId:" << _txnId;
-}
-
-RoomEvent::~RoomEvent() = default; // Let the smart pointer do its job
-
-QDateTime RoomEvent::timestamp() const
-{
- return QMatrixClient::fromJson<QDateTime>(
- originalJsonObject().value("origin_server_ts"));
}
-QString RoomEvent::roomId() const
-{
- return originalJsonObject().value("room_id").toString();
-}
-
-QString RoomEvent::senderId() const
-{
- return originalJsonObject().value("sender").toString();
-}
+Event::Event(Type type, event_mtype_t matrixType, const QJsonObject& contentJson)
+ : Event(type, basicEventJson(matrixType, contentJson))
+{ }
-QString RoomEvent::redactionReason() const
-{
- return isRedacted() ? _redactedBecause->reason() : QString{};
-}
+Event::~Event() = default;
-void RoomEvent::addId(const QString& id)
+QString Event::matrixType() const
{
- Q_ASSERT(_id.isEmpty()); Q_ASSERT(!id.isEmpty());
- _id = id;
+ return fullJson()[TypeKeyL].toString();
}
-template <>
-RoomEventPtr _impl::doMakeEvent(const QJsonObject& obj)
+QByteArray Event::originalJson() const
{
- // Check more specific event types first
- if (auto e = doMakeEvent<StateEventBase>(obj))
- return ptrCast<RoomEvent>(move(e));
-
- return makeIfMatches<RoomEvent,
- RoomMessageEvent, RedactionEvent>(obj, obj["type"].toString());
+ return QJsonDocument(_json).toJson();
}
-bool StateEventBase::repeatsState() const
+const QJsonObject Event::contentJson() const
{
- auto contentJson = originalJsonObject().value("content");
- auto prevContentJson = originalJsonObject().value("unsigned")
- .toObject().value("prev_content");
- return contentJson == prevContentJson;
+ return fullJson()[ContentKeyL].toObject();
}
-template<>
-StateEventPtr _impl::doMakeEvent<StateEventBase>(const QJsonObject& obj)
+const QJsonObject Event::unsignedJson() const
{
- return makeIfMatches<StateEventBase,
- RoomNameEvent, RoomAliasesEvent,
- RoomCanonicalAliasEvent, RoomMemberEvent, RoomTopicEvent,
- RoomAvatarEvent, EncryptionEvent>(obj, obj["type"].toString());
-
+ return fullJson()[UnsignedKeyL].toObject();
}
diff --git a/lib/events/event.h b/lib/events/event.h
index cbfa06ac..04384aa7 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -18,11 +18,14 @@
#pragma once
-#include "converters.h"
#include "util.h"
+#include <QtCore/QJsonObject>
+
namespace QMatrixClient
{
+ // === event_ptr_tt<> and type casting facilities ===
+
template <typename EventT>
using event_ptr_tt = std::unique_ptr<EventT>;
@@ -44,252 +47,238 @@ namespace QMatrixClient
return unique_ptr_cast<TargetT>(ptr);
}
- namespace _impl
+ // === Standard Matrix key names and basicEventJson() ===
+
+ 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;
+
+ // Minimal correct Matrix event JSON
+ template <typename StrT>
+ inline QJsonObject basicEventJson(StrT matrixType,
+ const QJsonObject& content)
+ {
+ return { { TypeKey, std::forward<StrT>(matrixType) },
+ { ContentKey, content } };
+ }
+
+ // === Event factory ===
+
+ using event_type_t = size_t;
+ using event_mtype_t = const char*;
+
+ template <typename EventT>
+ struct EventTypeTraits
+ {
+ static const event_type_t id;
+ };
+
+ template <>
+ struct EventTypeTraits<void>
+ {
+ static constexpr event_type_t id = 0;
+ };
+
+ event_type_t nextTypeId();
+
+ template <typename EventT>
+ const event_type_t EventTypeTraits<EventT>::id = nextTypeId();
+
+ template <typename EventT>
+ inline event_type_t typeId() { return EventTypeTraits<std::decay_t<EventT>>::id; }
+
+ inline event_type_t unknownEventTypeId() { return typeId<void>(); }
+
+ template <typename EventT, typename... ArgTs>
+ inline event_ptr_tt<EventT> makeEvent(ArgTs&&... args)
+ {
+ return std::make_unique<EventT>(std::forward<ArgTs>(args)...);
+ }
+
+ template <typename BaseEventT>
+ class EventFactory
{
- template <typename EventT, typename... ArgTs>
- inline event_ptr_tt<EventT> create(ArgTs&&... args)
- {
- return std::make_unique<EventT>(std::forward<ArgTs>(args)...);
- }
-
- template <typename EventT>
- inline event_ptr_tt<EventT> doMakeEvent(const QJsonObject& obj)
- {
- return create<EventT>(obj);
- }
+ public:
+ template <typename FnT>
+ static void addMethod(FnT&& method)
+ {
+ factories().emplace_back(std::forward<FnT>(method));
+ }
+
+ /** 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 <typename EventT>
+ static auto chainFactory()
+ {
+ addMethod(&EventT::factory_t::make);
+ return 0;
+ }
+
+ static event_ptr_tt<BaseEventT> make(const QJsonObject& json,
+ const QString& matrixType)
+ {
+ for (const auto& f: factories())
+ if (auto e = f(json, matrixType))
+ return e;
+ return makeEvent<BaseEventT>(unknownEventTypeId(), json);
+ }
+
+ private:
+ static auto& factories()
+ {
+ using inner_factory_tt =
+ std::function<event_ptr_tt<BaseEventT>(const QJsonObject&,
+ const QString&)>;
+ static std::vector<inner_factory_tt> _factories {};
+ return _factories;
+ }
+ };
+
+ /** 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 <typename EventT>
+ inline void setupFactory()
+ {
+ EventT::factory_t::addMethod(
+ [] (const QJsonObject& json, const QString& jsonMatrixType)
+ {
+ return EventT::matrixTypeId() == jsonMatrixType
+ ? makeEvent<EventT>(json) : nullptr;
+ });
}
+ // === Event ===
+
class Event
{
Q_GADGET
+ Q_PROPERTY(Type type READ type CONSTANT)
+ Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT)
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<Event>;
+
+ 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; }
- virtual QJsonObject toJson() const { Q_ASSERT(false); return {}; }
+ protected:
+ QJsonObject& editJson() { return _json; }
private:
Type _type;
- QJsonObject _originalJson;
-
- REGISTER_ENUM(Type)
- Q_PROPERTY(Type type READ type CONSTANT)
- Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT)
+ QJsonObject _json;
};
- using EventType = Event::Type;
using EventPtr = event_ptr_tt<Event>;
- /** Create an event with proper type from a JSON object
- * Use this factory template to detect the type from the JSON object
- * contents (the detected event type should derive from the template
- * parameter type) and create an event object of that type.
- */
- template <typename EventT>
- inline event_ptr_tt<EventT> makeEvent(const QJsonObject& obj)
- {
- auto e = _impl::doMakeEvent<EventT>(obj);
- if (!e)
- e = _impl::create<EventT>(EventType::Unknown, obj);
- return e;
- }
-
- namespace _impl
- {
- template <>
- EventPtr doMakeEvent<Event>(const QJsonObject& obj);
- }
-
- template <typename EventT> struct FromJson<event_ptr_tt<EventT>>
- {
- auto operator()(const QJsonValue& jv) const
- {
- return makeEvent<EventT>(jv.toObject());
- }
- };
-
template <typename EventT>
using EventsArray = std::vector<event_ptr_tt<EventT>>;
using Events = EventsArray<Event>;
- class RedactionEvent;
+ // === 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 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 typeId<>(), is<>() or visit<>()")]] \
+ static const auto _Id = typeId<_Type>(); \
+ } \
+ // End of macro
+
+ // === is<>() and visit<>() ===
- /** 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:
- // RedactionEvent is an incomplete type here so we cannot inline
- // constructors and destructors
- explicit RoomEvent(Type type);
- RoomEvent(Type type, const QJsonObject& rep);
- ~RoomEvent() override;
-
- QString id() const { return _id; }
- QDateTime timestamp() const;
- QString roomId() const;
- QString senderId() const;
- bool isRedacted() const { return bool(_redactedBecause); }
- const event_ptr_tt<RedactionEvent>& redactedBecause() const
- {
- return _redactedBecause;
- }
- QString redactionReason() const;
- const QString& transactionId() const { return _txnId; }
-
- /**
- * Sets the transaction id for locally created events. This should be
- * done before the event is exposed to any code using the respective
- * Q_PROPERTY.
- *
- * \param txnId - transaction id, normally obtained from
- * Connection::generateTxnId()
- */
- void setTransactionId(const QString& txnId) { _txnId = txnId; }
-
- /**
- * Sets event id for locally created events
- *
- * When a new event is created locally, it has no server id yet.
- * This function allows to add the id once the confirmation from
- * the server is received. There should be no id set previously
- * in the event. It's the responsibility of the code calling addId()
- * to notify clients that use Q_PROPERTY(id) about its change
- */
- void addId(const QString& id);
+ template <typename EventT>
+ inline bool is(const Event& e) { return e.type() == typeId<EventT>(); }
- private:
- QString _id;
- event_ptr_tt<RedactionEvent> _redactedBecause;
- QString _txnId;
- };
- using RoomEventPtr = event_ptr_tt<RoomEvent>;
- using RoomEvents = EventsArray<RoomEvent>;
- using RoomEventsRange = Range<RoomEvents>;
+ inline bool isUnknown(const Event& e) { return e.type() == unknownEventTypeId(); }
- namespace _impl
+ template <typename FnT>
+ inline fn_return_t<FnT> visit(const Event& event, FnT visitor)
{
- template <>
- RoomEventPtr doMakeEvent<RoomEvent>(const QJsonObject& obj);
+ using event_type = fn_arg_t<FnT>;
+ if (is<event_type>(event))
+ return visitor(static_cast<event_type>(event));
+ return fn_return_t<FnT>();
}
- class StateEventBase: public RoomEvent
+ template <typename FnT, typename... FnTs>
+ inline auto visit(const Event& event, FnT visitor1, FnTs&&... visitors)
{
- public:
- explicit StateEventBase(Type type, const QJsonObject& obj)
- : RoomEvent(obj.contains("state_key") ? type : Type::Unknown,
- obj)
- { }
- explicit StateEventBase(Type type)
- : RoomEvent(type)
- { }
- ~StateEventBase() override = default;
-
- virtual bool repeatsState() const;
- };
- using StateEventPtr = event_ptr_tt<StateEventBase>;
- using StateEvents = EventsArray<StateEventBase>;
+ using event_type1 = fn_arg_t<FnT>;
+ if (is<event_type1>(event))
+ return visitor1(static_cast<event_type1&>(event));
- namespace _impl
- {
- template <>
- StateEventPtr doMakeEvent<StateEventBase>(const QJsonObject& obj);
+ return visit(event, std::forward<FnTs>(visitors)...);
}
- template <typename ContentT>
- struct Prev
+ template <typename BaseEventT, typename... FnTs>
+ inline auto visit(const event_ptr_tt<BaseEventT>& eptr, FnTs&&... visitors)
{
- template <typename... ContentParamTs>
- explicit Prev(const QJsonObject& unsignedJson,
- ContentParamTs&&... contentParams)
- : senderId(unsignedJson.value("prev_sender").toString())
- , content(unsignedJson.value("prev_content").toObject(),
- std::forward<ContentParamTs>(contentParams)...)
- { }
-
- QString senderId;
- ContentT content;
- };
-
- template <typename ContentT>
- class StateEvent: public StateEventBase
- {
- public:
- using content_type = ContentT;
-
- template <typename... ContentParamTs>
- explicit StateEvent(Type type, const QJsonObject& obj,
- ContentParamTs&&... contentParams)
- : StateEventBase(type, obj)
- , _content(contentJson(),
- std::forward<ContentParamTs>(contentParams)...)
- {
- auto unsignedData = obj.value("unsigned").toObject();
- if (unsignedData.contains("prev_content"))
- _prev = std::make_unique<Prev<ContentT>>(unsignedData,
- std::forward<ContentParamTs>(contentParams)...);
- }
- template <typename... ContentParamTs>
- explicit StateEvent(Type type, ContentParamTs&&... contentParams)
- : StateEventBase(type)
- , _content(std::forward<ContentParamTs>(contentParams)...)
- { }
-
- QJsonObject toJson() const override { return _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 : ""; }
+ using return_type = decltype(visit(*eptr, visitors...));
+ if (eptr)
+ return visit(*eptr, visitors...);
+ return return_type();
+ }
- protected:
- ContentT _content;
- std::unique_ptr<Prev<ContentT>> _prev;
- };
} // namespace QMatrixClient
Q_DECLARE_METATYPE(QMatrixClient::Event*)
-Q_DECLARE_METATYPE(QMatrixClient::RoomEvent*)
Q_DECLARE_METATYPE(const QMatrixClient::Event*)
-Q_DECLARE_METATYPE(const QMatrixClient::RoomEvent*)
diff --git a/lib/events/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 <QtCore/QUrl>
#include <QtCore/QMimeDatabase>
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<ImageInfo>(*this));
+ infoJson->insert(QStringLiteral("thumbnail_url"), url.toString());
+ infoJson->insert(QStringLiteral("thumbnail_info"),
+ toInfoJson<ImageInfo>(*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 <QtCore/QJsonObject>
#include <QtCore/QMimeType>
#include <QtCore/QUrl>
#include <QtCore/QSize>
-#include <functional>
-
namespace QMatrixClient
{
namespace EventContent
@@ -58,37 +55,6 @@ namespace QMatrixClient
virtual void fillJson(QJsonObject* o) const = 0;
};
- template <typename T = QString>
- class SimpleContent: public Base
- {
- public:
- using value_type = T;
-
- // The constructor is templated to enable perfect forwarding
- template <typename TT>
- SimpleContent(QString keyName, TT&& value)
- : value(std::forward<TT>(value)), key(std::move(keyName))
- { }
- SimpleContent(const QJsonObject& json, QString keyName)
- : Base(json)
- , value(QMatrixClient::fromJson<T>(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/eventloader.h b/lib/events/eventloader.h
new file mode 100644
index 00000000..5f1e3b57
--- /dev/null
+++ b/lib/events/eventloader.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "stateevent.h"
+#include "converters.h"
+
+namespace QMatrixClient {
+ /** Create an event with proper type from a JSON object
+ * Use this factory template to detect the type from the JSON object
+ * contents (the detected event type should derive from the template
+ * parameter type) and create an event object of that type.
+ */
+ template <typename BaseEventT>
+ inline event_ptr_tt<BaseEventT> loadEvent(const QJsonObject& fullJson)
+ {
+ return EventFactory<BaseEventT>
+ ::make(fullJson, fullJson[TypeKeyL].toString());
+ }
+
+ /** Create an event from a type string and content JSON
+ * Use this factory template to resolve the C++ type from the Matrix
+ * type string in \p matrixType and create an event of that type that has
+ * its content part set to \p content.
+ */
+ template <typename BaseEventT>
+ inline event_ptr_tt<BaseEventT> loadEvent(const QString& matrixType,
+ const QJsonObject& content)
+ {
+ return EventFactory<BaseEventT>
+ ::make(basicEventJson(matrixType, content), matrixType);
+ }
+
+ template <typename EventT> struct FromJson<event_ptr_tt<EventT>>
+ {
+ auto operator()(const QJsonValue& jv) const
+ {
+ return loadEvent<EventT>(jv.toObject());
+ }
+ };
+} // namespace QMatrixClient
diff --git a/lib/events/receiptevent.cpp b/lib/events/receiptevent.cpp
index a12f4c05..47e1398c 100644
--- a/lib/events/receiptevent.cpp
+++ b/lib/events/receiptevent.cpp
@@ -41,11 +41,9 @@ Example of a Receipt Event:
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 +53,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<Receipt> 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<QDateTime>(user["ts"])});
+ fromJson<QDateTime>(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..c15a01c2 100644
--- a/lib/events/receiptevent.h
+++ b/lib/events/receiptevent.h
@@ -21,6 +21,7 @@
#include "event.h"
#include <QtCore/QVector>
+#include <QtCore/QDateTime>
namespace QMatrixClient
{
@@ -39,14 +40,15 @@ 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;
};
+ REGISTER_EVENT_TYPE(ReceiptEvent)
+ DEFINE_EVENTTYPE_ALIAS(Receipt, ReceiptEvent)
} // namespace QMatrixClient
diff --git a/lib/events/redactionevent.h b/lib/events/redactionevent.h
index dad54788..64504d57 100644
--- a/lib/events/redactionevent.h
+++ b/lib/events/redactionevent.h
@@ -25,19 +25,17 @@ 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(); }
};
+ REGISTER_EVENT_TYPE(RedactionEvent)
+ DEFINE_EVENTTYPE_ALIAS(Redaction, RedactionEvent)
} // namespace QMatrixClient
diff --git a/lib/events/roomavatarevent.h b/lib/events/roomavatarevent.h
index 0e44ad7c..491861b1 100644
--- a/lib/events/roomavatarevent.h
+++ b/lib/events/roomavatarevent.h
@@ -20,8 +20,6 @@
#include "event.h"
-#include <utility>
-
#include "eventcontent.h"
namespace QMatrixClient
@@ -33,11 +31,12 @@ 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; }
};
-
+ REGISTER_EVENT_TYPE(RoomAvatarEvent)
+ DEFINE_EVENTTYPE_ALIAS(RoomAvatar, RoomAvatarEvent)
} // namespace QMatrixClient
diff --git a/lib/events/roomevent.cpp b/lib/events/roomevent.cpp
new file mode 100644
index 00000000..3d09af8a
--- /dev/null
+++ b/lib/events/roomevent.cpp
@@ -0,0 +1,82 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "roomevent.h"
+
+#include "redactionevent.h"
+#include "converters.h"
+#include "logging.h"
+
+using namespace QMatrixClient;
+
+[[gnu::unused]] static auto roomEventTypeInitialised =
+ Event::factory_t::chainFactory<RoomEvent>();
+
+RoomEvent::RoomEvent(Type type, event_mtype_t matrixType,
+ const QJsonObject& contentJson)
+ : Event(type, matrixType, contentJson)
+{ }
+
+RoomEvent::RoomEvent(Type type, const QJsonObject& json)
+ : Event(type, json)
+{
+ const auto unsignedData = json[UnsignedKeyL].toObject();
+ const auto redaction = unsignedData[RedactedCauseKeyL];
+ if (redaction.isObject())
+ {
+ _redactedBecause = makeEvent<RedactionEvent>(redaction.toObject());
+ return;
+ }
+
+ _txnId = unsignedData.value("transactionId"_ls).toString();
+ if (!_txnId.isEmpty())
+ qCDebug(EVENTS) << "Event transactionId:" << _txnId;
+}
+
+RoomEvent::~RoomEvent() = default; // Let the smart pointer do its job
+
+QString RoomEvent::id() const
+{
+ return fullJson()[EventIdKeyL].toString();
+}
+
+QDateTime RoomEvent::timestamp() const
+{
+ return QMatrixClient::fromJson<QDateTime>(fullJson()["origin_server_ts"_ls]);
+}
+
+QString RoomEvent::roomId() const
+{
+ return fullJson()["room_id"_ls].toString();
+}
+
+QString RoomEvent::senderId() const
+{
+ return fullJson()["sender"_ls].toString();
+}
+
+QString RoomEvent::redactionReason() const
+{
+ return isRedacted() ? _redactedBecause->reason() : QString{};
+}
+
+void RoomEvent::addId(const QString& newId)
+{
+ Q_ASSERT(id().isEmpty()); Q_ASSERT(!newId.isEmpty());
+ editJson().insert(EventIdKey, newId);
+}
diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h
new file mode 100644
index 00000000..d2bc6edc
--- /dev/null
+++ b/lib/events/roomevent.h
@@ -0,0 +1,91 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "event.h"
+
+#include <QtCore/QDateTime>
+
+namespace QMatrixClient {
+ class RedactionEvent;
+
+ /** This class corresponds to m.room.* events */
+ class RoomEvent : public Event
+ {
+ Q_GADGET
+ Q_PROPERTY(QString id READ id)
+ Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT)
+ Q_PROPERTY(QString roomId READ roomId CONSTANT)
+ Q_PROPERTY(QString senderId READ senderId CONSTANT)
+ Q_PROPERTY(QString redactionReason READ redactionReason)
+ Q_PROPERTY(bool isRedacted READ isRedacted)
+ Q_PROPERTY(QString transactionId READ transactionId)
+ public:
+ using factory_t = EventFactory<RoomEvent>;
+
+ // RedactionEvent is an incomplete type here so we cannot inline
+ // constructors and destructors and we cannot use 'using'.
+ RoomEvent(Type type, event_mtype_t matrixType,
+ const QJsonObject& contentJson = {});
+ RoomEvent(Type type, const QJsonObject& json);
+ ~RoomEvent() override;
+
+ QString id() const;
+ QDateTime timestamp() const;
+ QString roomId() const;
+ QString senderId() const;
+ bool isRedacted() const { return bool(_redactedBecause); }
+ const event_ptr_tt<RedactionEvent>& redactedBecause() const
+ {
+ return _redactedBecause;
+ }
+ QString redactionReason() const;
+ const QString& transactionId() const { return _txnId; }
+
+ /**
+ * Sets the transaction id for locally created events. This should be
+ * done before the event is exposed to any code using the respective
+ * Q_PROPERTY.
+ *
+ * \param txnId - transaction id, normally obtained from
+ * Connection::generateTxnId()
+ */
+ void setTransactionId(const QString& txnId) { _txnId = txnId; }
+
+ /**
+ * Sets event id for locally created events
+ *
+ * When a new event is created locally, it has no server id yet.
+ * This function allows to add the id once the confirmation from
+ * the server is received. There should be no id set previously
+ * in the event. It's the responsibility of the code calling addId()
+ * to notify clients that use Q_PROPERTY(id) about its change
+ */
+ void addId(const QString& newId);
+
+ private:
+ event_ptr_tt<RedactionEvent> _redactedBecause;
+ QString _txnId;
+ };
+ using RoomEventPtr = event_ptr_tt<RoomEvent>;
+ using RoomEvents = EventsArray<RoomEvent>;
+ using RoomEventsRange = Range<RoomEvents>;
+} // namespace QMatrixClient
+Q_DECLARE_METATYPE(QMatrixClient::RoomEvent*)
+Q_DECLARE_METATYPE(const QMatrixClient::RoomEvent*)
diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp
index 76b003c2..79e4af2d 100644
--- a/lib/events/roommemberevent.cpp
+++ b/lib/events/roommemberevent.cpp
@@ -18,6 +18,7 @@
#include "roommemberevent.h"
+#include "converters.h"
#include "logging.h"
#include <array>
@@ -50,10 +51,10 @@ namespace QMatrixClient
}
MemberEventContent::MemberEventContent(const QJsonObject& json)
- : membership(fromJson<MembershipType>(json["membership"]))
- , isDirect(json["is_direct"].toBool())
- , displayName(json["displayname"].toString())
- , avatarUrl(json["avatar_url"].toString())
+ : membership(fromJson<MembershipType>(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 +63,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..f3e4f53a 100644
--- a/lib/events/roommemberevent.h
+++ b/lib/events/roommemberevent.h
@@ -18,12 +18,9 @@
#pragma once
-#include "event.h"
-
+#include "stateevent.h"
#include "eventcontent.h"
-#include <QtCore/QUrl>
-
namespace QMatrixClient
{
class MemberEventContent: public EventContent::Base
@@ -36,6 +33,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 +52,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 +79,6 @@ namespace QMatrixClient
private:
REGISTER_ENUM(MembershipType)
};
+ REGISTER_EVENT_TYPE(RoomMemberEvent)
+ 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..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
@@ -37,6 +36,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 +45,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 +61,13 @@ 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<EventContent::TypedBase> _content;
REGISTER_ENUM(MsgType)
};
+ REGISTER_EVENT_TYPE(RoomMessageEvent)
+ 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..fa1ca8f4 100644
--- a/lib/events/simplestateevents.h
+++ b/lib/events/simplestateevents.h
@@ -18,36 +18,76 @@
#pragma once
-#include "event.h"
+#include "stateevent.h"
#include "eventcontent.h"
namespace QMatrixClient
{
-#define DEFINE_SIMPLE_STATE_EVENT(_Name, _TypeId, _EnumType, _ContentType, _ContentKey) \
- class _Name \
- : public StateEvent<EventContent::SimpleContent<_ContentType>> \
+ namespace EventContent
+ {
+ template <typename T>
+ class SimpleContent: public Base
+ {
+ public:
+ using value_type = T;
+
+ // The constructor is templated to enable perfect forwarding
+ template <typename TT>
+ SimpleContent(QString keyName, TT&& value)
+ : value(std::forward<TT>(value)), key(std::move(keyName))
+ { }
+ SimpleContent(const QJsonObject& json, QString keyName)
+ : Base(json)
+ , value(QMatrixClient::fromJson<T>(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<EventContent::SimpleContent<_ContentType>> \
{ \
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 <typename T> \
explicit _Name(T&& value) \
- : StateEvent(_EnumType, QStringLiteral(#_ContentKey), \
+ : StateEvent(typeId(), matrixTypeId(), \
+ QStringLiteral(#_ContentKey), \
std::forward<T>(value)) \
{ } \
- const _ContentType& _ContentKey() const { return content().value; } \
- };
+ auto _ContentKey() const { return content().value; } \
+ }; \
+ REGISTER_EVENT_TYPE(_Name) \
+ // 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/stateevent.cpp b/lib/events/stateevent.cpp
new file mode 100644
index 00000000..fd5d2642
--- /dev/null
+++ b/lib/events/stateevent.cpp
@@ -0,0 +1,30 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "stateevent.h"
+
+using namespace QMatrixClient;
+
+[[gnu::unused]] static auto stateEventTypeInitialised =
+ RoomEvent::factory_t::chainFactory<StateEventBase>();
+
+bool StateEventBase::repeatsState() const
+{
+ const auto prevContentJson = unsignedJson().value(PrevContentKeyL);
+ return fullJson().value(ContentKeyL) == prevContentJson;
+}
diff --git a/lib/events/stateevent.h b/lib/events/stateevent.h
new file mode 100644
index 00000000..6032132e
--- /dev/null
+++ b/lib/events/stateevent.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+* Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#pragma once
+
+#include "roomevent.h"
+
+namespace QMatrixClient {
+ class StateEventBase: public RoomEvent
+ {
+ public:
+ using factory_t = EventFactory<StateEventBase>;
+
+ using RoomEvent::RoomEvent;
+ ~StateEventBase() override = default;
+
+ bool isStateEvent() const override { return true; }
+ virtual bool repeatsState() const;
+ };
+ using StateEventPtr = event_ptr_tt<StateEventBase>;
+ using StateEvents = EventsArray<StateEventBase>;
+
+ template <typename ContentT>
+ struct Prev
+ {
+ template <typename... ContentParamTs>
+ explicit Prev(const QJsonObject& unsignedJson,
+ ContentParamTs&&... contentParams)
+ : senderId(unsignedJson.value("prev_sender"_ls).toString())
+ , content(unsignedJson.value(PrevContentKeyL).toObject(),
+ std::forward<ContentParamTs>(contentParams)...)
+ { }
+
+ QString senderId;
+ ContentT content;
+ };
+
+ template <typename ContentT>
+ class StateEvent: public StateEventBase
+ {
+ public:
+ using content_type = ContentT;
+
+ template <typename... ContentParamTs>
+ explicit StateEvent(Type type, const QJsonObject& fullJson,
+ ContentParamTs&&... contentParams)
+ : StateEventBase(type, fullJson)
+ , _content(contentJson(),
+ std::forward<ContentParamTs>(contentParams)...)
+ {
+ const auto& unsignedData = unsignedJson();
+ if (unsignedData.contains(PrevContentKeyL))
+ _prev = std::make_unique<Prev<ContentT>>(unsignedData,
+ std::forward<ContentParamTs>(contentParams)...);
+ }
+ template <typename... ContentParamTs>
+ explicit StateEvent(Type type, event_mtype_t matrixType,
+ ContentParamTs&&... contentParams)
+ : StateEventBase(type, matrixType)
+ , _content(std::forward<ContentParamTs>(contentParams)...)
+ {
+ editJson().insert(ContentKey, _content.toJson());
+ }
+
+ const ContentT& content() const { return _content; }
+ [[deprecated("Use prevContent instead")]]
+ const ContentT* prev_content() const { return prevContent(); }
+ const ContentT* prevContent() const
+ { return _prev ? &_prev->content : nullptr; }
+ QString prevSenderId() const
+ { return _prev ? _prev->senderId : QString(); }
+
+ protected:
+ ContentT _content;
+ std::unique_ptr<Prev<ContentT>> _prev;
+ };
+} // namespace QMatrixClient
diff --git a/lib/events/typingevent.cpp b/lib/events/typingevent.cpp
index a4d3bae4..0d39d1be 100644
--- a/lib/events/typingevent.cpp
+++ b/lib/events/typingevent.cpp
@@ -18,15 +18,15 @@
#include "typingevent.h"
+#include <QtCore/QJsonArray>
+
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..27b668b4 100644
--- a/lib/events/typingevent.h
+++ b/lib/events/typingevent.h
@@ -20,20 +20,20 @@
#include "event.h"
-#include <QtCore/QStringList>
-
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;
};
+ REGISTER_EVENT_TYPE(TypingEvent)
+ DEFINE_EVENTTYPE_ALIAS(Typing, TypingEvent)
} // namespace QMatrixClient
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 <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
@@ -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/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/jobs/syncjob.cpp b/lib/jobs/syncjob.cpp
index cbdc37b4..02690e6d 100644
--- a/lib/jobs/syncjob.cpp
+++ b/lib/jobs/syncjob.cpp
@@ -18,6 +18,8 @@
#include "syncjob.h"
+#include "events/eventloader.h"
+
#include <QtCore/QElapsedTimer>
using namespace QMatrixClient;
@@ -32,13 +34,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<int>::max());
@@ -72,7 +74,7 @@ Events&&SyncData::takeToDeviceEvents()
template <typename EventsArrayT, typename StrT>
inline EventsArrayT load(const QJsonObject& batches, StrT keyName)
{
- return fromJson<EventsArrayT>(batches[keyName].toObject().value("events"));
+ return fromJson<EventsArrayT>(batches[keyName].toObject().value("events"_ls));
}
BaseJob::Status SyncJob::parseJson(const QJsonDocument& data)
@@ -85,12 +87,12 @@ BaseJob::Status SyncData::parseJson(const QJsonDocument &data)
QElapsedTimer et; et.start();
auto json = data.object();
- nextBatch_ = json.value("next_batch").toString();
- presenceData = load<Events>(json, "presence");
- accountData = load<Events>(json, "account_data");
- toDeviceEvents = load<Events>(json, "to_device");
+ nextBatch_ = json.value("next_batch"_ls).toString();
+ presenceData = load<Events>(json, "presence"_ls);
+ accountData = load<Events>(json, "account_data"_ls);
+ toDeviceEvents = load<Events>(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 +125,31 @@ SyncRoomData::SyncRoomData(const QString& roomId_, JoinState joinState_,
: roomId(roomId_)
, joinState(joinState_)
, state(load<StateEvents>(room_,
- joinState == JoinState::Invite ? "invite_state" : "state"))
+ joinState == JoinState::Invite ? "invite_state"_ls : "state"_ls))
{
switch (joinState) {
case JoinState::Join:
- ephemeral = load<Events>(room_, "ephemeral");
- accountData = load<Events>(room_, "account_data");
+ ephemeral = load<Events>(room_, "ephemeral"_ls);
+ accountData = load<Events>(room_, "account_data"_ls);
FALLTHROUGH;
case JoinState::Leave:
{
- timeline = load<RoomEvents>(room_, "timeline");
- auto timelineJson = room_.value("timeline").toObject();
- timelineLimited = timelineJson.value("limited").toBool();
- timelinePrevBatch = timelineJson.value("prev_batch").toString();
+ timeline = load<RoomEvents>(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;
}
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/lib/room.cpp b/lib/room.cpp
index 8e1eb8e8..080ad30d 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -110,7 +110,7 @@ class Room::Private
QHash<const User*, QString> lastReadEventIds;
QString serverReadMarker;
TagsMap tags;
- QHash<QString, AccountDataMap> accountData;
+ std::unordered_map<QString, EventPtr> accountData;
QString prevBatch;
QPointer<GetRoomEventsJob> eventsHistoryJob;
@@ -168,7 +168,7 @@ class Room::Private
{
return !ti->isRedacted() &&
ti->senderId() != connection->userId() &&
- ti->type() == EventType::RoomMessage;
+ is<RoomMessageEvent>(*ti);
}
void addNewMessageEvents(RoomEvents&& events);
@@ -203,14 +203,14 @@ class Room::Private
auto requestSetState(const QString& stateKey, const EvT& event)
{
return connection->callApi<SetRoomStateWithKeyJob>(
- id, EvT::typeId(), stateKey, event.toJson());
+ id, EvT::matrixTypeId(), stateKey, event.contentJson());
}
template <typename EvT>
auto requestSetState(const EvT& event)
{
return connection->callApi<SetRoomStateJob>(
- id, EvT::typeId(), event.toJson());
+ id, EvT::matrixTypeId(), event.contentJson());
}
/**
@@ -224,8 +224,8 @@ class Room::Private
void broadcastTagUpdates()
{
connection->callApi<SetAccountDataPerRoomJob>(
- 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() && is<RoomMessageEvent>(**evtIt))
{
auto* event = evtIt->viewAs<RoomMessageEvent>();
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 && is<RedactionEvent>(*e);
}
void Room::Private::processRedaction(event_ptr_tt<RedactionEvent>&& redaction)
@@ -1292,26 +1293,30 @@ void Room::Private::processRedaction(event_ptr_tt<RedactionEvent>&& 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<std::pair<EventType, QStringList>> 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<std::pair<Event::Type, QStringList>> 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<RedactionEvent>&& 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<RedactionEvent>&& 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<RoomEvent>(originalJson)) };
+ auto oldEvent = ti.replaceEvent(loadEvent<RoomEvent>(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<const RoomNameEvent&>(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<const RoomAliasesEvent&>(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<const RoomCanonicalAliasEvent&>(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<const RoomTopicEvent&>(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<const RoomAvatarEvent&>(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<const RoomMemberEvent&>(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<const EncryptionEvent&>(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<TypingEvent>(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<ReceiptEvent>(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<const TagEvent>(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<const ReadMarkerEvent>(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<AccountDataMap>(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<User *> &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 <typename EvtT>
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..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 <typename EventT>
const EventT* viewAs() const { return weakPtrCast<const EventT>(evt); }
const RoomEventPtr& operator->() const { return evt; }
+ const RoomEvent& operator*() const { return *evt; }
index_t index() const { return idx; }
// Used for event redaction
@@ -129,10 +133,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 +279,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<T1>(static_cast<T1*>(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 <typename T>
+ struct function_traits : public function_traits<decltype(&T::operator())>
+ { }; // A generic function object that has (non-overloaded) operator()
+
+ // Specialisation for a function
+ template <typename ReturnT, typename ArgT>
+ struct function_traits<ReturnT(ArgT)>
+ {
+ using return_type = ReturnT;
+ using arg_type = ArgT;
+ };
+
+ // Specialisation for a member function
+ template <typename ReturnT, typename ClassT, typename ArgT>
+ struct function_traits<ReturnT(ClassT::*)(ArgT)>
+ : function_traits<ReturnT(ArgT)>
+ { };
+
+ // Specialisation for a const member function
+ template <typename ReturnT, typename ClassT, typename ArgT>
+ struct function_traits<ReturnT(ClassT::*)(ArgT) const>
+ : function_traits<ReturnT(ArgT)>
+ { };
+
+ template <typename FnT>
+ using fn_return_t = typename function_traits<FnT>::return_type;
+
+ template <typename FnT>
+ using fn_arg_t = typename function_traits<FnT>::arg_type;
+
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
// Copy-pasted from Qt 5.10
template <typename T>
@@ -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.