Tesseract / studio /src /components /PreviewFrame.jsx
rkbosamia's picture
Tesseract major version upgrade - v2
9c49532
Raw
History Blame Contribute Delete
2.28 kB
import { useEffect, useRef, useState } from 'react'
import useAppStore from '../store/appStore'
export default function PreviewFrame({ url }) {
// The TopBar Reload button bumps runtime.iframeKey in the store. Without
// reading it here, clicks did nothing — local key only changed on URL flip.
const storeKey = useAppStore((s) => s.runtime.iframeKey)
const [iframeKey, setIframeKey] = useState(0)
const [loaded, setLoaded] = useState(false)
const urlRef = useRef(url)
// Force a fresh iframe load on URL change OR external reload request.
useEffect(() => {
setLoaded(false)
setIframeKey((k) => k + 1)
urlRef.current = url
}, [url, storeKey])
if (!url) {
return (
<div
style={{
height: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
color: 'var(--text-faint)',
fontFamily: 'system-ui, sans-serif',
fontSize: 13,
background: 'var(--bg)',
}}
>
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round" style={{ opacity: 0.4 }}>
<polygon points="5 3 19 12 5 21 5 3" />
</svg>
<span style={{ opacity: 0.6 }}>Click Run to start the dev servers</span>
</div>
)
}
return (
<div style={{ position: 'relative', height: '100%', background: '#fff' }}>
<iframe
key={iframeKey}
src={url}
title="App preview"
style={{ width: '100%', height: '100%', border: 'none', display: 'block' }}
sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-pointer-lock"
onLoad={() => setLoaded(true)}
/>
{!loaded && (
<div
style={{
position: 'absolute',
inset: 0,
background: '#fff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#9ca3af',
fontSize: 13,
fontFamily: 'system-ui, sans-serif',
}}
>
Connecting to dev server…
</div>
)}
</div>
)
}