Restyle audio room speaker cards like Spaces and add room chat to the toolbar.
Deploy Ladill Meet / deploy (push) Successful in 49s
Deploy Ladill Meet / deploy (push) Successful in 49s
Use a three-column avatar grid with role labels and speaking/muted indicators, enable chat in audio rooms, and swap the mobile People nav button for Chat since People stays in the header. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+62
-13
@@ -711,7 +711,10 @@ function meetRoom() {
|
||||
const displayName = this.displayNameForParticipant(participant);
|
||||
const avatarUrl = this.avatarUrlForParticipant(participant);
|
||||
const isAudioTile = tile.classList.contains('meet-audio-tile');
|
||||
const sizeClass = isAudioTile ? 'h-[4.5rem] w-[4.5rem] text-xl' : 'h-20 w-20 text-2xl';
|
||||
const isSpaceTile = tile.classList.contains('meet-space-tile');
|
||||
const sizeClass = isSpaceTile
|
||||
? 'h-[4.75rem] w-[4.75rem] text-lg sm:h-[5.25rem] sm:w-[5.25rem] sm:text-xl'
|
||||
: isAudioTile ? 'h-[4.5rem] w-[4.5rem] text-xl' : 'h-20 w-20 text-2xl';
|
||||
|
||||
circle.replaceChildren();
|
||||
|
||||
@@ -989,6 +992,35 @@ function meetRoom() {
|
||||
return room.remoteParticipants.get(identity) || null;
|
||||
},
|
||||
|
||||
spaceRoleLabel(role) {
|
||||
return {
|
||||
host: 'Host',
|
||||
co_host: 'Co-host',
|
||||
panelist: 'Speaker',
|
||||
}[role] || '';
|
||||
},
|
||||
|
||||
spaceSpeakerTileShellHtml() {
|
||||
return `
|
||||
<div class="flex w-full justify-center">
|
||||
<div data-tile-avatar-circle class="flex h-[4.75rem] w-[4.75rem] shrink-0 items-center justify-center rounded-full text-lg font-semibold text-white"></div>
|
||||
</div>
|
||||
<span data-tile-name class="mt-2 max-w-full truncate text-center text-sm font-bold leading-tight text-white"></span>
|
||||
<div data-tile-role-row class="mt-1 flex max-w-full items-center justify-center gap-1">
|
||||
<span data-tile-speaking class="hidden shrink-0 text-sky-400" title="Speaking">
|
||||
<svg class="h-3.5 w-3.5" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
||||
<rect class="meet-speaking-bar meet-speaking-bar--1" x="1" y="5" width="2.5" height="6" rx="1"/>
|
||||
<rect class="meet-speaking-bar meet-speaking-bar--2" x="6.75" y="3" width="2.5" height="10" rx="1"/>
|
||||
<rect class="meet-speaking-bar meet-speaking-bar--3" x="12.5" y="6" width="2.5" height="4" rx="1"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span data-tile-mic class="hidden shrink-0 text-slate-500" title="Muted">
|
||||
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 0 1 6 0v8.25a3 3 0 0 1-3 3Z"/><path stroke-linecap="round" stroke-linejoin="round" d="m3 3 18 18"/></svg>
|
||||
</span>
|
||||
<span data-tile-role class="truncate text-xs text-slate-400"></span>
|
||||
</div>`;
|
||||
},
|
||||
|
||||
participantTileShellHtml() {
|
||||
return `
|
||||
<div data-tile-body class="relative min-h-0 flex-1">
|
||||
@@ -1019,14 +1051,26 @@ function meetRoom() {
|
||||
|
||||
ensureParticipantTileShell(identity) {
|
||||
let tile = this.findParticipantTile(identity);
|
||||
const wantsSpaceTile = this.isSpace && !this.usesStageLayout;
|
||||
|
||||
if (tile && wantsSpaceTile !== tile.classList.contains('meet-space-tile')) {
|
||||
tile.remove();
|
||||
tile = null;
|
||||
}
|
||||
|
||||
if (!tile) {
|
||||
tile = document.createElement('div');
|
||||
tile.dataset.participantTile = identity;
|
||||
tile.className = this.audioOnly
|
||||
? 'meet-audio-tile relative flex aspect-square w-full flex-col overflow-hidden rounded-2xl bg-slate-900'
|
||||
: 'relative flex aspect-video w-full flex-col overflow-hidden rounded-xl bg-slate-900 min-h-0';
|
||||
tile.innerHTML = this.participantTileShellHtml();
|
||||
|
||||
if (wantsSpaceTile) {
|
||||
tile.className = 'meet-space-tile flex w-full min-w-0 flex-col items-center px-1 py-1';
|
||||
tile.innerHTML = this.spaceSpeakerTileShellHtml();
|
||||
} else {
|
||||
tile.className = this.audioOnly
|
||||
? 'meet-audio-tile relative flex aspect-square w-full flex-col overflow-hidden rounded-2xl bg-slate-900'
|
||||
: 'relative flex aspect-video w-full flex-col overflow-hidden rounded-xl bg-slate-900 min-h-0';
|
||||
tile.innerHTML = this.participantTileShellHtml();
|
||||
}
|
||||
}
|
||||
|
||||
return tile;
|
||||
@@ -1040,15 +1084,24 @@ function meetRoom() {
|
||||
|
||||
const pseudoParticipant = { identity: person.uuid, name: person.display_name };
|
||||
this.updateTileAvatarCircle(tile, pseudoParticipant);
|
||||
tile.querySelector('[data-tile-name]').textContent = person.display_name;
|
||||
|
||||
const speaking = this.isSpeaking(person.uuid);
|
||||
tile.classList.toggle('meet-tile-speaking', speaking);
|
||||
tile.querySelector('[data-tile-speaking]')?.classList.toggle('hidden', !speaking);
|
||||
|
||||
const muted = liveParticipant
|
||||
? !liveParticipant.isMicrophoneEnabled
|
||||
: Boolean(person.is_muted);
|
||||
|
||||
if (tile.classList.contains('meet-space-tile')) {
|
||||
tile.querySelector('[data-tile-name]').textContent = person.display_name;
|
||||
tile.querySelector('[data-tile-role]').textContent = this.spaceRoleLabel(person.role);
|
||||
tile.classList.toggle('meet-tile-speaking', speaking);
|
||||
tile.querySelector('[data-tile-speaking]')?.classList.toggle('hidden', !speaking);
|
||||
tile.querySelector('[data-tile-mic]')?.classList.toggle('hidden', !muted || speaking);
|
||||
return;
|
||||
}
|
||||
|
||||
tile.querySelector('[data-tile-name]').textContent = person.display_name;
|
||||
tile.classList.toggle('meet-tile-speaking', speaking);
|
||||
tile.querySelector('[data-tile-speaking]')?.classList.toggle('hidden', !speaking);
|
||||
tile.querySelector('[data-tile-mic]')?.classList.toggle('hidden', !muted);
|
||||
tile.querySelector('[data-tile-cam]')?.classList.add('hidden');
|
||||
},
|
||||
@@ -2755,10 +2808,6 @@ function meetRoom() {
|
||||
},
|
||||
|
||||
toggleChat() {
|
||||
if (this.isSpace) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.toggleSidebarPanel('chat');
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user