// ---------- Action "video" — lecture d'une vidéo de "Mes assets" ---------- // Voir screens/rendering/collision_rules.py::"video" — bloque la suite de // la chaîne "then" jusqu'à la fin de la vidéo (ou un clic sur "Passer"), // même esprit qu'un dialogue (voir dialogue-box-controller.js). Un seul // overlay posé sur
, réutilisé pour chaque lecture (pas la peine // d'en recréer un par appel). var forgeVideoOverlayEl = null; function forgeVideoOverlayRoot() { if (forgeVideoOverlayEl) return forgeVideoOverlayEl; var el = document.createElement('div'); el.className = 'forgeVideoOverlay'; el.innerHTML = '' + ''; document.body.appendChild(el); forgeVideoOverlayEl = el; return el; } // `onDone` : appelé une fois (fin naturelle OU "Passer") — jamais les // deux, `finished` protège contre un double appel (l'événement 'ended' // pouvant encore se déclencher juste après un clic sur "Passer"). function forgeShowVideoOverlay(url, mode, onDone) { if (!url) { if (onDone) onDone(); return; } var root = forgeVideoOverlayRoot(); root.className = 'forgeVideoOverlay ' + (mode === 'incrustation' ? 'forgeVideoOverlay-incrustation' : 'forgeVideoOverlay-pleinEcran'); root.style.display = 'flex'; var player = root.querySelector('.forgeVideoOverlayPlayer'); var skipBtn = root.querySelector('.forgeVideoOverlaySkip'); var finished = false; function finish() { if (finished) return; finished = true; root.style.display = 'none'; player.pause(); player.removeAttribute('src'); player.onended = null; skipBtn.onclick = null; if (onDone) onDone(); } player.src = url; player.onended = finish; skipBtn.onclick = finish; player.play().catch(function () {}); // lecture bloquée par le navigateur (pas d'interaction récente) : reste affichée, "Passer" fonctionne toujours. } // static/js/play/__tests__/ (node:test) — même garde que le reste de // static/js/play/. if (typeof module !== 'undefined' && module.exports) { module.exports = { forgeShowVideoOverlay }; }