From 26b1d626885e712f55ce25046531f894a77f0c0c Mon Sep 17 00:00:00 2001 From: DorraJaouad Date: Sun, 27 Oct 2024 14:10:57 +0100 Subject: [PATCH 1/2] wip webrtc Signed-off-by: DorraJaouad --- .../models/LocalCallParticipantModel.js | 19 +++++++++++++++++++ src/utils/webrtc/simplewebrtc/simplewebrtc.js | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/utils/webrtc/models/LocalCallParticipantModel.js b/src/utils/webrtc/models/LocalCallParticipantModel.js index bc6e0a22742..3901cdc533c 100644 --- a/src/utils/webrtc/models/LocalCallParticipantModel.js +++ b/src/utils/webrtc/models/LocalCallParticipantModel.js @@ -23,9 +23,11 @@ export default function LocalCallParticipantModel() { guestName: null, peerNeeded: false, connectionState: null, + forcedCallViewMode: null, }) this._handleForcedMuteBound = this._handleForcedMute.bind(this) + this._handleForcedCallViewModeBound = this._handleForcedCallViewMode.bind(this) this._handleExtendedIceConnectionStateChangeBound = this._handleExtendedIceConnectionStateChange.bind(this) } @@ -49,6 +51,7 @@ LocalCallParticipantModel.prototype = { setWebRtc(webRtc) { if (this._webRtc) { this._webRtc.off('forcedMute', this._handleForcedMuteBound) + this._webRtc.off('forcedCallViewMode', this._handleForcedCallViewModeBound) this._unwatchDisplayNameChange() } @@ -56,8 +59,10 @@ LocalCallParticipantModel.prototype = { this.set('peerId', this._webRtc.connection.getSessionId()) this.set('guestName', null) + this.set('forcedCallViewMode', null) this._webRtc.on('forcedMute', this._handleForcedMuteBound) + this._webRtc.on('forcedCallViewMode', this._handleForcedCallViewModeBound) this._unwatchDisplayNameChange = store.watch(state => state.actorStore.displayName, this.setGuestName.bind(this)) }, @@ -120,6 +125,10 @@ LocalCallParticipantModel.prototype = { this._trigger('forcedMute') }, + _handleForcedCallViewMode(forcedCallViewMode) { + this.set('forcedCallViewMode', forcedCallViewMode) + }, + _handleExtendedIceConnectionStateChange(extendedIceConnectionState) { switch (extendedIceConnectionState) { case 'new': @@ -162,6 +171,16 @@ LocalCallParticipantModel.prototype = { }) }, + forceCallViewMode(callViewMode) { + if (!this._webRtc) { + throw new Error('WebRtc not initialized yet') + } + + this._webRtc.sendToAll('control', { + action: 'forceCallViewMode', + callViewMode, + }) + }, } EmitterMixin.apply(LocalCallParticipantModel.prototype) diff --git a/src/utils/webrtc/simplewebrtc/simplewebrtc.js b/src/utils/webrtc/simplewebrtc/simplewebrtc.js index c84ed272458..0357ce7acde 100644 --- a/src/utils/webrtc/simplewebrtc/simplewebrtc.js +++ b/src/utils/webrtc/simplewebrtc/simplewebrtc.js @@ -116,6 +116,8 @@ export default function SimpleWebRTC(opts) { } else { self.emit('mute', { id: message.payload.peerId }) } + } else if (message.payload.action === 'forceCallViewMode') { + self.emit('forcedCallViewMode', message.payload.callViewMode) } } else if (message.type === 'nickChanged') { // "nickChanged" can be received from a participant without a Peer From fce900a8e6de6159a7b4bcd00dc21e3d88b022a6 Mon Sep 17 00:00:00 2001 From: DorraJaouad Date: Tue, 29 Oct 2024 00:03:05 +0100 Subject: [PATCH 2/2] feat(forceCallView): add the UI Signed-off-by: DorraJaouad --- src/components/CallView/CallView.vue | 18 +++ .../TopBar/CallModerationDialog.vue | 104 ++++++++++++++++++ src/components/TopBar/TopBarMenu.vue | 39 ++++++- 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 src/components/TopBar/CallModerationDialog.vue diff --git a/src/components/CallView/CallView.vue b/src/components/CallView/CallView.vue index feb4b1dfb34..09a3c674cd1 100644 --- a/src/components/CallView/CallView.vue +++ b/src/components/CallView/CallView.vue @@ -265,7 +265,19 @@ export default { return this.callViewStore.isViewerOverlay }, + forcedCallViewMode() { + return this.localCallParticipantModel.attributes.forcedCallViewMode + }, + isGrid() { + if (this.forcedCallViewMode === 'grid' && !this.$store.getters.isModerator) { + return true + } + + if (this.forcedCallViewMode === 'speaker' && !this.$store.getters.isModerator) { + return false + } + return this.callViewStore.isGrid && !this.isSidebar }, @@ -487,6 +499,7 @@ export default { mounted() { this.debounceFetchPeers = debounce(this.fetchPeers, 1500) EventBus.on('refresh-peer-list', this.debounceFetchPeers) + EventBus.on('force-call-view-mode', this.forceCallViewMode) callParticipantCollection.on('remove', this._lowerHandWhenParticipantLeaves) @@ -498,6 +511,7 @@ export default { this.debounceFetchPeers.clear?.() this.callViewStore.setIsEmptyCallView(true) EventBus.off('refresh-peer-list', this.debounceFetchPeers) + EventBus.off('force-call-view-mode', this.forceCallViewMode) callParticipantCollection.off('remove', this._lowerHandWhenParticipantLeaves) @@ -797,6 +811,10 @@ export default { } }, + forceCallViewMode(mode) { + this.localCallParticipantModel.forceCallViewMode(mode) + }, + }, } diff --git a/src/components/TopBar/CallModerationDialog.vue b/src/components/TopBar/CallModerationDialog.vue new file mode 100644 index 00000000000..39e5a7bed19 --- /dev/null +++ b/src/components/TopBar/CallModerationDialog.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/components/TopBar/TopBarMenu.vue b/src/components/TopBar/TopBarMenu.vue index ebbc9ea67fa..34526f206ec 100644 --- a/src/components/TopBar/TopBarMenu.vue +++ b/src/components/TopBar/TopBarMenu.vue @@ -62,6 +62,7 @@ @@ -148,10 +157,13 @@ {{ t('spreed', 'Download attendance list') }} + +