aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-10-19 08:12:50 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-10-19 08:14:56 +0900
commitecc364d4ad752b34e41b717e3deff4d17a840378 (patch)
treeca1077fb3a751ad01f6638ee5733ddd4583d005f
parent8800690c691dc9534fdb0f2d902862f816704d50 (diff)
parentf2f85ba093df5dcd991fd206af4d79d57f4c7fc8 (diff)
downloadlibquotient-ecc364d4ad752b34e41b717e3deff4d17a840378.tar.gz
libquotient-ecc364d4ad752b34e41b717e3deff4d17a840378.zip
Merge branch 'master' into kitsune-gtad
-rw-r--r--CMakeLists.txt2
-rw-r--r--connection.cpp41
-rw-r--r--connection.h18
-rw-r--r--events/roommemberevent.cpp8
-rw-r--r--jobs/basejob.cpp14
-rw-r--r--jobs/basejob.h1
-rw-r--r--jobs/generated/leaving.cpp30
-rw-r--r--jobs/generated/leaving.h31
-rw-r--r--jobs/generated/logout.cpp22
-rw-r--r--jobs/generated/logout.h24
-rw-r--r--jobs/generated/profile.cpp144
-rw-r--r--jobs/generated/profile.h80
-rw-r--r--jobs/leaveroomjob.cpp26
-rw-r--r--jobs/leaveroomjob.h30
-rw-r--r--jobs/logoutjob.cpp26
-rw-r--r--jobs/logoutjob.h30
-rw-r--r--jobs/sendeventjob.cpp2
-rw-r--r--jobs/sendeventjob.h4
-rw-r--r--jobs/setroomstatejob.h8
-rw-r--r--jobs/syncjob.cpp12
-rw-r--r--joinstate.h16
-rw-r--r--room.cpp33
-rw-r--r--room.h16
-rw-r--r--user.cpp38
-rw-r--r--user.h4
-rw-r--r--util.h2
26 files changed, 478 insertions, 184 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0d2f688f..b1d72131 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -83,11 +83,9 @@ set(libqmatrixclient_SRCS
jobs/setroomstatejob.cpp
jobs/postreceiptjob.cpp
jobs/joinroomjob.cpp
- jobs/leaveroomjob.cpp
jobs/roommessagesjob.cpp
jobs/syncjob.cpp
jobs/mediathumbnailjob.cpp
- jobs/logoutjob.cpp
)
if (MATRIX_DOC_PATH AND GTAD_PATH)
diff --git a/connection.cpp b/connection.cpp
index e20f843f..84a52149 100644
--- a/connection.cpp
+++ b/connection.cpp
@@ -21,12 +21,11 @@
#include "user.h"
#include "events/event.h"
#include "room.h"
+#include "jobs/generated/logout.h"
#include "jobs/passwordlogin.h"
-#include "jobs/logoutjob.h"
#include "jobs/sendeventjob.h"
#include "jobs/postreceiptjob.h"
#include "jobs/joinroomjob.h"
-#include "jobs/leaveroomjob.h"
#include "jobs/roommessagesjob.h"
#include "jobs/syncjob.h"
#include "jobs/mediathumbnailjob.h"
@@ -238,6 +237,44 @@ MediaThumbnailJob* Connection::getThumbnail(const QUrl& url, int requestedWidth,
return getThumbnail(url, QSize(requestedWidth, requestedHeight));
}
+ForgetRoomJob* Connection::forgetRoom(const QString& id)
+{
+ // To forget is hard :) First we should ensure the local user is not
+ // in the room (by leaving it, if necessary); once it's done, the /forget
+ // endpoint can be called; and once this is through, the local Room object
+ // (if any existed) is deleted. At the same time, we still have to
+ // (basically immediately) return a pointer to ForgetRoomJob. Therefore
+ // a ForgetRoomJob is created in advance and can be returned in a probably
+ // not-yet-started state (it will start once /leave completes).
+ auto forgetJob = new ForgetRoomJob(id);
+ auto joinedRoom = d->roomMap.value({id, false});
+ if (joinedRoom && joinedRoom->joinState() == JoinState::Join)
+ {
+ auto leaveJob = joinedRoom->leaveRoom();
+ connect(leaveJob, &BaseJob::success,
+ this, [=] { forgetJob->start(connectionData()); });
+ connect(leaveJob, &BaseJob::failure,
+ this, [=] { forgetJob->abandon(); });
+ }
+ else
+ forgetJob->start(connectionData());
+ connect(forgetJob, &BaseJob::success, this, [=]
+ {
+ // If the room happens to be in the map (possible in both forms),
+ // delete the found object(s).
+ for (auto f: {false, true})
+ if (auto r = d->roomMap.take({ id, f }))
+ {
+ emit aboutToDeleteRoom(r);
+ qCDebug(MAIN) << "Room" << id
+ << "in join state" << toCString(r->joinState())
+ << "will be deleted";
+ r->deleteLater();
+ }
+ });
+ return forgetJob;
+}
+
QUrl Connection::homeserver() const
{
return d->data->baseUrl();
diff --git a/connection.h b/connection.h
index 213bf26f..b7d049f1 100644
--- a/connection.h
+++ b/connection.h
@@ -18,6 +18,7 @@
#pragma once
+#include "jobs/generated/leaving.h"
#include "joinstate.h"
#include <QtCore/QObject>
@@ -94,6 +95,19 @@ namespace QMatrixClient
/** @deprecated Use callApi<MediaThumbnailJob>() instead */
MediaThumbnailJob* getThumbnail(const QUrl& url, int requestedWidth,
int requestedHeight) const;
+ /** Sends /forget to the server and also deletes room locally.
+ * This method is in Connection, not in Room, since it's a
+ * room lifecycle operation, and Connection is an acting room manager.
+ * It ensures that the local user is not a member of a room (running /leave,
+ * if necessary) then issues a /forget request and if that one doesn't fail
+ * deletion of the local Room object is ensured.
+ * \param id - the room id to forget
+ * \return - the ongoing /forget request to the server; note that the
+ * success() signal of this request is connected to deleteLater()
+ * of a respective room so by the moment this finishes, there might be no
+ * Room object anymore.
+ */
+ ForgetRoomJob* forgetRoom(const QString& id);
Q_INVOKABLE QUrl homeserver() const;
Q_INVOKABLE User* user(const QString& userId);
@@ -144,9 +158,9 @@ namespace QMatrixClient
* argument - callApi() will pass it automatically.
*/
template <typename JobT, typename... JobArgTs>
- JobT* callApi(JobArgTs... jobArgs) const
+ JobT* callApi(JobArgTs&&... jobArgs) const
{
- auto job = new JobT(jobArgs...);
+ auto job = new JobT(std::forward<JobArgTs>(jobArgs)...);
job->start(connectionData());
return job;
}
diff --git a/events/roommemberevent.cpp b/events/roommemberevent.cpp
index 5973acc7..19f116d2 100644
--- a/events/roommemberevent.cpp
+++ b/events/roommemberevent.cpp
@@ -22,6 +22,9 @@
using namespace QMatrixClient;
+static const auto membershipStrings =
+ { "invite", "join", "knock", "leave", "ban" };
+
RoomMemberEvent::RoomMemberEvent(const QJsonObject& obj)
: RoomEvent(Type::RoomMember, obj), _userId(obj["state_key"].toString())
{
@@ -29,11 +32,10 @@ RoomMemberEvent::RoomMemberEvent(const QJsonObject& obj)
_displayName = contentObj["displayname"].toString();
_avatarUrl = contentObj["avatar_url"].toString();
QString membershipString = contentObj["membership"].toString();
- const auto supportedStrings = { "invite", "join", "knock", "leave", "ban" };
- for (auto it = supportedStrings.begin(); it != supportedStrings.end(); ++it)
+ for (auto it = membershipStrings.begin(); it != membershipStrings.end(); ++it)
if (membershipString == *it)
{
- _membership = MembershipType(it - supportedStrings.begin());
+ _membership = MembershipType(it - membershipStrings.begin());
return;
}
qCWarning(EVENTS) << "Unknown MembershipType: " << membershipString;
diff --git a/jobs/basejob.cpp b/jobs/basejob.cpp
index 240192d9..7794337e 100644
--- a/jobs/basejob.cpp
+++ b/jobs/basejob.cpp
@@ -24,7 +24,7 @@
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtCore/QTimer>
-//#include <QtCore/QStringBuilder>
+#include <QtCore/QRegularExpression>
#include <array>
@@ -79,6 +79,13 @@ inline QDebug operator<<(QDebug dbg, const BaseJob* j)
return dbg << j->objectName();
}
+QDebug QMatrixClient::operator<<(QDebug dbg, const BaseJob::Status& s)
+{
+ QRegularExpression filter { "(access_token)=[-_A-Za-z0-9]+" };
+ return dbg << s.code << ':'
+ << QString(s.message).replace(filter, "\1=HIDDEN");
+}
+
BaseJob::BaseJob(HttpVerb verb, const QString& name, const QString& endpoint,
const Query& query, const Data& data, bool needsToken)
: d(new Private(verb, endpoint, query, data, needsToken))
@@ -331,10 +338,7 @@ void BaseJob::setStatus(Status s)
{
d->status = s;
if (!s.good())
- {
- qCWarning(d->logCat) << this << "status" << s.code
- << ":" << s.message;
- }
+ qCWarning(d->logCat) << this << "status" << s;
}
void BaseJob::setStatus(int code, QString message)
diff --git a/jobs/basejob.h b/jobs/basejob.h
index 2f7bd9cd..f8b367c6 100644
--- a/jobs/basejob.h
+++ b/jobs/basejob.h
@@ -110,6 +110,7 @@ namespace QMatrixClient
Status(int c, QString m) : code(c), message(std::move(m)) { }
bool good() const { return code < ErrorLevel; }
+ friend QDebug operator<<(QDebug dbg, const Status& s);
int code;
QString message;
diff --git a/jobs/generated/leaving.cpp b/jobs/generated/leaving.cpp
new file mode 100644
index 00000000..7fed347b
--- /dev/null
+++ b/jobs/generated/leaving.cpp
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+
+#include "leaving.h"
+
+#include "jobs/converters.h"
+#include <QtCore/QStringBuilder>
+
+using namespace QMatrixClient;
+
+static const auto basePath = QStringLiteral("/_matrix/client/r0");
+
+LeaveRoomJob::LeaveRoomJob(QString roomId)
+ : BaseJob(HttpVerb::Post, "LeaveRoomJob",
+ basePath % "/rooms/" % roomId % "/leave",
+ Query { },
+ Data { }
+ )
+{ }
+
+ForgetRoomJob::ForgetRoomJob(QString roomId)
+ : BaseJob(HttpVerb::Post, "ForgetRoomJob",
+ basePath % "/rooms/" % roomId % "/forget",
+ Query { },
+ Data { }
+ )
+{ }
+
diff --git a/jobs/generated/leaving.h b/jobs/generated/leaving.h
new file mode 100644
index 00000000..96304084
--- /dev/null
+++ b/jobs/generated/leaving.h
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+
+#pragma once
+
+#include "../basejob.h"
+
+#include <QtCore/QString>
+
+
+namespace QMatrixClient
+{
+
+ // Operations
+
+ class LeaveRoomJob : public BaseJob
+ {
+ public:
+ explicit LeaveRoomJob(QString roomId);
+
+ };
+ class ForgetRoomJob : public BaseJob
+ {
+ public:
+ explicit ForgetRoomJob(QString roomId);
+
+ };
+
+} // namespace QMatrixClient
diff --git a/jobs/generated/logout.cpp b/jobs/generated/logout.cpp
new file mode 100644
index 00000000..b750efe2
--- /dev/null
+++ b/jobs/generated/logout.cpp
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+
+#include "logout.h"
+
+#include "jobs/converters.h"
+#include <QtCore/QStringBuilder>
+
+using namespace QMatrixClient;
+
+static const auto basePath = QStringLiteral("/_matrix/client/r0");
+
+LogoutJob::LogoutJob()
+ : BaseJob(HttpVerb::Post, "LogoutJob",
+ basePath % "/logout",
+ Query { },
+ Data { }
+ )
+{ }
+
diff --git a/jobs/generated/logout.h b/jobs/generated/logout.h
new file mode 100644
index 00000000..28e85d8f
--- /dev/null
+++ b/jobs/generated/logout.h
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+
+#pragma once
+
+#include "../basejob.h"
+
+
+
+namespace QMatrixClient
+{
+
+ // Operations
+
+ class LogoutJob : public BaseJob
+ {
+ public:
+ explicit LogoutJob();
+
+ };
+
+} // namespace QMatrixClient
diff --git a/jobs/generated/profile.cpp b/jobs/generated/profile.cpp
new file mode 100644
index 00000000..9d20a480
--- /dev/null
+++ b/jobs/generated/profile.cpp
@@ -0,0 +1,144 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+
+#include "profile.h"
+
+#include "jobs/converters.h"
+#include <QtCore/QStringBuilder>
+
+using namespace QMatrixClient;
+
+static const auto basePath = QStringLiteral("/_matrix/client/r0");
+
+SetDisplayNameJob::SetDisplayNameJob(QString userId, QString displayname)
+ : BaseJob(HttpVerb::Put, "SetDisplayNameJob",
+ basePath % "/profile/" % userId % "/displayname",
+ Query { },
+ Data {
+ { "displayname", toJson(displayname) }
+ }
+ )
+{ }
+
+class GetDisplayNameJob::Private
+{
+ public:
+ QString displayname;
+
+};
+
+GetDisplayNameJob::GetDisplayNameJob(QString userId)
+ : BaseJob(HttpVerb::Get, "GetDisplayNameJob",
+ basePath % "/profile/" % userId % "/displayname",
+ Query { },
+ Data { }
+ ), d(new Private)
+{ }
+
+GetDisplayNameJob::~GetDisplayNameJob()
+{
+ delete d;
+}
+
+const QString& GetDisplayNameJob::displayname() const
+{
+ return d->displayname;
+}
+
+BaseJob::Status GetDisplayNameJob::parseJson(const QJsonDocument& data)
+{
+ auto json = data.object();
+
+ d->displayname = fromJson<QString>(json.value("displayname"));
+
+ return Success;
+}
+
+SetAvatarUrlJob::SetAvatarUrlJob(QString userId, QString avatar_url)
+ : BaseJob(HttpVerb::Put, "SetAvatarUrlJob",
+ basePath % "/profile/" % userId % "/avatar_url",
+ Query { },
+ Data {
+ { "avatar_url", toJson(avatar_url) }
+ }
+ )
+{ }
+
+class GetAvatarUrlJob::Private
+{
+ public:
+ QString avatar_url;
+
+};
+
+GetAvatarUrlJob::GetAvatarUrlJob(QString userId)
+ : BaseJob(HttpVerb::Get, "GetAvatarUrlJob",
+ basePath % "/profile/" % userId % "/avatar_url",
+ Query { },
+ Data { }
+ ), d(new Private)
+{ }
+
+GetAvatarUrlJob::~GetAvatarUrlJob()
+{
+ delete d;
+}
+
+const QString& GetAvatarUrlJob::avatar_url() const
+{
+ return d->avatar_url;
+}
+
+BaseJob::Status GetAvatarUrlJob::parseJson(const QJsonDocument& data)
+{
+ auto json = data.object();
+
+ d->avatar_url = fromJson<QString>(json.value("avatar_url"));
+
+ return Success;
+}
+
+class GetUserProfileJob::Private
+{
+ public:
+ QString avatar_url;
+ QString displayname;
+
+};
+
+GetUserProfileJob::GetUserProfileJob(QString userId)
+ : BaseJob(HttpVerb::Get, "GetUserProfileJob",
+ basePath % "/profile/" % userId,
+ Query { },
+ Data { }
+ ), d(new Private)
+{ }
+
+GetUserProfileJob::~GetUserProfileJob()
+{
+ delete d;
+}
+
+const QString& GetUserProfileJob::avatar_url() const
+{
+ return d->avatar_url;
+}
+
+const QString& GetUserProfileJob::displayname() const
+{
+ return d->displayname;
+}
+
+BaseJob::Status GetUserProfileJob::parseJson(const QJsonDocument& data)
+{
+ auto json = data.object();
+
+ d->avatar_url = fromJson<QString>(json.value("avatar_url"));
+
+ d->displayname = fromJson<QString>(json.value("displayname"));
+
+ return Success;
+}
+
diff --git a/jobs/generated/profile.h b/jobs/generated/profile.h
new file mode 100644
index 00000000..8e2b195b
--- /dev/null
+++ b/jobs/generated/profile.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+
+#pragma once
+
+#include "../basejob.h"
+
+#include <QtCore/QString>
+
+
+namespace QMatrixClient
+{
+
+ // Operations
+
+ class SetDisplayNameJob : public BaseJob
+ {
+ public:
+ explicit SetDisplayNameJob(QString userId, QString displayname = {});
+
+ };
+ class GetDisplayNameJob : public BaseJob
+ {
+ public:
+ explicit GetDisplayNameJob(QString userId);
+
+ ~GetDisplayNameJob() override;
+
+ const QString& displayname() const;
+
+ protected:
+ Status parseJson(const QJsonDocument& data) override;
+
+ private:
+ class Private;
+ Private* d;
+ };
+ class SetAvatarUrlJob : public BaseJob
+ {
+ public:
+ explicit SetAvatarUrlJob(QString userId, QString avatar_url = {});
+
+ };
+ class GetAvatarUrlJob : public BaseJob
+ {
+ public:
+ explicit GetAvatarUrlJob(QString userId);
+
+ ~GetAvatarUrlJob() override;
+
+ const QString& avatar_url() const;
+
+ protected:
+ Status parseJson(const QJsonDocument& data) override;
+
+ private:
+ class Private;
+ Private* d;
+ };
+ class GetUserProfileJob : public BaseJob
+ {
+ public:
+ explicit GetUserProfileJob(QString userId);
+
+ ~GetUserProfileJob() override;
+
+ const QString& avatar_url() const;
+ const QString& displayname() const;
+
+ protected:
+ Status parseJson(const QJsonDocument& data) override;
+
+ private:
+ class Private;
+ Private* d;
+ };
+
+} // namespace QMatrixClient
diff --git a/jobs/leaveroomjob.cpp b/jobs/leaveroomjob.cpp
deleted file mode 100644
index 54e7f307..00000000
--- a/jobs/leaveroomjob.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
- *
- * 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 "leaveroomjob.h"
-
-using namespace QMatrixClient;
-
-LeaveRoomJob::LeaveRoomJob(const QString& roomId)
- : BaseJob(HttpVerb::Post, "LeaveRoomJob",
- QStringLiteral("_matrix/client/r0/rooms/%1/leave").arg(roomId))
-{ }
diff --git a/jobs/leaveroomjob.h b/jobs/leaveroomjob.h
deleted file mode 100644
index 9224c1c8..00000000
--- a/jobs/leaveroomjob.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
- *
- * 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 "basejob.h"
-
-namespace QMatrixClient
-{
- class LeaveRoomJob: public BaseJob
- {
- public:
- explicit LeaveRoomJob(const QString& roomId);
- };
-} // namespace QMatrixClient
diff --git a/jobs/logoutjob.cpp b/jobs/logoutjob.cpp
deleted file mode 100644
index 5ea5cf4d..00000000
--- a/jobs/logoutjob.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2016 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 "logoutjob.h"
-
-using namespace QMatrixClient;
-
-LogoutJob::LogoutJob()
- : BaseJob(HttpVerb::Post, "LogoutJob", "/_matrix/client/r0/logout")
-{
-}
diff --git a/jobs/logoutjob.h b/jobs/logoutjob.h
deleted file mode 100644
index e1b988dc..00000000
--- a/jobs/logoutjob.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2016 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 "basejob.h"
-
-namespace QMatrixClient
-{
- class LogoutJob: public BaseJob
- {
- public:
- LogoutJob();
- };
-}
diff --git a/jobs/sendeventjob.cpp b/jobs/sendeventjob.cpp
index 7e33e089..f5190d4b 100644
--- a/jobs/sendeventjob.cpp
+++ b/jobs/sendeventjob.cpp
@@ -24,7 +24,7 @@ using namespace QMatrixClient;
SendEventJob::SendEventJob(const QString& roomId, const QString& type,
const QString& plainText)
- : SendEventJob(roomId, new RoomMessageEvent(plainText, type))
+ : SendEventJob(roomId, RoomMessageEvent(plainText, type))
{ }
void SendEventJob::beforeStart(const ConnectionData* connData)
diff --git a/jobs/sendeventjob.h b/jobs/sendeventjob.h
index 7b10b3d4..3a11eb6a 100644
--- a/jobs/sendeventjob.h
+++ b/jobs/sendeventjob.h
@@ -29,12 +29,12 @@ namespace QMatrixClient
public:
/** Constructs a job that sends an arbitrary room event */
template <typename EvT>
- SendEventJob(const QString& roomId, const EvT* event)
+ 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()
Query(),
- Data(event->toJson()))
+ Data(event.toJson()))
{ }
/**
diff --git a/jobs/setroomstatejob.h b/jobs/setroomstatejob.h
index ddc271b9..b7e6d4a1 100644
--- a/jobs/setroomstatejob.h
+++ b/jobs/setroomstatejob.h
@@ -33,24 +33,24 @@ namespace QMatrixClient
*/
template <typename EvT>
SetRoomStateJob(const QString& roomId, const QString& stateKey,
- const EvT* event)
+ const EvT& event)
: BaseJob(HttpVerb::Put, "SetRoomStateJob",
QStringLiteral("_matrix/client/r0/rooms/%1/state/%2/%3")
.arg(roomId, EvT::TypeId, stateKey),
Query(),
- Data(event->toJson()))
+ Data(event.toJson()))
{ }
/**
* Constructs a job that sets a state using an arbitrary room event
* without a state key.
*/
template <typename EvT>
- SetRoomStateJob(const QString& roomId, const EvT* event)
+ SetRoomStateJob(const QString& roomId, const EvT& event)
: BaseJob(HttpVerb::Put, "SetRoomStateJob",
QStringLiteral("_matrix/client/r0/rooms/%1/state/%2")
.arg(roomId, EvT::TypeId),
Query(),
- Data(event->toJson()))
+ Data(event.toJson()))
{ }
QString eventId() const { return _eventId; }
diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp
index 6d37db5c..ce5dd894 100644
--- a/jobs/syncjob.cpp
+++ b/jobs/syncjob.cpp
@@ -69,19 +69,13 @@ BaseJob::Status SyncData::parseJson(const QJsonDocument &data)
// TODO: account_data
QJsonObject rooms = json.value("rooms").toObject();
- static const struct { QString jsonKey; JoinState enumVal; } roomStates[]
+ for (size_t i = 0; i < JoinStateStrings.size(); ++i)
{
- { "join", JoinState::Join },
- { "invite", JoinState::Invite },
- { "leave", JoinState::Leave }
- };
- for (const auto& roomState: roomStates)
- {
- const QJsonObject rs = rooms.value(roomState.jsonKey).toObject();
+ const auto rs = rooms.value(JoinStateStrings[i]).toObject();
// We have a Qt container on the right and an STL one on the left
roomData.reserve(static_cast<size_t>(rs.size()));
for(auto roomIt = rs.begin(); roomIt != rs.end(); ++roomIt)
- roomData.emplace_back(roomIt.key(), roomState.enumVal,
+ roomData.emplace_back(roomIt.key(), JoinState(i),
roomIt.value().toObject());
}
qCDebug(PROFILER) << "*** SyncData::parseJson():" << et.elapsed() << "ms";
diff --git a/joinstate.h b/joinstate.h
index 348ca8a6..d6c374d2 100644
--- a/joinstate.h
+++ b/joinstate.h
@@ -18,12 +18,24 @@
#pragma once
+#include <array>
+
namespace QMatrixClient
{
enum class JoinState
{
- Join,
+ Join = 0,
Invite,
Leave
};
-}
+
+ // We cannot use REGISTER_ENUM outside of a Q_OBJECT and besides, we want
+ // to use strings that match respective JSON keys.
+ static const std::array<const char*, 3> JoinStateStrings
+ { { "join", "invite", "leave" } };
+
+ inline const char* toCString(JoinState js)
+ {
+ return JoinStateStrings[size_t(js)];
+ }
+} // namespace QMatrixClient
diff --git a/room.cpp b/room.cpp
index 79168d85..65cf2d2a 100644
--- a/room.cpp
+++ b/room.cpp
@@ -21,6 +21,7 @@
#include "jobs/generated/kicking.h"
#include "jobs/generated/inviting.h"
#include "jobs/generated/banning.h"
+#include "jobs/generated/leaving.h"
#include "jobs/setroomstatejob.h"
#include "events/roomnameevent.h"
#include "events/roomaliasesevent.h"
@@ -32,7 +33,6 @@
#include "jobs/sendeventjob.h"
#include "jobs/roommessagesjob.h"
#include "jobs/postreceiptjob.h"
-#include "jobs/leaveroomjob.h"
#include "connection.h"
#include "user.h"
@@ -445,7 +445,8 @@ void Room::Private::addMember(User *u)
if (!hasMember(u))
{
insertMemberIntoMap(u);
- connect(u, &User::nameChanged, q, &Room::userRenamed);
+ connect(u, &User::nameChanged, q,
+ [=] (User* u, const QString& newName) { renameMember(u, newName); });
emit q->userAdded(u);
}
}
@@ -490,11 +491,6 @@ void Room::Private::removeMember(User* u)
}
}
-void Room::userRenamed(User* user, QString oldName)
-{
- d->renameMember(user, std::move(oldName));
-}
-
QString Room::roomMembername(User *u) const
{
// See the CS spec, section 11.2.2.3
@@ -581,16 +577,15 @@ void Room::updateData(SyncRoomData&& data)
void Room::postMessage(const QString& type, const QString& plainText)
{
- connection()->callApi<SendEventJob>(id(), type, plainText);
+ postMessage(RoomMessageEvent { plainText, type });
}
void Room::postMessage(const QString& plainText, MessageEventType type)
{
- RoomMessageEvent rme(plainText, type);
- postMessage(&rme);
+ postMessage(RoomMessageEvent { plainText, type });
}
-void Room::postMessage(RoomMessageEvent* event)
+void Room::postMessage(const RoomMessageEvent& event)
{
connection()->callApi<SendEventJob>(id(), event);
}
@@ -598,7 +593,7 @@ void Room::postMessage(RoomMessageEvent* event)
void Room::setTopic(const QString& newTopic)
{
RoomTopicEvent evt(newTopic);
- connection()->callApi<SetRoomStateJob>(id(), &evt);
+ connection()->callApi<SetRoomStateJob>(id(), evt);
}
void Room::getPreviousContent(int limit)
@@ -623,27 +618,27 @@ void Room::Private::getPreviousContent(int limit)
}
}
-void Room::inviteToRoom(const QString& memberId) const
+void Room::inviteToRoom(const QString& memberId)
{
connection()->callApi<InviteUserJob>(id(), memberId);
}
-void Room::leaveRoom() const
+LeaveRoomJob* Room::leaveRoom()
{
- connection()->callApi<LeaveRoomJob>(id());
+ return connection()->callApi<LeaveRoomJob>(id());
}
-void Room::kickMember(const QString& memberId, const QString& reason) const
+void Room::kickMember(const QString& memberId, const QString& reason)
{
connection()->callApi<KickJob>(id(), memberId, reason);
}
-void Room::ban(const QString& userId, const QString& reason) const
+void Room::ban(const QString& userId, const QString& reason)
{
connection()->callApi<BanJob>(id(), userId, reason);
}
-void Room::unban(const QString& userId) const
+void Room::unban(const QString& userId)
{
connection()->callApi<UnbanJob>(id(), userId);
}
@@ -974,7 +969,7 @@ QJsonObject Room::Private::toJson() const
{
QJsonObject content;
content.insert("membership", QStringLiteral("join"));
- content.insert("displayname", i->displayname());
+ content.insert("displayname", i->name());
content.insert("avatar_url", i->avatarUrl().toString());
QJsonObject memberEvent;
diff --git a/room.h b/room.h
index d62d160f..2d0453bc 100644
--- a/room.h
+++ b/room.h
@@ -36,6 +36,7 @@ namespace QMatrixClient
class Connection;
class User;
class MemberSorter;
+ class LeaveRoomJob;
class TimelineItem
{
@@ -150,21 +151,18 @@ namespace QMatrixClient
public slots:
void postMessage(const QString& plainText,
MessageEventType type = MessageEventType::Text);
- void postMessage(RoomMessageEvent* event);
+ void postMessage(const RoomMessageEvent& event);
/** @deprecated */
void postMessage(const QString& type, const QString& plainText);
void setTopic(const QString& newTopic);
void getPreviousContent(int limit = 10);
- void inviteToRoom(const QString& memberId) const;
- void leaveRoom() const;
- void kickMember(const QString& memberId,
- const QString& reason = {}) const;
- void ban(const QString& userId, const QString& reason = {}) const;
- void unban(const QString& userId) const;
-
- void userRenamed(User* user, QString oldName);
+ void inviteToRoom(const QString& memberId);
+ LeaveRoomJob* leaveRoom();
+ void kickMember(const QString& memberId, const QString& reason = {});
+ void ban(const QString& userId, const QString& reason = {});
+ void unban(const QString& userId);
/** Mark all messages in the room as read */
void markAllMessagesAsRead();
diff --git a/user.cpp b/user.cpp
index 12eb2e0b..171d6d6c 100644
--- a/user.cpp
+++ b/user.cpp
@@ -22,7 +22,7 @@
#include "events/event.h"
#include "events/roommemberevent.h"
#include "jobs/mediathumbnailjob.h"
-#include "util.h"
+#include "jobs/generated/profile.h"
#include <QtCore/QTimer>
#include <QtCore/QDebug>
@@ -80,6 +80,24 @@ QString User::name() const
return d->name;
}
+void User::updateName(const QString& newName)
+{
+ const auto oldName = name();
+ if (d->name != newName)
+ {
+ qCDebug(MAIN) << "Renaming" << id()
+ << "from" << oldName << "to" << newName;
+ d->name = newName;
+ emit nameChanged(this, oldName);
+ }
+}
+
+void User::rename(const QString& newName)
+{
+ auto job = d->connection->callApi<SetDisplayNameJob>(id(), newName);
+ connect(job, &BaseJob::success, this, [=] { updateName(newName); });
+}
+
QString User::displayname() const
{
if( !d->name.isEmpty() )
@@ -140,18 +158,15 @@ void User::processEvent(Event* event)
if (e->membership() == MembershipType::Leave)
return;
- if( d->name != e->displayName() )
+ auto newName = e->displayName();
+ QRegularExpression reSuffix(" \\((IRC|Gitter)\\)$");
+ auto match = reSuffix.match(d->name);
+ if (match.hasMatch())
{
- const auto oldName = d->name;
- d->name = e->displayName();
- QRegularExpression reSuffix(" \\((IRC|Gitter)\\)$");
- auto match = reSuffix.match(d->name);
- if (match.hasMatch()) {
- d->bridged = match.captured(1);
- d->name = d->name.left(match.capturedStart(0));
- }
- emit nameChanged(this, oldName);
+ d->bridged = match.captured(1);
+ newName.truncate(match.capturedStart(0));
}
+ updateName(newName);
if( d->avatarUrl != e->avatarUrl() )
{
d->avatarUrl = e->avatarUrl();
@@ -176,3 +191,4 @@ void User::Private::requestAvatar()
emit q->avatarChanged(q);
});
}
+
diff --git a/user.h b/user.h
index a2d58908..79a6f5db 100644
--- a/user.h
+++ b/user.h
@@ -60,11 +60,15 @@ namespace QMatrixClient
public slots:
void requestAvatar();
+ void rename(const QString& newName);
signals:
void nameChanged(User*, QString);
void avatarChanged(User* user);
+ private slots:
+ void updateName(const QString& newName);
+
private:
class Private;
Private* d;
diff --git a/util.h b/util.h
index 1f9e3f0b..0c8f3640 100644
--- a/util.h
+++ b/util.h
@@ -231,7 +231,7 @@ namespace QMatrixClient
template <typename ResultT, typename... ArgTs>
Dispatch<ResultT, ArgTs...> dispatch(ArgTs&& ... args)
{
- return Dispatch<ResultT, ArgTs...>(std::forward<ArgTs...>(args)...);
+ return Dispatch<ResultT, ArgTs...>(std::forward<ArgTs>(args)...);
}
// The below enables pretty-printing of enums in logs