in app/components/Roster.tsx [18:122]
export default function Roster() {
const chime: ChimeSdkWrapper | null = useContext(getChimeContext());
const roster = useRoster();
const [videoAttendees, setVideoAttendees] = useState(new Set());
const raisedHandAttendees = useRaisedHandAttendees();
const intl = useIntl();
useEffect(() => {
const tileIds: { [tileId: number]: string } = {};
// <tileId, attendeeId>
const realTimeVideoAttendees = new Set();
const removeTileId = (tileId: number): void => {
const removedAttendeeId = tileIds[tileId];
delete tileIds[tileId];
realTimeVideoAttendees.delete(removedAttendeeId);
setVideoAttendees(new Set(realTimeVideoAttendees));
};
chime?.audioVideo?.addObserver({
videoTileDidUpdate: (tileState: VideoTileState): void => {
if (
!tileState.boundAttendeeId ||
tileState.isContent ||
!tileState.tileId
) {
return;
}
if (tileState.active) {
tileIds[tileState.tileId] = tileState.boundAttendeeId;
realTimeVideoAttendees.add(tileState.boundAttendeeId);
setVideoAttendees(new Set(realTimeVideoAttendees));
} else {
removeTileId(tileState.tileId);
}
},
videoTileWasRemoved: (tileId: number): void => {
removeTileId(tileId);
}
});
}, []);
let attendeeIds;
if (chime?.meetingSession && roster) {
attendeeIds = Object.keys(roster).filter(attendeeId => {
return !!roster[attendeeId].name;
});
}
return (
<div className={cx('roster')}>
{attendeeIds &&
attendeeIds.map((attendeeId: string) => {
const rosterAttendee: RosterAttendeeType = roster[attendeeId];
return (
<div key={attendeeId} className={cx('attendee')}>
<div className={cx('name')}>{rosterAttendee.name}</div>
{raisedHandAttendees.has(attendeeId) && (
<div className={cx('raisedHand')}>
<span
role="img"
aria-label={intl.formatMessage(
{
id: 'Roster.raiseHandAriaLabel'
},
{
name: rosterAttendee.name
}
)}
>
✋
</span>
</div>
)}
{videoAttendees.has(attendeeId) && (
<div className={cx('video')}>
<i className={cx('fas fa-video')} />
</div>
)}
{typeof rosterAttendee.muted === 'boolean' && (
<div className={cx('muted')}>
{rosterAttendee.muted ? (
<i className="fas fa-microphone-slash" />
) : (
<i
className={cx(
'fas fa-microphone',
{ 'active-speaker': rosterAttendee.active },
{
'weak-signal':
rosterAttendee.signalStrength &&
rosterAttendee.signalStrength < 50
}
)}
/>
)}
</div>
)}
</div>
);
})}
</div>
);
}