@@ -70,8 +70,8 @@ const ErrorStateView = memo(({ errorMsg }: { errorMsg: string }) => {
7070 < div className = "flex flex-col gap-3" >
7171 < h2 className = "text-2xl font-semibold text-error" > Secrets Required</ h2 >
7272 < p className = "text-base text-secondary leading-relaxed" >
73- This app requires secrets that must be configured. Please use the Secrets tab to set and bind
74- the required secrets for your app to run.
73+ This app requires secrets that must be configured. Please use the Secrets tab to set and
74+ bind the required secrets for your app to run.
7575 </ p >
7676 < div className = "text-left bg-panel border border-error/30 rounded-lg p-4 max-h-96 overflow-auto mt-2" >
7777 < pre className = "text-sm text-secondary whitespace-pre-wrap font-mono" > { displayMsg } </ pre >
@@ -178,47 +178,48 @@ const BuilderPreviewTab = memo(() => {
178178 const originalContent = useAtomValue ( model . originalContentAtom ) ;
179179 const builderStatus = useAtomValue ( model . builderStatusAtom ) ;
180180 const builderId = useAtomValue ( atoms . builderId ) ;
181-
182181 const fileExists = originalContent . length > 0 ;
183-
184- if ( isLoading ) {
185- return null ;
186- }
187-
188- if ( builderStatus ?. status === "error" ) {
189- return < ErrorStateView errorMsg = { builderStatus ?. errormsg || "" } /> ;
190- }
191-
192- if ( ! fileExists ) {
193- return < EmptyStateView /> ;
194- }
182+ const [ lastKnownUrl , setLastKnownUrl ] = useState < string > ( null ) ;
195183
196184 const status = builderStatus ?. status || "init" ;
185+ const isWebViewActive = status === "running" && builderStatus ?. port && builderStatus . port !== 0 ;
197186
198- if ( status === "init" ) {
199- return null ;
200- }
201-
202- if ( status === "building" ) {
203- return < BuildingStateView /> ;
204- }
205-
206- if ( status === "stopped" ) {
207- return < StoppedStateView onStart = { ( ) => model . startBuilder ( ) } /> ;
187+ if ( isWebViewActive ) {
188+ const previewUrl = `http://localhost:${ builderStatus . port } /?clientid=wave:${ builderId } ` ;
189+ if ( previewUrl !== lastKnownUrl ) {
190+ setLastKnownUrl ( previewUrl ) ;
191+ }
208192 }
209193
210- const shouldShowWebView = status === "running" && builderStatus ?. port && builderStatus . port !== 0 ;
211-
212- if ( shouldShowWebView ) {
213- const previewUrl = `http://localhost:${ builderStatus . port } /?clientid=wave:${ builderId } ` ;
214- return (
215- < div className = "w-full h-full" >
216- < webview src = { previewUrl } className = "w-full h-full" />
217- </ div >
218- ) ;
194+ let overlay = null ;
195+ if ( ! isLoading && ! isWebViewActive ) {
196+ if ( builderStatus ?. status === "error" ) {
197+ overlay = < ErrorStateView errorMsg = { builderStatus ?. errormsg || "" } /> ;
198+ } else if ( ! fileExists || status === "init" ) {
199+ overlay = < EmptyStateView /> ;
200+ } else if ( status === "building" ) {
201+ overlay = < BuildingStateView /> ;
202+ } else if ( status === "stopped" ) {
203+ overlay = < StoppedStateView onStart = { ( ) => model . startBuilder ( ) } /> ;
204+ }
219205 }
220206
221- return null ;
207+ return (
208+ < div className = "w-full h-full relative" >
209+ { lastKnownUrl && (
210+ < webview
211+ ref = { model . webviewRef }
212+ src = { lastKnownUrl }
213+ className = "w-full h-full"
214+ style = { {
215+ visibility : isWebViewActive ? "visible" : "hidden" ,
216+ pointerEvents : isWebViewActive ? "auto" : "none" ,
217+ } }
218+ />
219+ ) }
220+ { overlay && < div className = "absolute inset-0" > { overlay } </ div > }
221+ </ div >
222+ ) ;
222223} ) ;
223224
224225BuilderPreviewTab . displayName = "BuilderPreviewTab" ;
0 commit comments