From 190c0c00c1d5a7c6cdfb0801ebe3d9373dda05a0 Mon Sep 17 00:00:00 2001 From: Tina Harter Date: Tue, 14 May 2024 13:39:01 -0500 Subject: [PATCH 1/3] use capabilities feature for lobby --- Project/src/MakeCall/CallCard.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Project/src/MakeCall/CallCard.js b/Project/src/MakeCall/CallCard.js index 854f50a..4816fbe 100644 --- a/Project/src/MakeCall/CallCard.js +++ b/Project/src/MakeCall/CallCard.js @@ -63,6 +63,7 @@ export default class CallCard extends React.Component { canRaiseHands: this.capabilities.raiseHand?.isPresent || this.capabilities.raiseHand?.reason === 'FeatureNotSupported', canSpotlight: this.capabilities.spotlightParticipant?.isPresent || this.capabilities.spotlightParticipant?.reason === 'FeatureNotSupported', canReact: this.capabilities.useReactions?.isPresent || this.capabilities.useReactions?.reason === 'FeatureNotSupported', + canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported', videoOn: this.call.isLocalVideoStarted, screenSharingOn: this.call.isScreenSharingOn, micMuted: this.call.isMuted, @@ -216,10 +217,12 @@ export default class CallCard extends React.Component { if (this.call.state === 'LocalHold' || this.call.state === 'RemoteHold') { this.setState({ canRaiseHands: false }); this.setState({ canSpotlight: false }); + this.setState({ canManageLobby: false }); } if (this.call.state === 'Connected') { this.setState({ canRaiseHands: this.capabilities.raiseHand?.isPresent || this.capabilities.raiseHand?.reason === 'FeatureNotSupported' }); this.setState({ canSpotlight: this.capabilities.spotlightParticipant?.isPresent || this.capabilities.spotlightParticipant?.reason === 'FeatureNotSupported' }); + this.setState({ canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported' }); } } callStateChanged(); @@ -591,6 +594,10 @@ export default class CallCard extends React.Component { (value.isPresent) ? this.setState({ canReact: true }) : this.setState({ canReact: false }); continue; } + if(key === 'manageLobby' && value.reason != 'FeatureNotSupported') { + (value.isPresent) ? this.setState({ canManageLobby: true }) : this.setState({ canManageLobby: false }); + continue; + } } this.capabilities = this.capabilitiesFeature.capabilities; } From 3ee63296bbfd5eb170fcb49217166b87551ed079 Mon Sep 17 00:00:00 2001 From: Tina Harter Date: Thu, 16 May 2024 02:05:13 -0500 Subject: [PATCH 2/3] Hide lobby action buttons when the manageLobby capabilities is false --- Project/src/App.css | 10 +- Project/src/MakeCall/CallCard.js | 7 -- Project/src/MakeCall/Lobby.js | 102 +++++++++++------- Project/src/MakeCall/RemoteParticipantCard.js | 24 ++++- 4 files changed, 92 insertions(+), 51 deletions(-) diff --git a/Project/src/App.css b/Project/src/App.css index a71958a..2dcbd3f 100644 --- a/Project/src/App.css +++ b/Project/src/App.css @@ -1173,10 +1173,12 @@ div.volumeVisualizer::before { margin-top: 2px; } -.lobby-action a{ - display: inline-block; - color: #75b6e7; - text-decoration: none; +.red-link { + color: red; +} + +.green-link { + color: green; } .participantMenu, .participantMenu:hover{ diff --git a/Project/src/MakeCall/CallCard.js b/Project/src/MakeCall/CallCard.js index 4816fbe..854f50a 100644 --- a/Project/src/MakeCall/CallCard.js +++ b/Project/src/MakeCall/CallCard.js @@ -63,7 +63,6 @@ export default class CallCard extends React.Component { canRaiseHands: this.capabilities.raiseHand?.isPresent || this.capabilities.raiseHand?.reason === 'FeatureNotSupported', canSpotlight: this.capabilities.spotlightParticipant?.isPresent || this.capabilities.spotlightParticipant?.reason === 'FeatureNotSupported', canReact: this.capabilities.useReactions?.isPresent || this.capabilities.useReactions?.reason === 'FeatureNotSupported', - canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported', videoOn: this.call.isLocalVideoStarted, screenSharingOn: this.call.isScreenSharingOn, micMuted: this.call.isMuted, @@ -217,12 +216,10 @@ export default class CallCard extends React.Component { if (this.call.state === 'LocalHold' || this.call.state === 'RemoteHold') { this.setState({ canRaiseHands: false }); this.setState({ canSpotlight: false }); - this.setState({ canManageLobby: false }); } if (this.call.state === 'Connected') { this.setState({ canRaiseHands: this.capabilities.raiseHand?.isPresent || this.capabilities.raiseHand?.reason === 'FeatureNotSupported' }); this.setState({ canSpotlight: this.capabilities.spotlightParticipant?.isPresent || this.capabilities.spotlightParticipant?.reason === 'FeatureNotSupported' }); - this.setState({ canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported' }); } } callStateChanged(); @@ -594,10 +591,6 @@ export default class CallCard extends React.Component { (value.isPresent) ? this.setState({ canReact: true }) : this.setState({ canReact: false }); continue; } - if(key === 'manageLobby' && value.reason != 'FeatureNotSupported') { - (value.isPresent) ? this.setState({ canManageLobby: true }) : this.setState({ canManageLobby: false }); - continue; - } } this.capabilities = this.capabilitiesFeature.capabilities; } diff --git a/Project/src/MakeCall/Lobby.js b/Project/src/MakeCall/Lobby.js index 1a2de8d..aec1eca 100644 --- a/Project/src/MakeCall/Lobby.js +++ b/Project/src/MakeCall/Lobby.js @@ -1,24 +1,34 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { PrimaryButton } from 'office-ui-fabric-react'; +import { Features } from '@azure/communication-calling'; // Lobby react function component -const Lobby = ({ call }) => { - const [lobby, setLobby] = useState(call.lobby); - const [lobbyParticipantsCount, setLobbyParticipantsCount] = useState(lobby.participants.length); +export default class Lobby extends React.Component { + constructor(props) { + super(props); + this.call = props.call; + this.lobby = this.call.lobby; + + this.capabilitiesFeature = this.call.feature(Features.Capabilities); + this.capabilities = this.capabilitiesFeature.capabilities; + this.state = { + canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported', + lobbyParticipantsCount: this.lobby.participants.length + }; + } - useEffect(() => { - return () => { - lobby?.off('lobbyParticipantsUpdated', lobbyParticipantsUpdatedHandler); - } - }, []); + componentWillUnmount() { + this.lobby?.off('lobbyParticipantsUpdated', () => { }); + } - useEffect(() => { - lobby?.on('lobbyParticipantsUpdated', lobbyParticipantsUpdatedHandler); - }, [lobby]); + componentDidMount() { + this.lobby?.on('lobbyParticipantsUpdated', this.lobbyParticipantsUpdatedHandler); + this.capabilitiesFeature.on('capabilitiesChanged', this.capabilitiesChangedHandler); + } - const lobbyParticipantsUpdatedHandler = (event) => { + lobbyParticipantsUpdatedHandler = (event) => { console.log(`lobbyParticipantsUpdated, added=${event.added}, removed=${event.removed}`); - setLobbyParticipantsCount(lobby.participants.length); + this.state.lobbyParticipantsCount = this.lobby?.participants.length; if(event.added.length > 0) { event.added.forEach(participant => { console.log('lobbyParticipantAdded', participant); @@ -31,34 +41,52 @@ const Lobby = ({ call }) => { } }; - const admitAllParticipants = async () => { + capabilitiesChangedHandler = (capabilitiesChangeInfo) => { + console.log('lobby:capabilitiesChanged'); + for (const [key, value] of Object.entries(capabilitiesChangeInfo.newValue)) { + if(key === 'manageLobby' && value.reason != 'FeatureNotSupported') { + (value.isPresent) ? this.setState({ canManageLobby: true }) : this.setState({ canManageLobby: false }); + const admitAllButton = document.getElementById('admitAllButton'); + if(this.state.canManageLobby === true){ + admitAllButton.style.display = ''; + } else { + admitAllButton.style.display = 'none'; + } + continue; + } + } + }; + + async admitAllParticipants() { console.log('admitAllParticipants'); try { - await lobby.admitAll(); + await this.lobby?.admitAll(); } catch (e) { console.error(e); } } - return ( -
- { - (lobbyParticipantsCount > 0) && -
-
-
In-Lobby participants number: {lobbyParticipantsCount}
-
-
- - + render() { + return ( +
+ { + (this.state.lobbyParticipantsCount > 0) && +
+
+
In-Lobby participants number: {this.state.lobbyParticipantsCount}
+
+
+ this.admitAllParticipants()}> + +
-
- } -
- ); -}; - -export default Lobby; + } +
+ ); + } +} diff --git a/Project/src/MakeCall/RemoteParticipantCard.js b/Project/src/MakeCall/RemoteParticipantCard.js index bd37a5f..34d4c7b 100644 --- a/Project/src/MakeCall/RemoteParticipantCard.js +++ b/Project/src/MakeCall/RemoteParticipantCard.js @@ -23,6 +23,8 @@ export default class RemoteParticipantCard extends React.Component { this.spotlightFeature = this.call.feature(Features.Spotlight); this.raiseHandFeature = this.call.feature(Features.RaiseHand); + this.capabilitiesFeature = this.call.feature(Features.Capabilities); + this.capabilities = this.capabilitiesFeature.capabilities; this.menuOptionsHandler= props.menuOptionsHandler; this.state = { isSpeaking: this.remoteParticipant.isSpeaking, @@ -32,6 +34,7 @@ export default class RemoteParticipantCard extends React.Component { participantIds: this.remoteParticipant.endpointDetails.map((e) => { return e.participantId }), isHandRaised: utils.isParticipantHandRaised(this.remoteParticipant.identifier, this.raiseHandFeature.getRaisedHands()), isSpotlighted: utils.isParticipantHandRaised(this.remoteParticipant.identifier, this.spotlightFeature.getSpotlightedParticipants()), + canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported', }; } @@ -81,6 +84,21 @@ export default class RemoteParticipantCard extends React.Component { } this.raiseHandFeature.on("loweredHandEvent", isRaiseHandChangedHandler); this.raiseHandFeature.on("raisedHandEvent", isRaiseHandChangedHandler); + this.capabilitiesFeature.on('capabilitiesChanged', (capabilitiesChangeInfo) => { + for (const [key, value] of Object.entries(capabilitiesChangeInfo.newValue)) { + if(key === 'manageLobby' && value.reason != 'FeatureNotSupported') { + (value.isPresent) ? this.setState({ canManageLobby: true }) : this.setState({ canManageLobby: false }); + let lobbyActions = document.getElementById('lobbyAction'); + if(this.state.canManageLobby === false){ + lobbyActions.hidden = true; + } + else{ + lobbyActions.hidden = false; + } + continue; + } + } + }); } handleRemoveParticipant(e, identifier) { @@ -186,9 +204,9 @@ export default class RemoteParticipantCard extends React.Component {
{ this.state.state === "InLobby" ? -
- this.admitParticipant(e)} className="float-right ml-3"> Admit Participant - this.rejectParticipant(e)} className="float-right ml-3"> Reject Participant + :
Date: Fri, 24 May 2024 11:53:27 -0500 Subject: [PATCH 3/3] Address comment --- Project/src/MakeCall/CallCard.js | 3 ++- Project/src/MakeCall/Lobby.js | 2 +- Project/src/MakeCall/RemoteParticipantCard.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Project/src/MakeCall/CallCard.js b/Project/src/MakeCall/CallCard.js index 854f50a..edc9916 100644 --- a/Project/src/MakeCall/CallCard.js +++ b/Project/src/MakeCall/CallCard.js @@ -1662,7 +1662,7 @@ export default class CallCard extends React.Component { }
- +
{ this.state.dominantSpeakerMode && @@ -1683,6 +1683,7 @@ export default class CallCard extends React.Component { call={this.call} menuOptionsHandler={this.getParticipantMenuCallBacks()} onSelectionChanged={(identifier, isChecked) => this.remoteParticipantSelectionChanged(identifier, isChecked)} + capabilitiesFeature={this.capabilitiesFeature} /> ) } diff --git a/Project/src/MakeCall/Lobby.js b/Project/src/MakeCall/Lobby.js index aec1eca..535898b 100644 --- a/Project/src/MakeCall/Lobby.js +++ b/Project/src/MakeCall/Lobby.js @@ -9,7 +9,7 @@ export default class Lobby extends React.Component { this.call = props.call; this.lobby = this.call.lobby; - this.capabilitiesFeature = this.call.feature(Features.Capabilities); + this.capabilitiesFeature = props.capabilitiesFeature; this.capabilities = this.capabilitiesFeature.capabilities; this.state = { canManageLobby: this.capabilities.manageLobby?.isPresent || this.capabilities.manageLobby?.reason === 'FeatureNotSupported', diff --git a/Project/src/MakeCall/RemoteParticipantCard.js b/Project/src/MakeCall/RemoteParticipantCard.js index 34d4c7b..1518ee2 100644 --- a/Project/src/MakeCall/RemoteParticipantCard.js +++ b/Project/src/MakeCall/RemoteParticipantCard.js @@ -23,7 +23,7 @@ export default class RemoteParticipantCard extends React.Component { this.spotlightFeature = this.call.feature(Features.Spotlight); this.raiseHandFeature = this.call.feature(Features.RaiseHand); - this.capabilitiesFeature = this.call.feature(Features.Capabilities); + this.capabilitiesFeature = props.capabilitiesFeature; this.capabilities = this.capabilitiesFeature.capabilities; this.menuOptionsHandler= props.menuOptionsHandler; this.state = {