diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-10-19 08:12:50 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-10-19 08:14:56 +0900 |
commit | ecc364d4ad752b34e41b717e3deff4d17a840378 (patch) | |
tree | ca1077fb3a751ad01f6638ee5733ddd4583d005f | |
parent | 8800690c691dc9534fdb0f2d902862f816704d50 (diff) | |
parent | f2f85ba093df5dcd991fd206af4d79d57f4c7fc8 (diff) | |
download | libquotient-ecc364d4ad752b34e41b717e3deff4d17a840378.tar.gz libquotient-ecc364d4ad752b34e41b717e3deff4d17a840378.zip |
Merge branch 'master' into kitsune-gtad
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | connection.cpp | 41 | ||||
-rw-r--r-- | connection.h | 18 | ||||
-rw-r--r-- | events/roommemberevent.cpp | 8 | ||||
-rw-r--r-- | jobs/basejob.cpp | 14 | ||||
-rw-r--r-- | jobs/basejob.h | 1 | ||||
-rw-r--r-- | jobs/generated/leaving.cpp | 30 | ||||
-rw-r--r-- | jobs/generated/leaving.h | 31 | ||||
-rw-r--r-- | jobs/generated/logout.cpp | 22 | ||||
-rw-r--r-- | jobs/generated/logout.h | 24 | ||||
-rw-r--r-- | jobs/generated/profile.cpp | 144 | ||||
-rw-r--r-- | jobs/generated/profile.h | 80 | ||||
-rw-r--r-- | jobs/leaveroomjob.cpp | 26 | ||||
-rw-r--r-- | jobs/leaveroomjob.h | 30 | ||||
-rw-r--r-- | jobs/logoutjob.cpp | 26 | ||||
-rw-r--r-- | jobs/logoutjob.h | 30 | ||||
-rw-r--r-- | jobs/sendeventjob.cpp | 2 | ||||
-rw-r--r-- | jobs/sendeventjob.h | 4 | ||||
-rw-r--r-- | jobs/setroomstatejob.h | 8 | ||||
-rw-r--r-- | jobs/syncjob.cpp | 12 | ||||
-rw-r--r-- | joinstate.h | 16 | ||||
-rw-r--r-- | room.cpp | 33 | ||||
-rw-r--r-- | room.h | 16 | ||||
-rw-r--r-- | user.cpp | 38 | ||||
-rw-r--r-- | user.h | 4 | ||||
-rw-r--r-- | util.h | 2 |
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 @@ -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; @@ -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(); @@ -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); }); } + @@ -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; @@ -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 |