From 64abb494d54c8da0c39a42576a3b3b29d8a8fa1b Mon Sep 17 00:00:00 2001 From: Dorian Date: Thu, 19 Mar 2026 14:52:16 +0000 Subject: [PATCH] fix: iframe auto-retry for apps still starting + retry button Co-Authored-By: Claude Opus 4.6 (1M context) --- neode-ui/src/views/AppSession.vue | 45 ++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/neode-ui/src/views/AppSession.vue b/neode-ui/src/views/AppSession.vue index 766cd403..b0d64ed5 100644 --- a/neode-ui/src/views/AppSession.vue +++ b/neode-ui/src/views/AppSession.vue @@ -142,17 +142,29 @@

{{ mustOpenNewTab ? 'This app opens in a new tab' : 'App not reachable' }}

- +

- +
+ + +
@@ -211,7 +223,9 @@ const iframeBlocked = ref(false) const refreshKey = ref(0) const showIdentityPicker = ref(false) const showModeMenu = ref(false) +const autoRetryCount = ref(0) let loadTimeoutId: ReturnType | null = null +let autoRetryId: ReturnType | null = null /** Sites known to block iframes — skip the timeout and go straight to fallback */ const IFRAME_BLOCKED_APPS = new Set([]) @@ -483,8 +497,10 @@ async function sendIdentity(identity: SelectedIdentity) { function onLoad() { if (loadTimeoutId) { clearTimeout(loadTimeoutId); loadTimeoutId = null } + if (autoRetryId) { clearTimeout(autoRetryId); autoRetryId = null } loading.value = false isRefreshing.value = false + autoRetryCount.value = 0 // Check if iframe actually loaded content (same-origin only) setTimeout(() => { try { @@ -511,9 +527,17 @@ function onError() { loading.value = false isRefreshing.value = false iframeBlocked.value = true + // Auto-retry up to 6 times (60s total) for apps that are still starting + if (!mustOpenNewTab.value && autoRetryCount.value < 6) { + autoRetryId = setTimeout(() => { + autoRetryCount.value++ + refresh() + }, 10000) + } } function refresh() { + if (autoRetryId) { clearTimeout(autoRetryId); autoRetryId = null } isRefreshing.value = true loading.value = true iframeBlocked.value = false @@ -672,6 +696,7 @@ onMounted(() => { onBeforeUnmount(() => { if (loadTimeoutId) clearTimeout(loadTimeoutId) + if (autoRetryId) clearTimeout(autoRetryId) window.removeEventListener('keydown', onKeyDown, true) window.removeEventListener('message', onMessage) document.removeEventListener('click', onClickOutside)