diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-03-26 12:35:49 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-03-25 21:38:03 -0700 |
commit | 381ab25563cce26be8e3983b3fb3b8090385a766 (patch) | |
tree | bf8c4fed0c8b8d49af23676762d549f7bdd37cb6 | |
parent | b385baadc8e73ff3c499a0111e2a553d35dd29b6 (diff) | |
download | libquotient-381ab25563cce26be8e3983b3fb3b8090385a766.tar.gz libquotient-381ab25563cce26be8e3983b3fb3b8090385a766.zip |
Connection::doInDirectChat() and refactored direct chat requesting logic
Basically, the whole requestDirectChat() body has been moved and generalised to doInDirectChat(), and requestDirectChat() delegates to doInDirectChat(). The logic has been updated to cope with formerly left/forgotten rooms present in the list of direct chats (cleaning up the list along the way).
-rw-r--r-- | connection.cpp | 65 | ||||
-rw-r--r-- | connection.h | 9 |
2 files changed, 45 insertions, 29 deletions
diff --git a/connection.cpp b/connection.cpp index b32f38ea..2a748eb1 100644 --- a/connection.cpp +++ b/connection.cpp @@ -436,38 +436,45 @@ CreateRoomJob* Connection::createRoom(RoomVisibility visibility, void Connection::requestDirectChat(const QString& userId) { - auto roomId = d->directChats.value(user(userId)); - if (roomId.isEmpty()) - { - auto j = createDirectChat(userId); - connect(j, &BaseJob::success, this, [this,j,userId,roomId] { - qCDebug(MAIN) << "Direct chat with" << userId - << "has been created as" << roomId; - emit directChatAvailable(roomMap().value({j->roomId(), false})); - }); - return; - } + doInDirectChat(userId, [this] (Room* r) { emit directChatAvailable(r); }); +} - auto room = roomMap().value({roomId, false}, nullptr); - if (room) - { - Q_ASSERT(room->id() == roomId); - qCDebug(MAIN) << "Requested direct chat with" << userId - << "is already available as" << room->id(); - emit directChatAvailable(room); - return; - } - room = roomMap().value({roomId, true}, nullptr); - if (room) +void Connection::doInDirectChat(const QString& userId, + std::function<void (Room*)> operation) +{ + // There can be more than one DC; find the first valid, and delete invalid + // (left/forgotten) ones along the way. + for (auto roomId: d->directChats.values(user(userId))) { - Q_ASSERT(room->id() == roomId); - auto j = joinRoom(room->id()); - connect(j, &BaseJob::success, this, [this,j,roomId,userId] { - qCDebug(MAIN) << "Joined the already invited direct chat with" - << userId << "as" << roomId; - emit directChatAvailable(roomMap().value({roomId, false})); - }); + if (auto r = room(roomId, JoinState::Join)) + { + Q_ASSERT(r->id() == roomId); + qCDebug(MAIN) << "Requested direct chat with" << userId + << "is already available as" << r->id(); + operation(r); + return; + } + if (auto ir = invitation(roomId)) + { + Q_ASSERT(ir->id() == roomId); + auto j = joinRoom(ir->id()); + connect(j, &BaseJob::success, this, [this,roomId,userId,operation] { + qCDebug(MAIN) << "Joined the already invited direct chat with" + << userId << "as" << roomId; + operation(room(roomId, JoinState::Join)); + }); + } + qCWarning(MAIN) << "Direct chat with" << userId << "known as room" + << roomId << "is not valid, discarding it"; + removeFromDirectChats(roomId); } + + auto j = createDirectChat(userId); + connect(j, &BaseJob::success, this, [this,j,userId,operation] { + qCDebug(MAIN) << "Direct chat with" << userId + << "has been created as" << j->roomId(); + operation(room(j->roomId(), JoinState::Join)); + }); } CreateRoomJob* Connection::createDirectChat(const QString& userId, diff --git a/connection.h b/connection.h index 6a5285f9..7c11c32d 100644 --- a/connection.h +++ b/connection.h @@ -261,6 +261,15 @@ namespace QMatrixClient */ Q_INVOKABLE void requestDirectChat(const QString& userId); + /** Run an operation in a direct chat with the user + * This method may return synchronously or asynchoronously depending + * on whether a direct chat room with the respective person exists + * already. Instead of emitting a signal it executes the passed + * function object with the direct chat room as its parameter. + */ + Q_INVOKABLE void doInDirectChat(const QString& userId, + std::function<void(Room*)> operation); + /** Create a direct chat with a single user, optional name and topic * A room will always be created, unlike in requestDirectChat. * It is advised to use requestDirectChat as a default way of getting |