Skip to content

feat: show call member presence in pre-join lobby view#3803

Open
alex-vg wants to merge 1 commit into
element-hq:livekitfrom
alex-vg:feat/call-member-lobby-presence
Open

feat: show call member presence in pre-join lobby view#3803
alex-vg wants to merge 1 commit into
element-hq:livekitfrom
alex-vg:feat/call-member-lobby-presence

Conversation

@alex-vg
Copy link
Copy Markdown

@alex-vg alex-vg commented Mar 13, 2026

Summary

Display participant avatars with display names in the lobby when a call is already active, so users can see who's in the call before joining.

Changes

  • useCallParticipants hook — derives a deduplicated participant list with resolved display names and avatar URLs from MatrixRTCSession.memberships + Room
  • CallParticipantRow component — renders up to 8 participant avatars in a horizontal row. Overflow participants are shown as a +N indicator with a Compound <Tooltip> listing the remaining names. Uses Radix <VisuallyHidden> for screen reader accessibility.
  • LobbyView integration — the participant row appears above the VideoPreview when callParticipants.length > 0
  • GroupCallView — calls the hook and passes participants to LobbyView
  • RoomPage — passes callParticipants={[]} in the knock/waitForInvite state (user can't see room members)
  • i18n — 7 new translation keys for participant count and overflow labels

Testing

  • 5 unit tests for useCallParticipants
  • 9 unit tests for CallParticipantRow
  • All 452 existing tests still pass
  • Manually tested with 2 users on local dev backend

Screenshots

The participant row appears above the video preview in the lobby when another user is already in the call.
image

Display participant avatars with display names in the lobby when a call
is already active. Shows up to 8 avatars with an overflow indicator
and tooltip for additional participants.

- Add useCallParticipants hook to derive participants from memberships
- Add CallParticipantRow component using Compound Tooltip and Radix
  VisuallyHidden for accessibility
- Integrate into LobbyView above VideoPreview
- Include unit tests for hook and component
- Add i18n strings for participant count and overflow
@alex-vg alex-vg requested a review from a team as a code owner March 13, 2026 21:26
@alex-vg alex-vg requested a review from toger5 March 13, 2026 21:26
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 13, 2026

CLA assistant check
All committers have signed the CLA.

@bblacher
Copy link
Copy Markdown

fixes: #2385

@alex-vg
Copy link
Copy Markdown
Author

alex-vg commented Apr 8, 2026

@toger5 any feedback would be appreciated.

@TemoCrevlis
Copy link
Copy Markdown

@toger5 any feedback would be appreciated.

This would be really useful.
How would scalability work?
E.g. A call with many participants: all the names won't fit with equal spacing of avatars.

@alex-vg
Copy link
Copy Markdown
Author

alex-vg commented Apr 20, 2026

The PR already addresses the scalability concern. The CallParticipantRow component handles large participant counts via a display limit with overflow:

  • A displayLimit prop (defaulting to 8) caps how many avatars+names are rendered inline.
  • Participants beyond the limit are not rendered in the DOM but are accessible via a tooltip.
  • An ellipsis (…) element is shown to signal truncation, followed by a +N badge indicating how many additional participants are hidden (e.g. +2).
  • The overflow item is still a proper listitem in the accessible list, so screen readers get the full count.

So for a call with 50 participants, only the first 8 would be shown inline, with +42 displayed at the end. The displayLimit prop makes it easy to tune this threshold (e.g. based on available horizontal space if needed).

@TemoCrevlis
Copy link
Copy Markdown

TemoCrevlis commented Apr 21, 2026

The PR already addresses the scalability concern. The CallParticipantRow component handles large participant counts via a display limit with overflow:

* A displayLimit prop (defaulting to 8) caps how many avatars+names are rendered inline.

* Participants beyond the limit are not rendered in the DOM but are accessible via a tooltip.

* An ellipsis (…) element is shown to signal truncation, followed by a +N badge indicating how many additional participants are hidden (e.g. +2).

* The overflow item is still a proper listitem in the accessible list, so screen readers get the full count.

So for a call with 50 participants, only the first 8 would be shown inline, with +42 displayed at the end. The displayLimit prop makes it easy to tune this threshold (e.g. based on available horizontal space if needed).

Makes sense.
I tried recreating it in the desktop version to get a better idea of what it would be like and also made some iterations.
Here are a couple:

A participants preview A participants preview 31 A participants preview 1 A participants preview 6

@toger5
Copy link
Copy Markdown
Contributor

toger5 commented Apr 22, 2026

My instinct tells me design would like to see some of the existing avatar group components.
@americanrefugee have you seen this? Do we have designs for this? Do you want changes to how it is done here or do you approve the designs?

This is what I would like to see for reference:
Screenshot 2026-04-22 at 15 10 52

On click i think there should be a modal listing all participants?

@americanrefugee
Copy link
Copy Markdown

A few thoughts...

When a group call starts on Web there is a banner asking you to join or ignore. A face pile shown there. If you click "Ignore", then you see a "Join" button in the room and connect directly to the group call if you click it.

Meanwhile, seeing all the participants as a row above the video tile, and then a list to see all participants, feels like overkill. I'm not convinced that there's any current problem to be solved here.

However, for mobile in the lobby views, I'm fine with swapping out the generic person icon with a face pile.

@toger5
Copy link
Copy Markdown
Contributor

toger5 commented Apr 22, 2026

I think this PR focuses on Single-Page-App usage (which is a secondary priority since it is not leveraging all the security/privacy/federation features matrix offers)

However, for mobile in the lobby views, I'm fine with swapping out the generic person icon with a face pile.

This also seems to work very well for the SPA imo.

So:
Screenshot 2026-04-22 at 16 31 48
should become more similar to:
Screenshot 2026-04-22 at 15 10 52
?

@alex-vg
Copy link
Copy Markdown
Author

alex-vg commented Apr 22, 2026

@americanrefugee @toger5

Thanks for taking a look and sharing your thoughts!

Regarding the necessity of this feature: I built this to address an open issue #2385 that has gathered support from the community. The feedback there indicates that users specifically want the ability to see exactly who is in the call before making the decision to join. (As well known from Discord…)

Regarding the design suggestion to use a face pile: If we hide the usernames and overlap half of the profile pictures, would it fulfill this requirement? While a face pile is visually compact, to actually solve the problem of letting users know exactly who is in the room, I think the UI needs to display full profile pictures and display names clearly.

@americanrefugee
Copy link
Copy Markdown

The SPA is focused on guest users, in which case they should not have the ability to know anything about the members for privacy reason.

Whereas in the app we already have an existing room list. It would be far less complicated, for example, to simply show a green video icons in the People list. I have no problem changing the User icon Into a face pile, and perhaps tapping/clicking on the face pile simply opens the People panel/screen.

Meanwhile, a carousel of users isn't very accessible to begin with, and is nearly unusable after a certain number of participants. A searchable list would be far better for displaying potentially dozens, hundreds, or even thousands of attendees. In which case this already exists as the People panel/screen :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants