diff --git a/src/app/controller.cpp b/src/app/controller.cpp index 9d219afd6..6feeb5c64 100644 --- a/src/app/controller.cpp +++ b/src/app/controller.cpp @@ -32,6 +32,7 @@ #include "neochatroom.h" #include "notificationsmanager.h" #include "proxycontroller.h" +#include "roommanager.h" #if defined(Q_OS_WIN) || defined(Q_OS_MAC) #include "trayicon.h" @@ -230,6 +231,7 @@ void Controller::initConnection(NeoChatConnection *connection) m_notificationsManager.handleNotifications(connection); }); connect(this, &Controller::globalUrlPreviewDefaultChanged, connection, &NeoChatConnection::globalUrlPreviewEnabledChanged); + connect(connection, &NeoChatConnection::roomAboutToBeLeft, &RoomManager::instance(), &RoomManager::roomLeft); Q_EMIT connectionAdded(connection); } diff --git a/src/app/notificationsmanager.cpp b/src/app/notificationsmanager.cpp index 505454ce3..06f3ea35f 100644 --- a/src/app/notificationsmanager.cpp +++ b/src/app/notificationsmanager.cpp @@ -276,7 +276,7 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *rawRoom) if (inAnyOfOurRooms) { doPostInviteNotification(room); } else { - room->leaveRoom(); + room->forget(); } } }); @@ -330,14 +330,14 @@ void NotificationsManager::doPostInviteNotification(QPointer room) if (!room) { return; } - RoomManager::instance().leaveRoom(room); + room->forget(); notification->close(); }); connect(rejectAndIgnoreAction, &KNotificationAction::activated, this, [room, notification]() { if (!room) { return; } - RoomManager::instance().leaveRoom(room); + room->forget(); room->connection()->addToIgnoredUsers(room->invitingUserId()); notification->close(); }); diff --git a/src/app/qml/ConfirmLeaveDialog.qml b/src/app/qml/ConfirmLeaveDialog.qml index 1bf76d498..0cb452027 100644 --- a/src/app/qml/ConfirmLeaveDialog.qml +++ b/src/app/qml/ConfirmLeaveDialog.qml @@ -28,7 +28,7 @@ Kirigami.PromptDialog { text: i18nc("@action:button", "Leave Room") QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole icon.name: "arrow-left-symbolic" - onClicked: RoomManager.leaveRoom(root.room) + onClicked: root.room.forget(); } } } diff --git a/src/app/qml/InvitationView.qml b/src/app/qml/InvitationView.qml index e2f5e31ad..c2ff66d7a 100644 --- a/src/app/qml/InvitationView.qml +++ b/src/app/qml/InvitationView.qml @@ -108,7 +108,7 @@ ColumnLayout { icon.name: "dialog-cancel-symbolic" text: i18nc("@action:button Reject this invite", "Reject Invite") - onClicked: RoomManager.leaveRoom(root.currentRoom) + onClicked: root.currentRoom.forget() } } @@ -123,7 +123,7 @@ ColumnLayout { text: i18nc("@action:button Block the user", "Block %1", root.invitingMember.displayName) onClicked: { - RoomManager.leaveRoom(root.currentRoom); + root.currentRoom.forget() root.currentRoom.connection.addToIgnoredUsers(root.currentRoom.invitingUserId); } } diff --git a/src/app/qml/RoomPage.qml b/src/app/qml/RoomPage.qml index 166dd16cd..e27718ec2 100644 --- a/src/app/qml/RoomPage.qml +++ b/src/app/qml/RoomPage.qml @@ -139,8 +139,6 @@ Kirigami.Page { anchors.fill: parent sourceComponent: SpaceHomePage { room: root.currentRoom - - onRequestLeaveRoom: room => RoomManager.leaveRoom(room); } } diff --git a/src/app/roommanager.cpp b/src/app/roommanager.cpp index 18b04a5f6..7655002a2 100644 --- a/src/app/roommanager.cpp +++ b/src/app/roommanager.cpp @@ -448,29 +448,27 @@ void RoomManager::knockRoom(NeoChatConnection *account, const QString &roomAlias Qt::SingleShotConnection); } +void RoomManager::roomLeft(const QString &id) +{ + if (id.isEmpty()) { + return; + } + + if (m_currentRoom && m_currentRoom->id() == id) { + setCurrentRoom({}); + } + + if (m_currentSpaceId == id) { + setCurrentSpace({}); + } +} + bool RoomManager::visitNonMatrix(const QUrl &url) { UrlHelper().openUrl(url); return true; } -void RoomManager::leaveRoom(NeoChatRoom *room) -{ - if (!room) { - return; - } - - if (m_currentRoom && m_currentRoom->id() == room->id()) { - setCurrentRoom({}); - } - - if (m_currentSpaceId == room->id()) { - setCurrentSpace({}); - } - - room->forget(); -} - ChatDocumentHandler *RoomManager::chatDocumentHandler() const { return m_chatDocumentHandler; diff --git a/src/app/roommanager.h b/src/app/roommanager.h index 8f26fad71..051e5d976 100644 --- a/src/app/roommanager.h +++ b/src/app/roommanager.h @@ -195,11 +195,6 @@ public: */ Q_INVOKABLE void loadInitialRoom(); - /** - * @brief Leave the room and close it if it is open. - */ - Q_INVOKABLE void leaveRoom(NeoChatRoom *room); - /** * @brief Knock a room. * @@ -208,6 +203,13 @@ public: */ void knockRoom(NeoChatConnection *account, const QString &roomAliasOrId, const QString &reason, const QStringList &viaServers); + /** + * @brief Cleanup after the given room is left. + * + * This ensures that the current room and space are not set to the left room. + */ + void roomLeft(const QString &id); + /** * @brief Show a media item maximized. * diff --git a/src/libneochat/models/actionsmodel.cpp b/src/libneochat/models/actionsmodel.cpp index 0ca72a7f8..9f07ed4a6 100644 --- a/src/libneochat/models/actionsmodel.cpp +++ b/src/libneochat/models/actionsmodel.cpp @@ -29,7 +29,7 @@ QStringList rainbowColors{"#ff2b00"_L1, "#ff5500"_L1, "#ff8000"_L1, "#ffaa00"_L1 auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *) { if (text.isEmpty()) { Q_EMIT room->showMessage(MessageType::Information, i18n("Leaving this room.")); - room->connection()->leaveRoom(room); + room->forget(); } else { QRegularExpression roomRegex(uR"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"_s); auto regexMatch = roomRegex.match(text); @@ -38,13 +38,13 @@ auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache * i18nc("'' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text)); return QString(); } - auto leaving = room->connection()->room(text); + auto leaving = dynamic_cast(room->connection()->room(text)); if (!leaving) { - leaving = room->connection()->roomByAlias(text); + leaving = dynamic_cast(room->connection()->roomByAlias(text)); } if (leaving) { Q_EMIT room->showMessage(MessageType::Information, i18nc("Leaving room .", "Leaving room %1.", text)); - room->connection()->leaveRoom(leaving); + leaving->forget(); } else { Q_EMIT room->showMessage(MessageType::Information, i18nc("Room not found", "Room %1 not found.", text)); } diff --git a/src/libneochat/neochatconnection.cpp b/src/libneochat/neochatconnection.cpp index 9d9c55cf2..b4ed79d55 100644 --- a/src/libneochat/neochatconnection.cpp +++ b/src/libneochat/neochatconnection.cpp @@ -9,6 +9,7 @@ #include "neochatroom.h" #include "spacehierarchycache.h" +#include #include #include #include @@ -386,6 +387,13 @@ void NeoChatConnection::createSpace(const QString &name, const QString &topic, c }); } +Quotient::ForgetRoomJob *NeoChatConnection::forgetRoom(const QString &id) +{ + Q_EMIT roomAboutToBeLeft(id); + + return Connection::forgetRoom(id); +} + bool NeoChatConnection::directChatExists(Quotient::User *user) { return directChats().contains(user); diff --git a/src/libneochat/neochatconnection.h b/src/libneochat/neochatconnection.h index 96a50908f..84b22bbf5 100644 --- a/src/libneochat/neochatconnection.h +++ b/src/libneochat/neochatconnection.h @@ -150,6 +150,14 @@ public: */ Q_INVOKABLE void createSpace(const QString &name, const QString &topic, const QString &parent = {}, bool setChildParent = false); + /** + * @brief Send /forget to the server and delete room locally. + * + * @note This wraps around the Quotient::Connection::forgetRoom() to allow + * roomAboutToBeLeft() to be emitted. + */ + Quotient::ForgetRoomJob *forgetRoom(const QString &id); + /** * @brief Whether a direct chat with the user exists. */ @@ -224,6 +232,11 @@ Q_SIGNALS: */ void errorOccured(const QString &error); + /** + * @brief The given room ID is about to be forgotten. + */ + void roomAboutToBeLeft(const QString &id); + private: static bool m_globalUrlPreviewDefault; static PushRuleAction::Action m_defaultAction; diff --git a/src/libneochat/neochatroom.cpp b/src/libneochat/neochatroom.cpp index b86ea65ef..c9de1d8f5 100644 --- a/src/libneochat/neochatroom.cpp +++ b/src/libneochat/neochatroom.cpp @@ -305,8 +305,9 @@ void NeoChatRoom::forget() roomIds += predecessor->id(); } + const auto neochatConnection = dynamic_cast(connection()); for (const auto &id : roomIds) { - connection()->forgetRoom(id); + neochatConnection->forgetRoom(id); } } diff --git a/src/rooms/SpaceListContextMenu.qml b/src/rooms/SpaceListContextMenu.qml index 6b879ea16..b5ea3d4c0 100644 --- a/src/rooms/SpaceListContextMenu.qml +++ b/src/rooms/SpaceListContextMenu.qml @@ -72,6 +72,6 @@ KirigamiComponents.ConvergentContextMenu { QQC2.Action { text: i18nc("'Space' is a matrix space", "Leave Space") icon.name: "go-previous" - onTriggered: RoomManager.leaveRoom(room) + onTriggered: root.room.forget() } } diff --git a/src/spaces/SpaceHomePage.qml b/src/spaces/SpaceHomePage.qml index c7d90312a..176361576 100644 --- a/src/spaces/SpaceHomePage.qml +++ b/src/spaces/SpaceHomePage.qml @@ -19,11 +19,6 @@ ColumnLayout { */ required property NeoChatRoom room - /** - * @brief Request to leave the given room. - */ - signal requestLeaveRoom(NeoChatRoom room) - anchors.fill: parent spacing: 0 @@ -102,7 +97,7 @@ ColumnLayout { QQC2.Button { text: i18nc("@action:button", "Leave this space") icon.name: "go-previous" - onClicked: root.requestLeaveRoom(root.room) + onClicked: root.room.forget() } Item { Layout.fillWidth: true