aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp26
-rw-r--r--lib/connection.h7
-rw-r--r--lib/room.cpp3
3 files changed, 29 insertions, 7 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 18fa91e7..c582cf94 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -84,6 +84,7 @@ class Connection::Private
QHash<QPair<QString, bool>, Room*> roomMap;
QVector<QString> roomIdsToForget;
QVector<Room*> firstTimeRooms;
+ QVector<QString> pendingStateRoomIds;
QMap<QString, User*> userMap;
DirectChatsMap directChats;
DirectChatUsersMap directChatUsers;
@@ -339,6 +340,7 @@ void Connection::onSyncSuccess(SyncData &&data, bool fromCache) {
}
if ( auto* r = provideRoom(roomData.roomId, roomData.joinState) )
{
+ d->pendingStateRoomIds.removeOne(roomData.roomId);
r->updateData(std::move(roomData), fromCache);
if (d->firstTimeRooms.removeOne(r))
emit loadedRoomState(r);
@@ -427,14 +429,32 @@ JoinRoomJob* Connection::joinRoom(const QString& roomAlias,
const QStringList& serverNames)
{
auto job = callApi<JoinRoomJob>(roomAlias, serverNames);
+ // Upon completion, ensure a room object in Join state is created but only
+ // if it's not already there due to a sync completing earlier.
connect(job, &JoinRoomJob::success,
- this, [this, job] { provideRoom(job->roomId(), JoinState::Join); });
+ this, [this, job] { provideRoom(job->roomId()); });
return job;
}
-void Connection::leaveRoom(Room* room)
+LeaveRoomJob* Connection::leaveRoom(Room* room)
{
- callApi<LeaveRoomJob>(room->id());
+ const auto& roomId = room->id();
+ const auto job = callApi<LeaveRoomJob>(roomId);
+ if (room->joinState() == JoinState::Invite)
+ {
+ // Workaround matrix-org/synapse#2181 - if the room is in invite state
+ // the invite may have been cancelled but Synapse didn't send it in
+ // `/sync`. See also #273 for the discussion in the library context.
+ d->pendingStateRoomIds.push_back(roomId);
+ connect(job, &LeaveRoomJob::success, this, [this,roomId] {
+ if (d->pendingStateRoomIds.removeOne(roomId))
+ {
+ qCDebug(MAIN) << "Forcing the room to Leave status";
+ provideRoom(roomId, JoinState::Leave);
+ }
+ });
+ }
+ return job;
}
inline auto splitMediaId(const QString& mediaId)
diff --git a/lib/connection.h b/lib/connection.h
index f2e10488..cba57e3d 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -48,6 +48,7 @@ namespace QMatrixClient
class DownloadFileJob;
class SendToDeviceJob;
class SendMessageJob;
+ class LeaveRoomJob;
/** Create a single-shot connection that triggers on the signal and
* then self-disconnects
@@ -494,14 +495,14 @@ namespace QMatrixClient
SendMessageJob* sendMessage(const QString& roomId,
const RoomEvent& event) const;
+ /** \deprecated Do not use this directly, use Room::leaveRoom() instead */
+ virtual LeaveRoomJob* leaveRoom( Room* room );
+
// Old API that will be abolished any time soon. DO NOT USE.
/** @deprecated Use callApi<PostReceiptJob>() or Room::postReceipt() instead */
virtual PostReceiptJob* postReceipt(Room* room,
RoomEvent* event) const;
- /** @deprecated Use callApi<LeaveRoomJob>() or Room::leaveRoom() instead */
- virtual void leaveRoom( Room* room );
-
signals:
/**
* @deprecated
diff --git a/lib/room.cpp b/lib/room.cpp
index 1931be49..d806183f 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -1633,7 +1633,8 @@ void Room::inviteToRoom(const QString& memberId)
LeaveRoomJob* Room::leaveRoom()
{
- return connection()->callApi<LeaveRoomJob>(id());
+ // FIXME, #63: It should be RoomManager, not Connection
+ return connection()->leaveRoom(this);
}
SetRoomStateWithKeyJob*Room::setMemberState(const QString& memberId, const RoomMemberEvent& event) const