diff --git a/site/blueprints/blocks/jeu.yml b/site/blueprints/blocks/jeu.yml
new file mode 100644
index 0000000..9a2d331
--- /dev/null
+++ b/site/blueprints/blocks/jeu.yml
@@ -0,0 +1,9 @@
+name: Jeu (iframe)
+icon: preview
+
+fields:
+ url:
+ label: URL de l'iframe
+ type: url
+ required: true
+ help: "URL complète de l'iframe (ex: https://impact.games/...)"
diff --git a/site/snippets/blocks/jeu.php b/site/snippets/blocks/jeu.php
new file mode 100644
index 0000000..a8f52c7
--- /dev/null
+++ b/site/snippets/blocks/jeu.php
@@ -0,0 +1,19 @@
+url()->isNotEmpty()): ?>
+
+
+
+
+
▶
+
Cliquez pour jouer
+
+
+
+
+
diff --git a/src/views/Article.svelte b/src/views/Article.svelte
index 5248d9c..1af731d 100644
--- a/src/views/Article.svelte
+++ b/src/views/Article.svelte
@@ -5,6 +5,7 @@
*/
import { t } from '@i18n'
+ import { onMount } from 'svelte'
import Footer from '@components/layout/Footer.svelte'
let { data, onBack } = $props()
@@ -12,6 +13,64 @@
let copySuccess = $state(false)
let copyTimer = null
+ // Setup click-to-play iframes après le rendu du body HTML
+ $effect(() => {
+ if (!data.body) return
+
+ const timer = setTimeout(() => {
+ document.querySelectorAll('.iframe-game-container').forEach(container => {
+ if (container.dataset.initialized) return
+ container.dataset.initialized = 'true'
+
+ const overlay = container.querySelector('.iframe-click-overlay')
+ const iframe = container.querySelector('iframe')
+ const deactivateBtn = container.querySelector('.iframe-deactivate-btn')
+
+ overlay?.addEventListener('click', () => {
+ overlay.style.display = 'none'
+ iframe.style.pointerEvents = 'auto'
+ container.classList.add('game-active')
+ overlay.setAttribute('data-state', 'played')
+ })
+
+ deactivateBtn?.addEventListener('click', (e) => {
+ e.stopPropagation()
+ overlay.style.display = 'flex'
+ iframe.style.pointerEvents = 'none'
+ container.classList.remove('game-active')
+ })
+ })
+ }, 300)
+
+ return () => clearTimeout(timer)
+ })
+
+ // Écoute les messages postMessage depuis l'iframe du jeu
+ onMount(() => {
+ const handleIframeMessage = (event) => {
+ if (!event.origin.includes('impact.games')) return
+ if (event.data.type !== 'GameReleaseFocus') return
+
+ document.querySelectorAll('.iframe-click-overlay').forEach(overlay => {
+ if (overlay.getAttribute('data-state') === 'played') {
+ overlay.setAttribute('data-state', 'ended')
+ overlay.innerHTML = ''
+ overlay.style.cursor = 'default'
+ overlay.style.pointerEvents = 'none'
+ }
+ overlay.style.display = 'flex'
+ })
+
+ document.querySelectorAll('.iframe-game-container').forEach(container => {
+ container.querySelector('iframe').style.pointerEvents = 'none'
+ container.classList.remove('game-active')
+ })
+ }
+
+ window.addEventListener('message', handleIframeMessage)
+ return () => window.removeEventListener('message', handleIframeMessage)
+ })
+
function copyLink() {
navigator.clipboard.writeText(window.location.href)
copySuccess = true