Browse Source

feat(conversation): Send switch-to signaling message when creating from one-to-one

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/14871/head
Joas Schilling 7 months ago
committed by backportbot[bot]
parent
commit
bfc0d6175e
  1. 16
      docs/constants.md
  2. 8
      docs/events.md
  3. 2
      lib/AppInfo/Application.php
  4. 16
      lib/Controller/RoomController.php
  5. 24
      lib/Events/RoomExtendedEvent.php
  6. 1
      lib/Room.php
  7. 1
      lib/Service/RoomService.php
  8. 26
      lib/Signaling/Listener.php
  9. 4
      tests/php/Signaling/ListenerTest.php

16
docs/constants.md

@ -12,13 +12,15 @@
### Object types
| Constant | Can be created | Description | Object ID |
|------------------|----------------|------------------------------------------------------------------|---------------------------------------------------------|
| `file` | No | Conversations about a file in the right sidebar of the files app | File ID |
| `share:password` | No | Video verification to verify the identity of the share recipient | Share token |
| `room` | Yes | Room is a breakout room | Token of the main/parent conversation |
| `phone` | Yes | Room is created when calling a phone number with SIP dial-out | `phone` (not set atm, just used for the default avatar) |
| `sample` | No | Room is a sample conversation | User ID the sample |
| Constant | Can be created | Description | Object ID |
|-------------------------|----------------|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|
| `file` | No | Conversations about a file in the right sidebar of the files app | File ID |
| `share:password` | No | Video verification to verify the identity of the share recipient | Share token |
| `room` | Yes | Room is a breakout room | Token of the main/parent conversation |
| `phone` | Yes | Room is created when calling a phone number with SIP dial-out | `phone` (not set atm, just used for the default avatar) |
| `sample` | No | Room is a sample conversation | User ID the sample |
| `event` | Yes | Event conversation created via the calendar | Start and end unix timestamp of the event concatenated by pound sign: `start#end` |
| `extended_conversation` | Yes | Room is created from another conversation (e.g. adding a participant to 1-1) | Token of previous conversation |
### Read-only states
* `0` Read-write

8
docs/events.md

