Fix live room header flash and instant sidebar panel switching.
Deploy Ladill Meet / deploy (push) Successful in 1m21s
Deploy Ladill Meet / deploy (push) Successful in 1m21s
Server-render the speaker pill on load, hide noisy connection status on mobile, and use a single sidebarPanel slot so desktop panels replace in place instead of animating side by side. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -63,4 +63,83 @@ class ParticipantPresenter
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array<string, mixed>> $participants
|
||||
* @param list<string> $presenterRefs
|
||||
*/
|
||||
public static function isSpeakerPerson(array $person, array $presenterRefs = []): bool
|
||||
{
|
||||
if (in_array($person['role'] ?? '', ['host', 'co_host', 'panelist'], true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$userRef = $person['user_ref'] ?? null;
|
||||
|
||||
return is_string($userRef) && $userRef !== '' && in_array($userRef, $presenterRefs, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array<string, mixed>> $participants
|
||||
* @param list<string> $presenterRefs
|
||||
*/
|
||||
public static function headerCountLabel(array $participants, bool $usesStageLayout, array $presenterRefs = []): string
|
||||
{
|
||||
$joined = array_values(array_filter($participants, fn ($p) => ($p['status'] ?? '') === 'joined'));
|
||||
|
||||
if ($usesStageLayout) {
|
||||
$count = count(array_filter($joined, fn ($p) => self::isSpeakerPerson($p, $presenterRefs)));
|
||||
|
||||
return $count === 1 ? '1 speaker' : "{$count} speakers";
|
||||
}
|
||||
|
||||
$count = count($joined);
|
||||
|
||||
return "{$count} in call";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array<string, mixed>> $participants
|
||||
* @return array{display_name: string, avatar_url: ?string}|null
|
||||
*/
|
||||
public static function headerHost(array $participants, array $roomHost): ?array
|
||||
{
|
||||
foreach ($participants as $person) {
|
||||
if (($person['status'] ?? '') !== 'joined') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($person['role'] ?? '', ['host', 'co_host'], true)) {
|
||||
return [
|
||||
'display_name' => (string) ($person['display_name'] ?? 'Host'),
|
||||
'avatar_url' => $person['avatar_url'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (($roomHost['display_name'] ?? '') !== '') {
|
||||
return [
|
||||
'display_name' => (string) $roomHost['display_name'],
|
||||
'avatar_url' => $roomHost['avatar_url'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function initials(?string $name): string
|
||||
{
|
||||
$parts = preg_split('/\s+/', trim($name ?? '')) ?: [];
|
||||
$parts = array_values(array_filter($parts, fn ($part) => $part !== ''));
|
||||
|
||||
if ($parts === []) {
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (count($parts) === 1) {
|
||||
return strtoupper(substr($parts[0], 0, 2));
|
||||
}
|
||||
|
||||
return strtoupper(substr($parts[0], 0, 1).substr($parts[count($parts) - 1], 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,6 +361,29 @@ html.meet-room-page {
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.meet-room-page .meet-room-panels-stack {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
transition: width 0s;
|
||||
}
|
||||
|
||||
.meet-room-page .meet-room-panels-stack.is-open {
|
||||
width: 20rem;
|
||||
}
|
||||
|
||||
.meet-room-page .meet-room-panels-stack:not(.is-open) {
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.meet-room-page .meet-room-panels-stack .meet-room-panel__pane {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.meet-room-page .meet-room-panel {
|
||||
position: relative;
|
||||
inset: auto;
|
||||
|
||||
+37
-39
@@ -73,12 +73,9 @@ function meetRoom() {
|
||||
assignedBreakoutRoomId: null,
|
||||
breakoutRoomName: '',
|
||||
breakoutClosesAt: '',
|
||||
featuresOpen: false,
|
||||
programmeOpen: false,
|
||||
sidebarPanel: null,
|
||||
whiteboardOpen: false,
|
||||
qaInput: '',
|
||||
chatOpen: false,
|
||||
participantsOpen: false,
|
||||
chatInput: '',
|
||||
shareOpen: false,
|
||||
shareCopied: false,
|
||||
@@ -1074,6 +1071,16 @@ function meetRoom() {
|
||||
return this.inCallParticipants().length;
|
||||
},
|
||||
|
||||
headerParticipantLabel() {
|
||||
if (this.usesStageLayout) {
|
||||
const count = this.speakerCount();
|
||||
|
||||
return count === 1 ? '1 speaker' : `${count} speakers`;
|
||||
}
|
||||
|
||||
return `${this.participantCount()} in call`;
|
||||
},
|
||||
|
||||
inCallParticipants() {
|
||||
return this.sessionParticipants.filter((p) => p.status === 'joined');
|
||||
},
|
||||
@@ -1518,7 +1525,7 @@ function meetRoom() {
|
||||
if (!this.isHost || !this.config.breakoutsCreateUrl) return;
|
||||
this.breakoutCount = '4';
|
||||
this.breakoutModalOpen = true;
|
||||
this.featuresOpen = false;
|
||||
this.closeSidebar();
|
||||
},
|
||||
|
||||
async submitBreakouts() {
|
||||
@@ -1545,7 +1552,7 @@ function meetRoom() {
|
||||
if (!this.isHost || !this.config.breakoutsCloseUrl) return;
|
||||
|
||||
await fetch(this.config.breakoutsCloseUrl, { method: 'POST', headers: this.headers() });
|
||||
this.featuresOpen = false;
|
||||
this.closeSidebar();
|
||||
this.breakoutsActive = false;
|
||||
this.activeBreakouts = [];
|
||||
},
|
||||
@@ -1665,28 +1672,22 @@ function meetRoom() {
|
||||
},
|
||||
|
||||
toggleProgramme() {
|
||||
this.programmeOpen = !this.programmeOpen;
|
||||
if (this.programmeOpen) {
|
||||
this.chatOpen = false;
|
||||
this.participantsOpen = false;
|
||||
this.featuresOpen = false;
|
||||
this.shareOpen = false;
|
||||
}
|
||||
this.toggleSidebarPanel('programme');
|
||||
},
|
||||
|
||||
openUploadPicker() {
|
||||
document.getElementById('meet-file-input')?.click();
|
||||
this.featuresOpen = false;
|
||||
this.closeSidebar();
|
||||
},
|
||||
|
||||
async toggleRecordingFromMenu() {
|
||||
await this.toggleRecording();
|
||||
this.featuresOpen = false;
|
||||
this.closeSidebar();
|
||||
},
|
||||
|
||||
async toggleLockFromMenu() {
|
||||
await this.toggleLock();
|
||||
this.featuresOpen = false;
|
||||
this.closeSidebar();
|
||||
},
|
||||
|
||||
openEndMeetingConfirm() {
|
||||
@@ -1941,34 +1942,33 @@ function meetRoom() {
|
||||
this.applyStageLayout();
|
||||
},
|
||||
|
||||
toggleChat() {
|
||||
this.chatOpen = !this.chatOpen;
|
||||
if (this.chatOpen) {
|
||||
this.participantsOpen = false;
|
||||
this.featuresOpen = false;
|
||||
this.programmeOpen = false;
|
||||
closeSidebar() {
|
||||
this.sidebarPanel = null;
|
||||
},
|
||||
|
||||
toggleSidebarPanel(name) {
|
||||
this.sidebarPanel = this.sidebarPanel === name ? null : name;
|
||||
|
||||
if (this.sidebarPanel) {
|
||||
this.shareOpen = false;
|
||||
}
|
||||
},
|
||||
|
||||
toggleChat() {
|
||||
this.toggleSidebarPanel('chat');
|
||||
},
|
||||
|
||||
toggleParticipants() {
|
||||
this.participantsOpen = !this.participantsOpen;
|
||||
if (this.participantsOpen) {
|
||||
this.chatOpen = false;
|
||||
this.featuresOpen = false;
|
||||
this.programmeOpen = false;
|
||||
this.shareOpen = false;
|
||||
}
|
||||
this.toggleSidebarPanel('participants');
|
||||
},
|
||||
|
||||
toggleFeatures() {
|
||||
this.featuresOpen = !this.featuresOpen;
|
||||
if (this.featuresOpen) {
|
||||
this.chatOpen = false;
|
||||
this.participantsOpen = false;
|
||||
this.programmeOpen = false;
|
||||
this.toggleSidebarPanel('features');
|
||||
},
|
||||
|
||||
openParticipantsPanel() {
|
||||
this.sidebarPanel = 'participants';
|
||||
this.shareOpen = false;
|
||||
}
|
||||
},
|
||||
|
||||
async openShare() {
|
||||
@@ -1992,9 +1992,7 @@ function meetRoom() {
|
||||
|
||||
this.shareOpen = true;
|
||||
this.shareCopied = false;
|
||||
this.participantsOpen = false;
|
||||
this.chatOpen = false;
|
||||
this.featuresOpen = false;
|
||||
this.closeSidebar();
|
||||
},
|
||||
|
||||
async copyJoinLink() {
|
||||
@@ -2067,7 +2065,7 @@ function meetRoom() {
|
||||
const previous = this.waitingCount;
|
||||
this.waitingCount = data.waiting_count;
|
||||
if (this.isHost && data.waiting_count > previous) {
|
||||
this.participantsOpen = true;
|
||||
this.openParticipantsPanel();
|
||||
}
|
||||
}
|
||||
this.updateChatFromPoll(data.messages || []);
|
||||
|
||||
@@ -1,30 +1,13 @@
|
||||
@props([
|
||||
'show',
|
||||
'title' => null,
|
||||
'close' => 'closeSidebar()',
|
||||
])
|
||||
|
||||
<aside x-show="{{ $show }}" x-cloak
|
||||
class="meet-room-panel"
|
||||
@keydown.escape.window="{{ $show }} = false">
|
||||
<div x-show="{{ $show }}"
|
||||
x-transition:enter="transition-opacity ease-out duration-200"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition-opacity ease-in duration-150"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
class="meet-room-panel__backdrop"
|
||||
@click="{{ $show }} = false"
|
||||
aria-hidden="true"></div>
|
||||
|
||||
<div x-show="{{ $show }}"
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="translate-y-full sm:translate-y-0"
|
||||
x-transition:enter-end="translate-y-0"
|
||||
x-transition:leave="transition ease-in duration-200"
|
||||
x-transition:leave-start="translate-y-0"
|
||||
x-transition:leave-end="translate-y-full sm:translate-y-0"
|
||||
class="meet-room-panel__sheet">
|
||||
class="meet-room-panel meet-room-panel__pane"
|
||||
@keydown.escape.window="{{ $close }}">
|
||||
<div class="meet-room-panel__sheet">
|
||||
<div class="meet-room-panel__handle" aria-hidden="true"><span></span></div>
|
||||
|
||||
<div class="meet-room-panel__header">
|
||||
@@ -38,7 +21,7 @@
|
||||
<div class="text-xs text-slate-400">{{ $subtitle }}</div>
|
||||
@endisset
|
||||
</div>
|
||||
<button @click="{{ $show }} = false" type="button"
|
||||
<button @click="{{ $close }}" type="button"
|
||||
class="shrink-0 rounded-lg p-2 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white"
|
||||
title="Close">
|
||||
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>{{ $room->title }} · Ladill Meet</title>
|
||||
@include('partials.favicon')
|
||||
<style>[x-cloak]{display:none!important}</style>
|
||||
@vite(['resources/css/app.css', 'resources/js/meet-room.js'])
|
||||
</head>
|
||||
<body class="h-full overflow-hidden bg-slate-950 font-sans text-white" x-data="meetRoom()" x-init="init()">
|
||||
@@ -31,6 +32,29 @@
|
||||
default => 'meeting',
|
||||
};
|
||||
$sessionNounTitle = ucfirst($sessionNoun);
|
||||
$presenterRefsList = (array) ($presenterRefs ?? []);
|
||||
$headerHostPerson = ParticipantPresenter::headerHost($joinedParticipants->all(), $roomHost);
|
||||
$headerParticipantLabel = ParticipantPresenter::headerCountLabel(
|
||||
$joinedParticipants->all(),
|
||||
(bool) ($usesStageLayout ?? false),
|
||||
$presenterRefsList,
|
||||
);
|
||||
$headerWaitingCount = $joinedParticipants->where('status', 'waiting')->count();
|
||||
$stageLayoutName = ($stageConfig['stage_layout'] ?? 'plenary') === 'panel' ? 'Panel discussion' : 'Plenary';
|
||||
$initialConferenceStatus = match (true) {
|
||||
($inBreakout ?? false) => 'Breakout · meeting mode',
|
||||
($isGreenRoom ?? false) && ($usesStageLayout ?? false) => "Green room · {$stageLayoutName}",
|
||||
($isGreenRoom ?? false) => 'Green room',
|
||||
! ($usesStageLayout ?? false) => 'Conference live',
|
||||
($stageConfig['stage_layout'] ?? 'plenary') === 'panel' => 'Panel discussion live',
|
||||
default => 'Plenary live',
|
||||
};
|
||||
$initialConferenceStatusClass = match (true) {
|
||||
($inBreakout ?? false) => 'text-amber-400/90',
|
||||
($isGreenRoom ?? false) => 'text-violet-400/90',
|
||||
($stageConfig['stage_layout'] ?? 'plenary') === 'panel' => 'text-violet-400/90',
|
||||
default => 'text-sky-400/90',
|
||||
};
|
||||
@endphp
|
||||
<div id="meet-config"
|
||||
data-token="{{ $mediaToken }}"
|
||||
@@ -111,15 +135,15 @@
|
||||
@if ($isAudioOnly ?? false)
|
||||
<p class="text-[10px] font-medium uppercase tracking-wide text-emerald-400/90">Audio room</p>
|
||||
@elseif ($isConference ?? false)
|
||||
<p class="text-[10px] font-medium uppercase tracking-wide"
|
||||
<p class="text-[10px] font-medium uppercase tracking-wide {{ $initialConferenceStatusClass }}"
|
||||
:class="conferenceStatusClass()"
|
||||
x-text="conferenceStatusLabel()"></p>
|
||||
x-text="conferenceStatusLabel()">{{ $initialConferenceStatus }}</p>
|
||||
@endif
|
||||
<p class="text-xs text-slate-400" x-text="connectionStatus"></p>
|
||||
<p class="min-h-4 truncate text-xs font-medium leading-4"
|
||||
<p class="hidden text-xs text-slate-400 sm:block" x-text="connectionStatus">Connecting…</p>
|
||||
<p class="hidden min-h-4 truncate text-xs font-medium leading-4 text-slate-600 sm:block"
|
||||
:class="activeSpeakerCount() > 0 ? 'text-emerald-400' : 'text-slate-600'"
|
||||
:title="activeSpeakersMessage()"
|
||||
x-text="activeSpeakersMessage() || '...'"></p>
|
||||
x-text="activeSpeakersMessage()"> </p>
|
||||
</div>
|
||||
<div class="flex shrink-0 items-center gap-2 text-xs text-slate-400">
|
||||
<button @click.stop="openShare()" data-share-trigger type="button"
|
||||
@@ -134,20 +158,22 @@
|
||||
class="relative inline-flex items-center gap-2 rounded-lg bg-slate-900 px-2 py-1 text-xs font-medium text-slate-200 transition-colors hover:bg-slate-800"
|
||||
:class="isHost && waitingCount > 0 ? 'ring-2 ring-amber-400/60' : ''"
|
||||
:title="usesStageLayout ? 'View speakers' : 'View participants'">
|
||||
<span x-show="isHost && waitingCount > 0"
|
||||
<span x-show="isHost && waitingCount > 0" x-cloak
|
||||
x-text="waitingCount > 9 ? '9+' : waitingCount"
|
||||
class="absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-amber-500 px-1 text-[10px] font-bold text-amber-950"></span>
|
||||
<span x-show="hostParticipant()" class="relative flex h-7 w-7 shrink-0">
|
||||
<img x-show="hostParticipant()?.avatar_url"
|
||||
:src="hostParticipant()?.avatar_url"
|
||||
alt=""
|
||||
@if ($headerHostPerson)
|
||||
<span class="relative flex h-7 w-7 shrink-0 overflow-hidden rounded-full" aria-hidden="true">
|
||||
@if (! empty($headerHostPerson['avatar_url']))
|
||||
<img src="{{ $headerHostPerson['avatar_url'] }}" alt="" width="28" height="28"
|
||||
class="h-7 w-7 rounded-full object-cover">
|
||||
<span x-show="hostParticipant() && !hostParticipant()?.avatar_url"
|
||||
class="flex h-7 w-7 items-center justify-center rounded-full text-[11px] font-semibold text-white"
|
||||
:style="avatarStyle(hostParticipant()?.display_name)"
|
||||
x-text="participantInitials(hostParticipant()?.display_name || '')"></span>
|
||||
@else
|
||||
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-slate-700 text-[11px] font-semibold text-white">
|
||||
{{ ParticipantPresenter::initials($headerHostPerson['display_name']) }}
|
||||
</span>
|
||||
<span x-text="usesStageLayout ? speakerCount() + (speakerCount() === 1 ? ' speaker' : ' speakers') : participantCount() + ' in call'"></span>
|
||||
@endif
|
||||
</span>
|
||||
@endif
|
||||
<span x-text="headerParticipantLabel()">{{ $headerParticipantLabel }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
@@ -228,7 +254,7 @@
|
||||
<span class="truncate"
|
||||
x-text="waitingCount === 1 ? '1 person is waiting to be admitted' : waitingCount + ' people are waiting to be admitted'"></span>
|
||||
</div>
|
||||
<button @click="participantsOpen = true" type="button"
|
||||
<button @click="openParticipantsPanel()" type="button"
|
||||
class="shrink-0 rounded-lg bg-amber-500 px-3 py-1.5 text-xs font-semibold text-amber-950 transition-colors hover:bg-amber-400">
|
||||
Review
|
||||
</button>
|
||||
@@ -339,7 +365,7 @@
|
||||
</button>
|
||||
<button @click="toggleFeatures()" type="button"
|
||||
class="rounded-full p-3 transition-colors sm:hidden"
|
||||
:class="featuresOpen ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
|
||||
:class="sidebarPanel === 'features' ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
|
||||
title="More options">
|
||||
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM12.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM18.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"/></svg>
|
||||
</button>
|
||||
@@ -356,14 +382,14 @@
|
||||
</button>
|
||||
<button @click="toggleChat()" type="button"
|
||||
class="hidden rounded-full p-3 transition-colors sm:inline-flex"
|
||||
:class="chatOpen ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
|
||||
:class="sidebarPanel === 'chat' ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
|
||||
title="Chat">
|
||||
@include('meet.room.partials.meet-icon', ['icon' => 'chat'])
|
||||
</button>
|
||||
<input type="file" id="meet-file-input" class="hidden" @change="uploadFile">
|
||||
<button @click="toggleFeatures()" type="button"
|
||||
class="hidden items-center gap-1.5 rounded-full px-3.5 py-3 text-xs font-medium transition-colors sm:inline-flex"
|
||||
:class="featuresOpen ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
|
||||
:class="sidebarPanel === 'features' ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-slate-700 hover:bg-slate-600'"
|
||||
title="More options">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM12.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM18.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"/></svg>
|
||||
More
|
||||
@@ -441,7 +467,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-meet.room.panel show="chatOpen" title="{{ $sessionNounTitle }} chat">
|
||||
<div class="meet-room-panels-stack max-sm:contents"
|
||||
:class="sidebarPanel ? 'is-open' : ''">
|
||||
<div x-show="sidebarPanel" x-cloak
|
||||
class="meet-room-panel__backdrop fixed inset-0 z-40 sm:hidden"
|
||||
@click="closeSidebar()"
|
||||
aria-hidden="true"></div>
|
||||
|
||||
<x-meet.room.panel show="sidebarPanel === 'chat'" title="{{ $sessionNounTitle }} chat">
|
||||
<x-slot:subtitle>
|
||||
<p>Messages are visible to everyone in the call</p>
|
||||
</x-slot:subtitle>
|
||||
@@ -473,7 +506,7 @@
|
||||
</div>
|
||||
</x-meet.room.panel>
|
||||
|
||||
<x-meet.room.panel show="programmeOpen" title="Programme">
|
||||
<x-meet.room.panel show="sidebarPanel === 'programme'" title="Programme">
|
||||
<x-slot:subtitle>
|
||||
<p>Lineup from Events when linked to this {{ $sessionNoun }}</p>
|
||||
</x-slot:subtitle>
|
||||
@@ -487,7 +520,7 @@
|
||||
</div>
|
||||
</x-meet.room.panel>
|
||||
|
||||
<x-meet.room.panel show="participantsOpen" :title="null">
|
||||
<x-meet.room.panel show="sidebarPanel === 'participants'" :title="null">
|
||||
<x-slot:subtitle>
|
||||
<template x-if="usesStageLayout">
|
||||
<div>
|
||||
@@ -670,7 +703,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-meet.room.panel show="featuresOpen" title="More options">
|
||||
<x-meet.room.panel show="sidebarPanel === 'features'" title="More options">
|
||||
<x-slot:subtitle>
|
||||
<p>{{ $sessionNounTitle }} tools and extras</p>
|
||||
</x-slot:subtitle>
|
||||
@@ -679,23 +712,23 @@
|
||||
<div class="space-y-1">
|
||||
<div class="space-y-1 sm:hidden" x-show="canPublish">
|
||||
<x-meet.room.menu-item icon="raise-hand" title="Raise hand" subtitle="Let the host know you have a question"
|
||||
@click="raiseHand(); featuresOpen = false" />
|
||||
@click="raiseHand(); closeSidebar()" />
|
||||
<x-meet.room.menu-item icon="applause" title="Applause" subtitle="Send applause — sound plays when others join in"
|
||||
@click="sendReaction('thumbs'); featuresOpen = false" />
|
||||
@click="sendReaction('thumbs'); closeSidebar()" />
|
||||
<x-meet.room.menu-item icon="react" title="React" subtitle="Send a heart to the room"
|
||||
@click="sendReaction('heart'); featuresOpen = false" />
|
||||
@click="sendReaction('heart'); closeSidebar()" />
|
||||
<x-meet.room.menu-item icon="chat" title="Chat" subtitle="Open the {{ $sessionNoun }} chat"
|
||||
@click="toggleChat(); featuresOpen = false" />
|
||||
@click="toggleChat()" />
|
||||
<div class="my-1 border-t border-slate-800"></div>
|
||||
</div>
|
||||
<div class="space-y-1 sm:hidden" x-show="!canPublish">
|
||||
<x-meet.room.menu-item icon="chat" title="Chat" subtitle="Open the {{ $sessionNoun }} chat"
|
||||
@click="toggleChat(); featuresOpen = false" />
|
||||
@click="toggleChat()" />
|
||||
<div class="my-1 border-t border-slate-800"></div>
|
||||
</div>
|
||||
|
||||
<x-meet.room.menu-item icon="programme" title="Programme" :subtitle="'View the '.$sessionNoun.' lineup from Events'"
|
||||
@click="toggleProgramme(); featuresOpen = false" />
|
||||
@click="toggleProgramme()" />
|
||||
|
||||
<button @click="openUploadPicker()" type="button"
|
||||
class="flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left text-sm text-slate-200 transition-colors hover:bg-slate-800">
|
||||
@@ -772,5 +805,6 @@
|
||||
</div>
|
||||
</x-meet.room.panel>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user