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