File size: 2,836 Bytes
31eb5de
 
ad31128
31eb5de
 
 
 
 
 
 
ad31128
 
31eb5de
 
ad31128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31eb5de
 
ad31128
31eb5de
ad31128
 
 
 
 
 
 
31eb5de
 
ad31128
 
 
 
 
 
 
31eb5de
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use client'

import React, { useEffect, useRef, useState } from 'react'

interface DartPadEmbedProps {
    code: string
    theme?: 'light' | 'dark'
}

export function DartPadEmbed({ code, theme = 'light' }: DartPadEmbedProps) {
    const containerRef = useRef<HTMLDivElement>(null)
    const [isLoaded, setIsLoaded] = useState(false)

    useEffect(() => {
        if (!containerRef.current) return

        // Create a unique ID for this instance
        const embedId = `dartpad-${Date.now()}`

        // Create the container for DartPad with the code
        const embedContainer = document.createElement('div')
        embedContainer.id = embedId
        embedContainer.style.width = '100%'
        embedContainer.style.height = '100%'

        // Clear the container and add the new element
        containerRef.current.innerHTML = ''
        containerRef.current.appendChild(embedContainer)

        // Use iframe with postMessage to inject code and run it
        const iframe = document.createElement('iframe')
        iframe.src = `https://dartpad.dev/embed-flutter.html?theme=${theme}&run=true`
        iframe.style.width = '100%'
        iframe.style.height = '100%'
        iframe.style.border = 'none'

        // Listen for iframe load and inject the code
        iframe.onload = () => {
            setIsLoaded(true)

            // Wait a bit for DartPad to fully initialize
            setTimeout(() => {
                // Try to inject the code using postMessage
                try {
                    // DartPad listens for messages to update code
                    iframe.contentWindow?.postMessage({
                        type: 'sourceCode',
                        sourceCode: {
                            main: code
                        }
                    }, '*')

                    // Auto-run the code after a short delay
                    setTimeout(() => {
                        iframe.contentWindow?.postMessage({
                            type: 'execute'
                        }, '*')
                    }, 500)
                } catch (error) {
                    console.error('Failed to inject code:', error)
                }
            }, 1000)
        }

        embedContainer.appendChild(iframe)

        return () => {
            // Cleanup
            if (containerRef.current) {
                containerRef.current.innerHTML = ''
            }
        }
    }, [code, theme])

    return (
        <div className="w-full h-full relative">
            {!isLoaded && (
                <div className="absolute inset-0 flex items-center justify-center bg-gray-900">
                    <div className="text-white">Loading DartPad...</div>
                </div>
            )}
            <div ref={containerRef} className="w-full h-full" />
        </div>
    )
}