Show non-spotlight participants in the plenary audience strip.
Deploy Ladill Meet / deploy (push) Successful in 38s
Deploy Ladill Meet / deploy (push) Successful in 38s
Include speakers and attendees below the stage, resolve avatars with the same fallbacks as video tiles, and refresh the strip when poll data updates. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -201,6 +201,10 @@ html.meet-room-page {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.meet-room-page .meet-audience-avatar--speaker {
|
||||
border-color: rgb(139 92 246 / 0.55);
|
||||
}
|
||||
|
||||
.meet-room-page .meet-audio-grid {
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
|
||||
+79
-26
@@ -550,24 +550,30 @@ function meetRoom() {
|
||||
return person?.display_name || participant.name || participant.identity;
|
||||
},
|
||||
|
||||
avatarUrlForParticipant(participant) {
|
||||
const person = this.participantForIdentity(participant.identity);
|
||||
avatarUrlForPerson(person) {
|
||||
if (!person) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (person?.avatar_url) {
|
||||
if (person.avatar_url) {
|
||||
return person.avatar_url;
|
||||
}
|
||||
|
||||
if (person && ['host', 'co_host'].includes(person.role) && this.roomHost?.avatar_url) {
|
||||
if (['host', 'co_host'].includes(person.role) && this.roomHost?.avatar_url) {
|
||||
return this.roomHost.avatar_url;
|
||||
}
|
||||
|
||||
if (this.roomHost?.user_ref && person?.user_ref === this.roomHost.user_ref && this.roomHost.avatar_url) {
|
||||
if (this.roomHost?.user_ref && person.user_ref === this.roomHost.user_ref && this.roomHost.avatar_url) {
|
||||
return this.roomHost.avatar_url;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
avatarUrlForParticipant(participant) {
|
||||
return this.avatarUrlForPerson(this.participantForIdentity(participant.identity));
|
||||
},
|
||||
|
||||
updateTileAvatarCircle(tile, participant) {
|
||||
const circle = tile.querySelector('[data-tile-avatar-circle]');
|
||||
if (!circle) {
|
||||
@@ -662,6 +668,71 @@ function meetRoom() {
|
||||
return [...this.audienceParticipants()].sort((a, b) => a.display_name.localeCompare(b.display_name));
|
||||
},
|
||||
|
||||
resolveSpotlightParticipantUuid() {
|
||||
const spotlightRef = this.resolveSpotlightSpeakerRef();
|
||||
if (spotlightRef) {
|
||||
const match = this.speakerParticipants().find((person) => person.user_ref === spotlightRef);
|
||||
if (match) {
|
||||
return match.uuid;
|
||||
}
|
||||
}
|
||||
|
||||
return this.speakerParticipantsSorted()[0]?.uuid || null;
|
||||
},
|
||||
|
||||
plenaryStripParticipants() {
|
||||
const spotlightUuid = this.resolveSpotlightParticipantUuid();
|
||||
|
||||
return this.inCallParticipants()
|
||||
.filter((person) => person.uuid !== spotlightUuid)
|
||||
.sort((a, b) => {
|
||||
const aSpeaker = this.isSpeakerPerson(a);
|
||||
const bSpeaker = this.isSpeakerPerson(b);
|
||||
|
||||
if (aSpeaker !== bSpeaker) {
|
||||
return aSpeaker ? -1 : 1;
|
||||
}
|
||||
|
||||
return a.display_name.localeCompare(b.display_name);
|
||||
});
|
||||
},
|
||||
|
||||
createStripInitials(person) {
|
||||
const initials = document.createElement('span');
|
||||
initials.className = 'meet-audience-avatar__initials';
|
||||
initials.style.background = this.avatarStyle(person.display_name).background;
|
||||
initials.textContent = this.participantInitials(person.display_name);
|
||||
|
||||
return initials;
|
||||
},
|
||||
|
||||
appendStripAvatarItem(strip, person, index, total) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'meet-audience-avatar';
|
||||
if (this.isSpeakerPerson(person)) {
|
||||
item.classList.add('meet-audience-avatar--speaker');
|
||||
}
|
||||
item.style.zIndex = String(total - index);
|
||||
item.title = person.display_name;
|
||||
|
||||
const avatarUrl = this.avatarUrlForPerson(person);
|
||||
|
||||
if (avatarUrl) {
|
||||
const img = document.createElement('img');
|
||||
img.src = avatarUrl;
|
||||
img.alt = '';
|
||||
img.className = 'meet-audience-avatar__image';
|
||||
img.addEventListener('error', () => {
|
||||
img.replaceWith(this.createStripInitials(person));
|
||||
}, { once: true });
|
||||
item.appendChild(img);
|
||||
} else {
|
||||
item.appendChild(this.createStripInitials(person));
|
||||
}
|
||||
|
||||
strip.appendChild(item);
|
||||
},
|
||||
|
||||
resolveSpotlightSpeakerRef() {
|
||||
const speakers = this.speakerParticipants();
|
||||
|
||||
@@ -773,7 +844,7 @@ function meetRoom() {
|
||||
return;
|
||||
}
|
||||
|
||||
const audience = this.audienceParticipantsSorted();
|
||||
const audience = this.plenaryStripParticipants();
|
||||
if (audience.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -783,26 +854,7 @@ function meetRoom() {
|
||||
const overflow = audience.length - visible.length;
|
||||
|
||||
visible.forEach((person, index) => {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'meet-audience-avatar';
|
||||
item.style.zIndex = String(visible.length - index);
|
||||
item.title = person.display_name;
|
||||
|
||||
if (person.avatar_url) {
|
||||
const img = document.createElement('img');
|
||||
img.src = person.avatar_url;
|
||||
img.alt = '';
|
||||
img.className = 'meet-audience-avatar__image';
|
||||
item.appendChild(img);
|
||||
} else {
|
||||
const initials = document.createElement('span');
|
||||
initials.className = 'meet-audience-avatar__initials';
|
||||
initials.style.background = this.avatarStyle(person.display_name).background;
|
||||
initials.textContent = this.participantInitials(person.display_name);
|
||||
item.appendChild(initials);
|
||||
}
|
||||
|
||||
strip.appendChild(item);
|
||||
this.appendStripAvatarItem(strip, person, index, visible.length);
|
||||
});
|
||||
|
||||
if (overflow > 0) {
|
||||
@@ -1811,6 +1863,7 @@ function meetRoom() {
|
||||
this.sessionParticipants = data.participants;
|
||||
this.pruneTilesFromSession();
|
||||
this.refreshParticipantTileAvatars();
|
||||
this.renderAudienceStrip();
|
||||
}
|
||||
if (typeof data.uses_stage_layout === 'boolean' || typeof data.stage_layout === 'string') {
|
||||
this.mergeStageConfig(data);
|
||||
|
||||
Reference in New Issue
Block a user