Participant list
In this lesson, we will add a panel with a list of participants in the conference. This list will be displayed on the left side of the screen and will show the name of each participant.
You can download the starter code from Step.08-Exercise-Participant-list.
App component
Open the file src/App.tsx
and start editing it by adding the following
imports:
import {
...
type Participant
} from '@pexip/infinity'
Define the state variables participants
and me
:
const [participants, setParticipants] = useState<Participant[]>([]);
const [me, setMe] = useState<Participant>();
The participants
state will store the list of participants in the conference,
and the me
state will store the information about the current participant.
In the useEffect
hook, add the following code to listen to the
onParticipants
and onMe
signals. These signals will update the
participants
and me
states when a new participant joins or leaves the
conference:
useEffect(() => {
...
infinityClientSignals.onParticipants.add((event) => {
if (event.id === 'main') {
setParticipants(event.participants)
}
})
infinityClientSignals.onMe.add((event) => {
if (event.id === 'main') {
setMe(event.participant)
}
})
...
}, [])
Pass the participants
and me
states to the Conference
component:
<Conference
localVideoStream={processedStream}
remoteStream={remoteStream}
presentationStream={presentationStream}
screenShared={screenShared}
devices={devices}
settings={{
audioInput,
audioOutput,
videoInput,
effect
}}
participants={participants}
me={me}
onAudioMute={handleAudioMute}
onVideoMute={handleVideoMute}
onScreenShare={handleScreenShare}
onSettingsChange={handleSettingsChange}
onDisconnect={handleDisconnect}
/>
Now the Conference
component will receive the list of participants and the
current participant.
Conference component
Edit the file src/components/Conference/Conference.css
and add the following
code to adapt the layout for small screens:
@media screen and (max-width: 550px) {
.Conference {
flex-direction: column-reverse;
height: calc(100% - 2em);
}
.Conference .VideoContainer {
flex: 0;
}
.Conference .Participants {
height: 10em;
flex: 1;
width: 100%;
max-width: none;
}
}
Edit the file src/components/Conference/Conference.tsx
and add the following
imports:
import {type Participant} from '@pexip/infinity';
import {Participants} from './Participants/Participants';
Add participants
and me
to the ConferenceProps
interface:
interface ConferenceProps {
localVideoStream: MediaStream | undefined;
remoteStream: MediaStream | undefined;
presentationStream: MediaStream | undefined;
screenShared: boolean;
devices: MediaDeviceInfoLike[];
settings: Settings;
participants: Participant[];
me: Participant | undefined;
onAudioMute: (mute: boolean) => Promise<void>;
onVideoMute: (mute: boolean) => Promise<void>;
onScreenShare: () => Promise<void>;
onSettingsChange: (settings: Settings) => Promise<void>;
onDisconnect: () => Promise<void>;
}
Add the Participants
component to the Conference
component:
<Participants participants={props.participants} me={props.me} />
This component will display the list of participants in the conference and information about the current participant. This way the user can see who is in the conference and who they are.
Participants component
This component will use the list of participants and the current participant and
display them in a list. Open the file
src/components/Conference/Participants/Participants.tsx
and start editing it
by adding the following imports:
import {Box, BoxHeader, Icon, IconTypes, Tooltip} from '@pexip/components';
import {type Participant} from '@pexip/infinity';
Define the properties participants
and me
in the ParticipantsProps
interface:
interface ParticipantsProps {
participants: Participant[];
me: Participant | undefined;
}
Add the following code to the Participants
component to render the list of
participants:
return (
<Box className="Participants">
<BoxHeader>Participants</BoxHeader>
<div className="ParticipantsBody">
<div className="ParticipantsInner">
{props.participants.map((participant) => (
<div className="Participant" key={participant.uuid}>
<span
className={
participant.uuid === props.me?.uuid ? 'selected' : ''
}
>
{participant.displayName}
{participant.uuid === props.me?.uuid && ' (You)'}
</span>
<span className="ParticipantStatus">
{participant.isMuted && (
<Tooltip text="Microphone Muted">
<Icon source={IconTypes.IconMicrophoneOff} size="compact" />
</Tooltip>
)}
{participant.isCameraMuted && (
<Tooltip text="Camera Muted">
<Icon source={IconTypes.IconVideoOff} size="compact" />
</Tooltip>
)}
</span>
</div>
))}
</div>
</div>
</Box>
)
The Participant
component will display the name of the participant and an icon
to indicate if the participant has muted their microphone or camera. If the
participant is the current user, the component will display the text (You)
next to the name.
As you can see, we read several properties from the Participant
object:
uuid
: The unique identifier of the participant.displayName
: The name of the participant.isMuted
: A boolean that indicates if the participant has muted their microphone.isCameraMuted
: A boolean that indicates if the participant has muted their camera.
Run the app
Now we have everything in place to test the new functionality. When the user joins the conference, they will see a list of participants on the left side of the screen.
You can compare your code with the solution in Step.08-Solution-Participant-list. You can also check the differences with the previous lesson in the git diff.