diff --git a/lib/Chat/SystemMessage/Listener.php b/lib/Chat/SystemMessage/Listener.php index b06aa26aaac..c9e591dae24 100644 --- a/lib/Chat/SystemMessage/Listener.php +++ b/lib/Chat/SystemMessage/Listener.php @@ -150,6 +150,10 @@ public static function register(IEventDispatcher $dispatcher): void { $dispatcher->addListener(Room::EVENT_AFTER_TYPE_SET, static function (ModifyRoomEvent $event) { $room = $event->getRoom(); + if ($event->getOldValue() === Room::ONE_TO_ONE_CALL) { + return; + } + if ($event->getNewValue() === Room::PUBLIC_CALL) { /** @var self $listener */ $listener = \OC::$server->query(self::class); diff --git a/lib/Listener/UserDeletedListener.php b/lib/Listener/UserDeletedListener.php index c12a3fd9b10..47ad1b723c4 100644 --- a/lib/Listener/UserDeletedListener.php +++ b/lib/Listener/UserDeletedListener.php @@ -52,7 +52,6 @@ public function handle(Event $event): void { $user = $event->getUser(); $rooms = $this->manager->getRoomsForUser($user->getUID()); - foreach ($rooms as $room) { if ($this->participantService->getNumberOfUsers($room) === 1) { $room->deleteRoom(); @@ -60,5 +59,13 @@ public function handle(Event $event): void { $this->participantService->removeUser($room, $user, Room::PARTICIPANT_REMOVED); } } + + $leftRooms = $this->manager->getLeftOneToOneRoomsForUser($user->getUID()); + foreach ($leftRooms as $room) { + // We are changing the room type and name so a potential follow up + // user with the same user-id can not reopen the one-to-one conversation. + $room->setType(Room::GROUP_CALL, true); + $room->setName($user->getDisplayName(), ''); + } } } diff --git a/lib/Manager.php b/lib/Manager.php index a7c529c3f34..8edaeda4cb1 100644 --- a/lib/Manager.php +++ b/lib/Manager.php @@ -342,6 +342,34 @@ public function getRoomsForUser(string $userId, bool $includeLastMessage = false return $rooms; } + /** + * @param string $userId + * @return Room[] + */ + public function getLeftOneToOneRoomsForUser(string $userId): array { + $query = $this->db->getQueryBuilder(); + $helper = new SelectHelper(); + $helper->selectRoomsTable($query); + $query->from('talk_rooms', 'r') + ->where($query->expr()->eq('r.type', $query->createNamedParameter(Room::ONE_TO_ONE_CALL))) + ->andWhere($query->expr()->like('r.name', $query->createNamedParameter('%' . $this->db->escapeLikeParameter(json_encode($userId)) . '%'))); + + $result = $query->execute(); + $rooms = []; + while ($row = $result->fetch()) { + if ($row['token'] === null) { + // FIXME Temporary solution for the Talk6 release + continue; + } + + $room = $this->createRoomObject($row); + $rooms[] = $room; + } + $result->closeCursor(); + + return $rooms; + } + /** * @param string $userId * @return string[] diff --git a/lib/Room.php b/lib/Room.php index 4721ff41aee..8084a9f1ace 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -754,12 +754,12 @@ public function setAssignedSignalingServer(?int $signalingServer): bool { * @param int $newType Currently it is only allowed to change between `self::GROUP_CALL` and `self::PUBLIC_CALL` * @return bool True when the change was valid, false otherwise */ - public function setType(int $newType): bool { + public function setType(int $newType, bool $allowSwitchingOneToOne = false): bool { if ($newType === $this->getType()) { return true; } - if ($this->getType() === self::ONE_TO_ONE_CALL) { + if (!$allowSwitchingOneToOne && $this->getType() === self::ONE_TO_ONE_CALL) { return false; } diff --git a/tests/integration/features/conversation/delete-user.feature b/tests/integration/features/conversation/delete-user.feature index b20dc8a2bc4..c211a25a59d 100644 --- a/tests/integration/features/conversation/delete-user.feature +++ b/tests/integration/features/conversation/delete-user.feature @@ -16,6 +16,23 @@ Feature: conversation/delete-user Then user "participant1" sees the following messages in room "one-to-one room" with 200 | room | actorType | actorId | actorDisplayName | message | messageParameters | | one-to-one room | deleted_users | deleted_users | | Message 1 | [] | + Then user "participant1" is participant of the following rooms (v4) + | name | type | + | participant2-displayname | 2 | + + Scenario: delete user who left a one-to-one room + Given user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + And user "participant2" sends message "Message 1" to room "one-to-one room" with 201 + When user "participant2" leaves room "one-to-one room" with 200 (v4) + When user "participant2" is deleted + Then user "participant1" sees the following messages in room "one-to-one room" with 200 + | room | actorType | actorId | actorDisplayName | message | messageParameters | + | one-to-one room | deleted_users | deleted_users | | Message 1 | [] | + Then user "participant1" is participant of the following rooms (v4) + | name | type | + | participant2-displayname | 2 | Scenario: delete user who is in a group room Given user "participant1" creates room "group room"