Fix PCI Stripe e anteprima regia; checkout sempre hosted.

Blocca l'invio di numeri carta dall'API server, usa Checkout anche per i cambi piano e nasconde correttamente il placeholder video in regia.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 08:00:28 +02:00
parent f4b7be0f80
commit 148402a97c
12 changed files with 294 additions and 50 deletions

View File

@@ -35,6 +35,7 @@
let pendingAction = null;
let hls = null;
let previewStarted = false;
function toast(msg) {
els.toast.textContent = msg;
@@ -156,6 +157,22 @@
});
});
function syncPreviewFromStatus(data) {
if (data.stream_closed) {
cfg.streamClosed = true;
stopPreview();
return;
}
if (data.on_air) {
if (!previewStarted) startPreview();
else if (els.preview && els.preview.readyState >= 2) hidePreviewPlaceholder();
} else {
destroyPreview();
showPreviewPlaceholder("Anteprima in attesa del segnale…");
}
}
async function pollStatus() {
try {
const res = await fetch(cfg.statusUrl, { headers: { Accept: "application/json" } });
@@ -163,38 +180,52 @@
const data = await res.json();
applyScorePayload(data);
setBadge(data);
if (data.stream_closed) {
cfg.streamClosed = true;
stopPreview();
}
syncPreviewFromStatus(data);
} catch (_) {}
}
function initPreview() {
if (cfg.streamClosed || !els.preview || !cfg.hlsUrl) return;
if (els.preview.canPlayType("application/vnd.apple.mpegurl")) {
els.preview.src = cfg.hlsUrl;
} else if (window.Hls && Hls.isSupported()) {
hls = new Hls({ maxBufferLength: 8 });
hls.loadSource(cfg.hlsUrl);
hls.attachMedia(els.preview);
}
els.preview.addEventListener("playing", () => {
if (els.previewPlaceholder) els.previewPlaceholder.hidden = true;
function bindPreviewEvents() {
if (!els.preview) return;
["playing", "loadeddata", "canplay"].forEach((ev) => {
els.preview.addEventListener(ev, hidePreviewPlaceholder);
});
}
function startPreview() {
if (cfg.streamClosed || !els.preview || !cfg.hlsUrl || previewStarted) return;
previewStarted = true;
const url = hlsUrlFresh();
if (window.Hls && Hls.isSupported()) {
hls = new Hls({ lowLatencyMode: true, maxBufferLength: 8 });
hls.loadSource(url);
hls.attachMedia(els.preview);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
els.preview.play().catch(() => {});
});
hls.on(Hls.Events.ERROR, (_, err) => {
if (err.fatal) {
destroyPreview();
setTimeout(() => {
if (!cfg.streamClosed) startPreview();
}, 2500);
}
});
} else if (els.preview.canPlayType("application/vnd.apple.mpegurl")) {
els.preview.src = url;
els.preview.addEventListener(
"loadedmetadata",
() => els.preview.play().catch(() => {}),
{ once: true }
);
}
}
function stopPreview() {
if (hls) {
hls.destroy();
hls = null;
}
if (els.preview) els.preview.remove();
if (els.previewPlaceholder) {
els.previewPlaceholder.hidden = false;
els.previewPlaceholder.textContent = "Diretta terminata";
}
destroyPreview();
if (els.preview) els.preview.style.display = "none";
showPreviewPlaceholder("Diretta terminata");
}
async function pauseStream() {
@@ -246,7 +277,11 @@
document.getElementById("btn-share")?.addEventListener("click", () => shareLink());
document.getElementById("btn-copy")?.addEventListener("click", () => copyLink());
initPreview();
bindPreviewEvents();
if (!cfg.streamClosed && cfg.hlsUrl) {
pollStatus();
} else if (cfg.streamClosed) {
stopPreview();
}
setInterval(pollStatus, 4000);
pollStatus();
})();