Files
ladill-meet/resources/js/meet-public.js
T
isaacclad 86fa37b9fd
Deploy Ladill Meet / deploy (push) Successful in 2m44s
Reduce Meet poll load with shared cache, ETag, and slower clients.
Heavy per-participant poll queries were saturating the shared host during
live rooms. Cache the shared room payload for 2s, return 304 when unchanged,
throttle breakout expiry and captions, and slow client polling (6s / 20s
when hidden) so concurrent attendees no longer fan out full Laravel work.
2026-07-15 19:59:52 +00:00

143 lines
3.3 KiB
JavaScript

import Alpine from 'alpinejs';
Alpine.data('waitingRoom', () => ({
message: 'Waiting for the host to let you in…',
denied: false,
pollTimer: null,
init() {
this.pollTimer = setInterval(() => this.poll(), 5000);
this.poll();
},
destroy() {
if (this.pollTimer) {
clearInterval(this.pollTimer);
}
},
async poll() {
const url = this.$el.dataset.statusUrl;
if (!url) return;
try {
const res = await fetch(url, { headers: { Accept: 'application/json' } });
const data = await res.json();
if (data.ended && data.redirect) {
window.location.href = data.redirect;
return;
}
if (data.redirect) {
window.location.href = data.redirect;
return;
}
if (data.denied) {
this.denied = true;
this.message = 'The host declined your request to join.';
clearInterval(this.pollTimer);
}
} catch {
// ignore transient errors
}
},
}));
Alpine.data('leaveFeedback', () => ({
rating: 0,
audioRating: 0,
videoRating: 0,
hoverRating: 0,
hoverAudio: 0,
hoverVideo: 0,
comment: '',
setRating(value) {
this.rating = value;
},
setAudioRating(value) {
this.audioRating = value;
},
setVideoRating(value) {
this.videoRating = value;
},
canSubmit() {
return this.rating > 0;
},
}));
Alpine.data('meetBadgeScanner', () => ({
scanning: false,
scanError: '',
scanner: null,
toggle() {
if (this.scanning) {
this.stop();
return;
}
this.scanning = true;
this.scanError = '';
this.$nextTick(() => this.start());
},
start() {
if (typeof Html5Qrcode === 'undefined') {
this.scanError = 'QR scanner could not load. Enter your badge code manually.';
this.scanning = false;
return;
}
const el = document.getElementById('meet-badge-qr-reader');
if (!el) {
return;
}
this.scanner = new Html5Qrcode('meet-badge-qr-reader');
this.scanner.start(
{ facingMode: 'environment' },
{ fps: 10, qrbox: { width: 220, height: 220 } },
(decoded) => {
const code = (decoded || '').trim().toUpperCase();
if (!code) {
return;
}
this.stop();
const input = document.querySelector('input[name="badge_code"]');
if (input) {
input.value = code;
}
input?.closest('form')?.requestSubmit();
},
() => {},
).catch(() => {
this.scanError = 'Camera access was denied or unavailable.';
this.scanning = false;
});
},
stop() {
if (!this.scanner) {
this.scanning = false;
return;
}
this.scanner.stop().catch(() => {}).finally(() => {
this.scanner.clear().catch(() => {});
this.scanner = null;
this.scanning = false;
});
},
}));
window.Alpine = Alpine;
Alpine.start();