@ -28,6 +28,14 @@ See the general [Nextcloud Developers - Events](https://docs.nextcloud.com/serve
* After event: `OCA\Talk\Events\RoomModifiedEvent`
* Since: 18.0.0
### Conversation extended
When a new conversation is created from a one-to-one conversation
* Before event: *Not available*
* After event: `OCA\Talk\Events\RoomExtendedEvent`
* Since: 21.1.0
### Lobby modified
* Before event: `OCA\Talk\Events\BeforeLobbyModifiedEvent`

2
lib/AppInfo/Application.php

@ -65,6 +65,7 @@ use OCA\Talk\Events\ReactionAddedEvent;
use OCA\Talk\Events\ReactionRemovedEvent;
use OCA\Talk\Events\RoomCreatedEvent;
use OCA\Talk\Events\RoomDeletedEvent;
use OCA\Talk\Events\RoomExtendedEvent;
use OCA\Talk\Events\RoomModifiedEvent;
use OCA\Talk\Events\RoomSyncedEvent;
use OCA\Talk\Events\SessionLeftRoomEvent;
@ -312,6 +313,7 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(LobbyModifiedEvent::class, SignalingListener::class);
$context->registerEventListener(BeforeRoomSyncedEvent::class, SignalingListener::class);
$context->registerEventListener(RoomSyncedEvent::class, SignalingListener::class);
$context->registerEventListener(RoomExtendedEvent::class, SignalingListener::class);
$context->registerEventListener(ChatMessageSentEvent::class, SignalingListener::class);
$context->registerEventListener(SystemMessageSentEvent::class, SignalingListener::class);

16
lib/Controller/RoomController.php

@ -13,6 +13,7 @@ use OCA\Talk\Capabilities;
use OCA\Talk\Config;
use OCA\Talk\Events\AAttendeeRemovedEvent;
use OCA\Talk\Events\BeforeRoomsFetchEvent;
use OCA\Talk\Events\RoomExtendedEvent;
use OCA\Talk\Exceptions\CannotReachRemoteException;
use OCA\Talk\Exceptions\FederationRestrictionException;
use OCA\Talk\Exceptions\ForbiddenException;
@ -614,6 +615,16 @@ class RoomController extends AEnvironmentAwareOCSController {
/** @var IUser $user */
$user = $this->userManager->get($this->userId);
/** @var ?Room $oldRoom */
$oldRoom = null;
if ($objectType === Room::OBJECT_TYPE_EXTENDED_CONVERSATION && $objectId !== '') {
try {
$oldRoom = $this->manager->getRoomForUserByToken($objectId, $this->userId);
} catch (RoomNotFoundException) {
return new DataResponse(['error' => CreationException::REASON_OBJECT], Http::STATUS_BAD_REQUEST);
}
}
if ($this->talkConfig->isNotAllowedToCreateConversations($user)) {
return new DataResponse(['error' => 'permissions'], Http::STATUS_FORBIDDEN);
}
@ -696,6 +707,11 @@ class RoomController extends AEnvironmentAwareOCSController {
$this->participantService->addInvitationList($room, $invitationList, $user);
}
if ($objectType === Room::OBJECT_TYPE_EXTENDED_CONVERSATION) {
$event = new RoomExtendedEvent($oldRoom, $room);
$this->dispatcher->dispatchTyped($event);
}
if (!$invitationList->hasInvalidInvitations()) {
return new DataResponse($this->formatRoom($room, $this->participantService->getParticipant($room, $this->userId, false)), Http::STATUS_CREATED);
}

24
lib/Events/RoomExtendedEvent.php

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Events;
use OCA\Talk\Room;
class RoomExtendedEvent extends ARoomEvent {
public function __construct(
Room $oldRoom,
protected Room $newRoom,
) {
parent::__construct($oldRoom);
}
public function getNewRoom(): Room {
return $this->newRoom;
}
}

1
lib/Room.php

@ -41,6 +41,7 @@ class Room {
public const OBJECT_TYPE_EMAIL = 'emails';
public const OBJECT_TYPE_EVENT = 'event';
public const OBJECT_TYPE_EXTENDED_CONVERSATION = 'extended_conversation';
public const OBJECT_TYPE_FILE = 'file';
public const OBJECT_TYPE_NOTE_TO_SELF = 'note_to_self';
public const OBJECT_TYPE_PHONE = 'phone';

1
lib/Service/RoomService.php

@ -182,6 +182,7 @@ class RoomService {
'',
Room::OBJECT_TYPE_PHONE,
Room::OBJECT_TYPE_EVENT,
Room::OBJECT_TYPE_EXTENDED_CONVERSATION,
];
if ($allowInternalTypes) {
$objectTypes[] = BreakoutRoom::PARENT_OBJECT_TYPE;

26
lib/Signaling/Listener.php

@ -27,6 +27,7 @@ use OCA\Talk\Events\GuestJoinedRoomEvent;
use OCA\Talk\Events\GuestsCleanedUpEvent;
use OCA\Talk\Events\LobbyModifiedEvent;
use OCA\Talk\Events\ParticipantModifiedEvent;
use OCA\Talk\Events\RoomExtendedEvent;
use OCA\Talk\Events\RoomModifiedEvent;
use OCA\Talk\Events\RoomSyncedEvent;
use OCA\Talk\Events\SessionLeftRoomEvent;
@ -35,10 +36,12 @@ use OCA\Talk\Events\SystemMessagesMultipleSentEvent;
use OCA\Talk\Events\UserJoinedRoomEvent;
use OCA\Talk\Manager;
use OCA\Talk\Model\BreakoutRoom;
use OCA\Talk\Model\Session;
use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCA\Talk\Service\ParticipantService;
use OCA\Talk\Service\SessionService;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Server;
@ -71,6 +74,7 @@ class Listener implements IEventListener {
protected Manager $manager,
protected ParticipantService $participantService,
protected SessionService $sessionService,
protected ITimeFactory $timeFactory,
) {
}
@ -125,6 +129,7 @@ class Listener implements IEventListener {
match (get_class($event)) {
RoomModifiedEvent::class,
LobbyModifiedEvent::class => $this->notifyRoomModified($event),
RoomExtendedEvent::class => $this->notifyRoomExtended($event),
BeforeRoomSyncedEvent::class => $this->pauseRoomModifiedListener(),
RoomSyncedEvent::class => $this->notifyRoomSynced($event),
BeforeRoomDeletedEvent::class => $this->notifyBeforeRoomDeleted($event),
@ -388,6 +393,27 @@ class Listener implements IEventListener {
}
}
protected function notifyRoomExtended(RoomExtendedEvent $event): void {
$room = $event->getRoom();
if ($room->getCallFlag() === Participant::FLAG_DISCONNECTED) {
return;
}
$timeout = $this->timeFactory->getTime() - Session::SESSION_TIMEOUT;
$participants = $this->participantService->getParticipantsInCall($room, $timeout);
$sessionIds = [];
foreach ($participants as $participant) {
if ($participant->getSession() instanceof Session) {
$sessionIds[] = $participant->getSession()->getSessionId();
}
}
$newRoom = $event->getNewRoom();
$this->externalSignaling->switchToRoom($room, $newRoom->getToken(), $sessionIds);
}
/**
* @param Participant $targetParticipant
* @param Participant[] $participants

4
tests/php/Signaling/ListenerTest.php

@ -25,6 +25,7 @@ use OCA\Talk\Signaling\BackendNotifier;
use OCA\Talk\Signaling\Listener;
use OCA\Talk\Signaling\Messages;
use OCA\Talk\Webinary;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Comments\IComment;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
@ -37,6 +38,7 @@ class ListenerTest extends TestCase {
protected Manager&MockObject $manager;
protected ParticipantService&MockObject $participantService;
protected SessionService&MockObject $sessionService;
protected ITimeFactory&MockObject $timeFactory;
protected ?Listener $listener;
public function setUp(): void {
@ -46,6 +48,7 @@ class ListenerTest extends TestCase {
$this->manager = $this->createMock(Manager::class);
$this->participantService = $this->createMock(ParticipantService::class);
$this->sessionService = $this->createMock(SessionService::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->listener = new Listener(
$this->createMock(Config::class),
@ -54,6 +57,7 @@ class ListenerTest extends TestCase {
$this->manager,
$this->participantService,
$this->sessionService,
$this->timeFactory,
);
}

Loading…
Cancel
Save