diff options
-rw-r--r-- | connection.cpp | 38 | ||||
-rw-r--r-- | connection.h | 61 | ||||
-rw-r--r-- | jobs/generated/create_room.cpp | 3 | ||||
-rw-r--r-- | jobs/generated/create_room.h | 2 | ||||
-rw-r--r-- | room.cpp | 11 | ||||
-rw-r--r-- | room.h | 2 |
6 files changed, 94 insertions, 23 deletions
diff --git a/connection.cpp b/connection.cpp index c515e5a4..e06baef7 100644 --- a/connection.cpp +++ b/connection.cpp @@ -24,6 +24,7 @@ #include "jobs/generated/login.h" #include "jobs/generated/logout.h" #include "jobs/generated/receipts.h" +#include "jobs/generated/leaving.h" #include "jobs/sendeventjob.h" #include "jobs/joinroomjob.h" #include "jobs/roommessagesjob.h" @@ -61,7 +62,7 @@ class Connection::Private // Leave state of the same room. QHash<QPair<QString, bool>, Room*> roomMap; QVector<QString> roomIdsToForget; - QHash<QString, User*> userMap; + QMap<QString, User*> userMap; QString userId; SyncJob* syncJob = nullptr; @@ -385,6 +386,27 @@ DownloadFileJob* Connection::downloadFile(const QUrl& url, return job; } +CreateRoomJob* Connection::createRoom(RoomVisibility visibility, + const QString& alias, const QString& name, const QString& topic, + const QVector<QString>& invites, const QString& presetName, + bool isDirect, bool guestsCanJoin, + const QVector<CreateRoomJob::StateEvent>& initialState, + const QVector<CreateRoomJob::Invite3pid>& invite3pids, + const QJsonObject creationContent) +{ + return callApi<CreateRoomJob>( + visibility == PublishRoom ? "public" : "private", alias, name, + topic, invites, invite3pids, creationContent, initialState, + presetName, isDirect, guestsCanJoin); +} + +CreateRoomJob* Connection::createDirectChat(const QString& userId, + const QString& topic, const QString& name) +{ + return createRoom(UnpublishRoom, "", name, topic, {userId}, + "trusted_private_chat", true); +} + ForgetRoomJob* Connection::forgetRoom(const QString& id) { // To forget is hard :) First we should ensure the local user is not @@ -437,8 +459,9 @@ User* Connection::user(const QString& userId) { if( d->userMap.contains(userId) ) return d->userMap.value(userId); - auto* user = createUser(this, userId); + auto* user = userFactory(this, userId); d->userMap.insert(userId, user); + emit newUser(user); return user; } @@ -493,6 +516,11 @@ QHash< QPair<QString, bool>, Room* > Connection::roomMap() const return roomMap; } +QMap<QString, User*> Connection::users() const +{ + return d->userMap; +} + const ConnectionData* Connection::connectionData() const { return d->data.get(); @@ -515,7 +543,7 @@ Room* Connection::provideRoom(const QString& id, JoinState joinState) } else { - room = createRoom(this, id, joinState); + room = roomFactory(this, id, joinState); if (!room) { qCCritical(MAIN) << "Failed to create a room" << id; @@ -550,11 +578,11 @@ Room* Connection::provideRoom(const QString& id, JoinState joinState) return room; } -Connection::room_factory_t Connection::createRoom = +Connection::room_factory_t Connection::roomFactory = [](Connection* c, const QString& id, JoinState joinState) { return new Room(c, id, joinState); }; -Connection::user_factory_t Connection::createUser = +Connection::user_factory_t Connection::userFactory = [](Connection* c, const QString& id) { return new User(id, c); }; QByteArray Connection::generateTxnId() diff --git a/connection.h b/connection.h index 79d7d658..2f7c38b3 100644 --- a/connection.h +++ b/connection.h @@ -18,7 +18,7 @@ #pragma once -#include "jobs/generated/leaving.h" +#include "jobs/generated/create_room.h" #include "joinstate.h" #include <QtCore/QObject> @@ -39,6 +39,7 @@ namespace QMatrixClient class SyncData; class RoomMessagesJob; class PostReceiptJob; + class ForgetRoomJob; class MediaThumbnailJob; class JoinRoomJob; class UploadContentJob; @@ -51,6 +52,11 @@ namespace QMatrixClient /** Whether or not the rooms state should be cached locally * \sa loadState(), saveState() */ + Q_PROPERTY(User* localUser READ user CONSTANT) + Q_PROPERTY(QString localUserId READ userId CONSTANT) + Q_PROPERTY(QString deviceId READ deviceId CONSTANT) + Q_PROPERTY(QByteArray accessToken READ accessToken CONSTANT) + Q_PROPERTY(QUrl homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged) Q_PROPERTY(bool cacheState READ cacheState WRITE setCacheState NOTIFY cacheStateChanged) public: using room_factory_t = @@ -58,11 +64,14 @@ namespace QMatrixClient using user_factory_t = std::function<User*(Connection*, const QString&)>; + enum RoomVisibility { PublishRoom, UnpublishRoom }; // FIXME: Should go inside CreateRoomJob + explicit Connection(QObject* parent = nullptr); explicit Connection(const QUrl& server, QObject* parent = nullptr); virtual ~Connection(); QHash<QPair<QString, bool>, Room*> roomMap() const; + QMap<QString, User*> users() const; /** Sends /forget to the server and also deletes room locally. * This method is in Connection, not in Room, since it's a @@ -80,14 +89,14 @@ namespace QMatrixClient // FIXME: Convert Q_INVOKABLEs to Q_PROPERTIES // (breaks back-compatibility) - Q_INVOKABLE QUrl homeserver() const; + QUrl homeserver() const; Q_INVOKABLE User* user(const QString& userId); - Q_INVOKABLE User* user(); - Q_INVOKABLE QString userId() const; - Q_INVOKABLE QString deviceId() const; + User* user(); + QString userId() const; + QString deviceId() const; /** @deprecated Use accessToken() instead. */ Q_INVOKABLE QString token() const; - Q_INVOKABLE QByteArray accessToken() const; + QByteArray accessToken() const; Q_INVOKABLE SyncJob* syncJob() const; Q_INVOKABLE int millisToReconnect() const; @@ -145,7 +154,7 @@ namespace QMatrixClient template <typename T = Room> static void setRoomType() { - createRoom = + roomFactory = [](Connection* c, const QString& id, JoinState joinState) { return new T(c, id, joinState); }; } @@ -153,7 +162,7 @@ namespace QMatrixClient template <typename T = User> static void setUserType() { - createUser = + userFactory = [](Connection* c, const QString& id) { return new T(id, c); }; } @@ -186,17 +195,34 @@ namespace QMatrixClient int requestedHeight) const; // QIODevice* should already be open - virtual UploadContentJob* uploadContent(QIODevice* contentSource, + UploadContentJob* uploadContent(QIODevice* contentSource, const QString& filename = {}, const QString& contentType = {}) const; - virtual UploadContentJob* uploadFile(const QString& fileName, - const QString& contentType = {}); - virtual GetContentJob* getContent(const QString& mediaId) const; + UploadContentJob* uploadFile(const QString& fileName, + const QString& contentType = {}); + GetContentJob* getContent(const QString& mediaId) const; GetContentJob* getContent(const QUrl& url) const; // If localFilename is empty, a temporary file will be created - virtual DownloadFileJob* downloadFile(const QUrl& url, + DownloadFileJob* downloadFile(const QUrl& url, const QString& localFilename = {}) const; + /** + * \brief Create a room (generic method) + * This method allows to customize room entirely to your liking, + * providing all the attributes the original CS API provides. + */ + CreateRoomJob* createRoom(RoomVisibility visibility, + const QString& alias, const QString& name, const QString& topic, + const QVector<QString>& invites, const QString& presetName = {}, bool isDirect = false, + bool guestsCanJoin = false, + const QVector<CreateRoomJob::StateEvent>& initialState = {}, + const QVector<CreateRoomJob::Invite3pid>& invite3pids = {}, + const QJsonObject creationContent = {}); + + /** Create a direct chat with a single user, optional name and topic */ + CreateRoomJob* createDirectChat(const QString& userId, + const QString& topic = {}, const QString& name = {}); + virtual JoinRoomJob* joinRoom(const QString& roomAlias); // Old API that will be abolished any time soon. DO NOT USE. @@ -237,6 +263,8 @@ namespace QMatrixClient void syncDone(); void syncError(QString error); + void newUser(User* user); + /** * \group Signals emitted on room transitions * @@ -310,7 +338,7 @@ namespace QMatrixClient * the server; in particular, does not automatically create rooms * on the server. * @return a pointer to a Room object with the specified id; nullptr - * if roomId is empty if createRoom() failed to create a Room object. + * if roomId is empty if roomFactory() failed to create a Room object. */ Room* provideRoom(const QString& roomId, JoinState joinState); @@ -340,7 +368,8 @@ namespace QMatrixClient const QString& initialDeviceName, const QString& deviceId = {}); - static room_factory_t createRoom; - static user_factory_t createUser; + static room_factory_t roomFactory; + static user_factory_t userFactory; }; } // namespace QMatrixClient +Q_DECLARE_METATYPE(QMatrixClient::Connection*) diff --git a/jobs/generated/create_room.cpp b/jobs/generated/create_room.cpp index be06873a..de7807b5 100644 --- a/jobs/generated/create_room.cpp +++ b/jobs/generated/create_room.cpp @@ -74,7 +74,7 @@ class CreateRoomJob::Private QString roomId; }; -CreateRoomJob::CreateRoomJob(const QString& visibility, const QString& roomAliasName, const QString& name, const QString& topic, const QVector<QString>& invite, const QVector<Invite3pid>& invite3pid, const QJsonObject& creationContent, const QVector<StateEvent>& initialState, const QString& preset, bool isDirect) +CreateRoomJob::CreateRoomJob(const QString& visibility, const QString& roomAliasName, const QString& name, const QString& topic, const QVector<QString>& invite, const QVector<Invite3pid>& invite3pid, const QJsonObject& creationContent, const QVector<StateEvent>& initialState, const QString& preset, bool isDirect, bool guestCanJoin) : BaseJob(HttpVerb::Post, "CreateRoomJob", basePath % "/createRoom") , d(new Private) @@ -95,6 +95,7 @@ CreateRoomJob::CreateRoomJob(const QString& visibility, const QString& roomAlias if (!preset.isEmpty()) _data.insert("preset", toJson(preset)); _data.insert("is_direct", toJson(isDirect)); + _data.insert("guest_can_join", toJson(guestCanJoin)); setRequestData(_data); } diff --git a/jobs/generated/create_room.h b/jobs/generated/create_room.h index 13c9d2c0..b479615a 100644 --- a/jobs/generated/create_room.h +++ b/jobs/generated/create_room.h @@ -40,7 +40,7 @@ namespace QMatrixClient // End of inner data structures - explicit CreateRoomJob(const QString& visibility = {}, const QString& roomAliasName = {}, const QString& name = {}, const QString& topic = {}, const QVector<QString>& invite = {}, const QVector<Invite3pid>& invite3pid = {}, const QJsonObject& creationContent = {}, const QVector<StateEvent>& initialState = {}, const QString& preset = {}, bool isDirect = {}); + explicit CreateRoomJob(const QString& visibility = {}, const QString& roomAliasName = {}, const QString& name = {}, const QString& topic = {}, const QVector<QString>& invite = {}, const QVector<Invite3pid>& invite3pid = {}, const QJsonObject& creationContent = {}, const QVector<StateEvent>& initialState = {}, const QString& preset = {}, bool isDirect = {}, bool guestCanJoin = {}); ~CreateRoomJob() override; const QString& roomId() const; @@ -862,6 +862,17 @@ void Room::postMessage(const RoomMessageEvent& event) connection()->callApi<SendEventJob>(id(), event); } +void Room::setName(const QString& newName) +{ + connection()->callApi<SetRoomStateJob>(id(), RoomNameEvent(newName)); +} + +void Room::setCanonicalAlias(const QString& newAlias) +{ + connection()->callApi<SetRoomStateJob>(id(), + RoomCanonicalAliasEvent(newAlias)); +} + void Room::setTopic(const QString& newTopic) { RoomTopicEvent evt(newTopic); @@ -235,6 +235,8 @@ namespace QMatrixClient /** @deprecated If you have a custom event type, construct the event * and pass it as a whole to postMessage() */ void postMessage(const QString& type, const QString& plainText); + void setName(const QString& newName); + void setCanonicalAlias(const QString& newAlias); void setTopic(const QString& newTopic); void getPreviousContent(int limit = 10); |