@@ -109,6 +109,7 @@ export function PreviewPanel({
109109 )
110110 const [ hasTriggeredScreenshots , setHasTriggeredScreenshots ] = useState ( false )
111111 const screenshotTimeoutRef = useRef < ReturnType < typeof setTimeout > | null > ( null )
112+ const screenshotRetryRef = useRef < ReturnType < typeof setTimeout > | null > ( null )
112113 const { Canvas } = useQRCode ( )
113114
114115 // Track if user has seen Expo Go modal
@@ -393,36 +394,59 @@ export function PreviewPanel({
393394 const projectId = currentProject . id
394395 const currentUserId = userId
395396
396- screenshotTimeoutRef . current = setTimeout ( async ( ) => {
397+ const triggerScreenshots = async ( ) => {
397398 console . log ( '[PreviewPanel] Triggering automatic screenshot capture for project:' , projectId )
398399
399400 try {
400401 const response = await fetch ( `/api/projects/${ projectId } /screenshots` , {
401402 method : 'POST' ,
402- headers : {
403- 'Content-Type' : 'application/json' ,
404- } ,
405- body : JSON . stringify ( {
406- userID : currentUserId ,
407- } ) ,
403+ headers : { 'Content-Type' : 'application/json' } ,
404+ body : JSON . stringify ( { userID : currentUserId } ) ,
408405 } )
409406
410407 if ( response . ok ) {
411408 const data = await response . json ( )
412409 console . log ( '[PreviewPanel] Screenshots captured successfully:' , data . screenshots )
413-
414- // Update current project with new screenshot URLs
415410 if ( data . project && onProjectUpdate ) {
416411 onProjectUpdate ( data . project )
417412 }
413+ return true
418414 } else {
419415 const error = await response . json ( )
420416 console . error ( '[PreviewPanel] Failed to capture screenshots:' , error )
417+ return false
421418 }
422419 } catch ( error ) {
423420 console . error ( '[PreviewPanel] Error triggering screenshots:' , error )
424- } finally {
425- screenshotTimeoutRef . current = null
421+ return false
422+ }
423+ }
424+
425+ screenshotTimeoutRef . current = setTimeout ( async ( ) => {
426+ const success = await triggerScreenshots ( )
427+ screenshotTimeoutRef . current = null
428+
429+ if ( ! success ) {
430+ // Schedule a retry in 120 seconds: first check DB, only retry if still missing
431+ console . log ( '[PreviewPanel] Screenshot failed, scheduling retry in 120 seconds...' )
432+ screenshotRetryRef . current = setTimeout ( async ( ) => {
433+ screenshotRetryRef . current = null
434+ try {
435+ const check = await fetch ( `/api/projects/${ projectId } /public` )
436+ if ( check . ok ) {
437+ const data = await check . json ( )
438+ if ( data . screenshotMobile && data . screenshotDesktop ) {
439+ console . log ( '[PreviewPanel] Screenshots already saved, skipping retry' )
440+ if ( onProjectUpdate ) onProjectUpdate ( data )
441+ return
442+ }
443+ }
444+ } catch {
445+ // If check fails, attempt the retry anyway
446+ }
447+ console . log ( '[PreviewPanel] Screenshots still missing, retrying...' )
448+ await triggerScreenshots ( )
449+ } , 120000 )
426450 }
427451 } , 60000 ) // 60 seconds - wait for app to fully initialize
428452 }
@@ -435,6 +459,10 @@ export function PreviewPanel({
435459 clearTimeout ( screenshotTimeoutRef . current )
436460 screenshotTimeoutRef . current = null
437461 }
462+ if ( screenshotRetryRef . current ) {
463+ clearTimeout ( screenshotRetryRef . current )
464+ screenshotRetryRef . current = null
465+ }
438466 }
439467 } , [ ] )
440468
0 commit comments