diff --git a/docs/standalone-signaling-api-v1.md b/docs/standalone-signaling-api-v1.md index 8cfffc49b3f..f98e841691a 100644 --- a/docs/standalone-signaling-api-v1.md +++ b/docs/standalone-signaling-api-v1.md @@ -549,7 +549,9 @@ Message format (Server -> Client, participants change): If a participant has the `inCall` flag set, he has joined the call of the room and a WebRTC peerconnection should be established if the local client is also -in the call. +in the call. In that case the participant information will contain properties +for both the signaling session id (`sessionId`) and the Nextcloud session id +(`nextcloudSessionId`). ## Room messages diff --git a/lib/Signaling/BackendNotifier.php b/lib/Signaling/BackendNotifier.php index f850a22f697..1d5be017f7d 100644 --- a/lib/Signaling/BackendNotifier.php +++ b/lib/Signaling/BackendNotifier.php @@ -334,6 +334,7 @@ public function roomInCallChanged(Room $room, int $flags, array $sessionIds): vo $data['inCall'] = $session->getInCall(); $data['lastPing'] = $session->getLastPing(); $data['sessionId'] = $session->getSessionId(); + $data['nextcloudSessionId'] = $session->getSessionId(); if ($session->getInCall() !== Participant::FLAG_DISCONNECTED) { $users[] = $data; diff --git a/src/components/CallView/CallView.vue b/src/components/CallView/CallView.vue index 96fe21414c0..03af3a2557d 100644 --- a/src/components/CallView/CallView.vue +++ b/src/components/CallView/CallView.vue @@ -377,9 +377,13 @@ export default { }, mounted() { EventBus.$on('refreshPeerList', this.debounceFetchPeers) + + callParticipantCollection.on('remove', this._lowerHandWhenParticipantLeaves) }, beforeDestroy() { EventBus.$off('refreshPeerList', this.debounceFetchPeers) + + callParticipantCollection.off('remove', this._lowerHandWhenParticipantLeaves) }, methods: { /** @@ -410,8 +414,6 @@ export default { this.raisedHandUnwatchers[removedModelId]() // Not reactive, but not a problem delete this.raisedHandUnwatchers[removedModelId] - // FIXME: when using HPB sessionId doesn't match - this.$store.dispatch('setParticipantHandRaised', { sessionId: removedModelId, raisedHand: { state: false } }) const index = this.speakers.findIndex(speaker => speaker.id === removedModelId) this.speakers.splice(index, 1) @@ -501,12 +503,18 @@ export default { // update in callViewStore this.$store.dispatch('setParticipantHandRaised', { - // FIXME: this is a bit hacky to fix the HPB session mismatch - sessionId: raisedHand?.sessionId ? raisedHand?.sessionId : callParticipantModel.attributes.peerId, + sessionId: callParticipantModel.attributes.nextcloudSessionId, raisedHand: raisedHand, }) }, + _lowerHandWhenParticipantLeaves(callParticipantCollection, callParticipantModel) { + this.$store.dispatch('setParticipantHandRaised', { + sessionId: callParticipantModel.attributes.nextcloudSessionId, + raisedHand: false, + }) + }, + _setScreenAvailable(id, screen) { if (screen) { this.screens.unshift(id) diff --git a/src/components/CallView/shared/LocalMediaControls.vue b/src/components/CallView/shared/LocalMediaControls.vue index ce115030f5a..5bef8676f8c 100644 --- a/src/components/CallView/shared/LocalMediaControls.vue +++ b/src/components/CallView/shared/LocalMediaControls.vue @@ -582,8 +582,7 @@ export default { this.$store.dispatch( 'setParticipantHandRaised', { - // FIXME: when using HPB these don't match - sessionId: this.localCallParticipantModel.attributes.peerId, + sessionId: this.$store.getters.getSessionId(), raisedHand: this.model.attributes.raisedHand, } ) diff --git a/src/utils/webrtc/models/CallParticipantModel.js b/src/utils/webrtc/models/CallParticipantModel.js index 159bc5aa3c0..dc4028b9611 100644 --- a/src/utils/webrtc/models/CallParticipantModel.js +++ b/src/utils/webrtc/models/CallParticipantModel.js @@ -37,6 +37,7 @@ export default function CallParticipantModel(options) { this.attributes = { peerId: null, + nextcloudSessionId: null, peer: null, screenPeer: null, // "undefined" is used for values not known yet; "null" or "false" @@ -348,4 +349,8 @@ CallParticipantModel.prototype = { this.set('userId', userId) }, + setNextcloudSessionId: function(nextcloudSessionId) { + this.set('nextcloudSessionId', nextcloudSessionId) + }, + } diff --git a/src/utils/webrtc/models/LocalMediaModel.js b/src/utils/webrtc/models/LocalMediaModel.js index 4ddb185d661..b17b579a2e4 100644 --- a/src/utils/webrtc/models/LocalMediaModel.js +++ b/src/utils/webrtc/models/LocalMediaModel.js @@ -444,7 +444,6 @@ LocalMediaModel.prototype = { const raisedHand = { state: raised, timestamp: Date.now(), - sessionId: this._webRtc.connection?.nextcloudSessionId, } this._webRtc.sendToAll('raiseHand', raisedHand) diff --git a/src/utils/webrtc/webrtc.js b/src/utils/webrtc/webrtc.js index 52c117bcd41..fdd91c3e385 100644 --- a/src/utils/webrtc/webrtc.js +++ b/src/utils/webrtc/webrtc.js @@ -229,6 +229,12 @@ function usersChanged(signaling, newUsers, disconnectedSessionIds) { // TODO(fancycode): Adjust property name of internal PHP backend to be all lowercase. const userId = user.userId || user.userid || null + // When the external signaling server is used the Nextcloud session id + // will be provided in its own property. When the internal signaling + // server is used the Nextcloud session id and the signaling session id + // are the same and thus set from the signaling session id. + const nextcloudSessionId = user.nextcloudSessionId || user.nextcloudsessionid || sessionId + let callParticipantModel = callParticipantCollection.get(sessionId) if (!callParticipantModel) { callParticipantModel = callParticipantCollection.add({ @@ -237,6 +243,7 @@ function usersChanged(signaling, newUsers, disconnectedSessionIds) { }) } callParticipantModel.setUserId(userId) + callParticipantModel.setNextcloudSessionId(nextcloudSessionId) if (user.internal) { callParticipantModel.set('internal', true) } diff --git a/tests/php/Signaling/BackendNotifierTest.php b/tests/php/Signaling/BackendNotifierTest.php index 57226b74312..39dabc43d44 100644 --- a/tests/php/Signaling/BackendNotifierTest.php +++ b/tests/php/Signaling/BackendNotifierTest.php @@ -513,6 +513,7 @@ public function testRoomInCallChanged() { 'inCall' => 7, 'lastPing' => 0, 'sessionId' => $userSession, + 'nextcloudSessionId' => $userSession, 'participantType' => Participant::USER, 'userId' => $this->userId, ], @@ -522,6 +523,7 @@ public function testRoomInCallChanged() { 'inCall' => 7, 'lastPing' => 0, 'sessionId' => $userSession, + 'nextcloudSessionId' => $userSession, 'participantType' => Participant::USER, 'userId' => $this->userId, ], @@ -545,6 +547,7 @@ public function testRoomInCallChanged() { 'inCall' => 1, 'lastPing' => 0, 'sessionId' => $guestSession, + 'nextcloudSessionId' => $guestSession, 'participantType' => Participant::GUEST, ], ], @@ -553,6 +556,7 @@ public function testRoomInCallChanged() { 'inCall' => 7, 'lastPing' => 0, 'sessionId' => $userSession, + 'nextcloudSessionId' => $userSession, 'participantType' => Participant::USER, 'userId' => $this->userId, ], @@ -560,6 +564,7 @@ public function testRoomInCallChanged() { 'inCall' => 1, 'lastPing' => 0, 'sessionId' => $guestSession, + 'nextcloudSessionId' => $guestSession, 'participantType' => Participant::GUEST, ], ], @@ -578,6 +583,7 @@ public function testRoomInCallChanged() { 'inCall' => 0, 'lastPing' => 0, 'sessionId' => $userSession, + 'nextcloudSessionId' => $userSession, 'participantType' => Participant::USER, 'userId' => $this->userId, ], @@ -587,6 +593,7 @@ public function testRoomInCallChanged() { 'inCall' => 1, 'lastPing' => 0, 'sessionId' => $guestSession, + 'nextcloudSessionId' => $guestSession, 'participantType' => Participant::GUEST, ], ],