Deploy Ladill Meet / deploy (push) Successful in 2m44s
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.
143 lines
3.3 KiB
JavaScript
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();
|