From fecdd87b3dc3e610a95c2c9c1af832f35306f484 Mon Sep 17 00:00:00 2001 From: MrViSiOn <> Date: Tue, 19 May 2026 13:16:11 +0200 Subject: [PATCH 1/2] fix(dashboard): show QR loading state immediately and keep polling until ready MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Chromium is still initializing, getQR returns an error before the QR is available. The previous code caught that error, set a global error banner, and stopped — leaving the user with no way to scan without manually retrying. This fix opens the QR modal in a loading state as soon as the user triggers Reconnect/Start, so the existing 5-second polling interval starts immediately. The interval now keeps running on transient errors (QR not ready yet) and only stops when the session itself reaches a terminal state (failed/disconnected) or when the QR is successfully scanned (status: ready). --- dashboard/src/pages/Sessions.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/dashboard/src/pages/Sessions.tsx b/dashboard/src/pages/Sessions.tsx index ac448e5..f63c60f 100644 --- a/dashboard/src/pages/Sessions.tsx +++ b/dashboard/src/pages/Sessions.tsx @@ -72,9 +72,14 @@ export function Sessions() { fetchSessions(); } } catch { - setQrData(null); - currentSessionName.current = ''; - fetchSessions(); + // Keep qrData alive so the polling interval keeps retrying until the QR + // is ready. Only stop polling if the session itself has failed. + const currentSession = await sessionApi.get(sessionId).catch(() => null); + if (!currentSession || currentSession.status === 'failed' || currentSession.status === 'disconnected') { + setQrData(null); + currentSessionName.current = ''; + fetchSessions(); + } } }, []); @@ -150,12 +155,17 @@ export function Sessions() { const handleShowQR = async (id: string) => { const session = sessions.find(s => s.id === id); const sessionName = session?.name || ''; + // Show loading state immediately so the modal opens and polling starts + // even before Chromium has finished initializing. + setQrData({ sessionId: id, sessionName, qrCode: '' }); + currentSessionName.current = sessionName; try { const qr = await sessionApi.getQR(id); setQrData({ sessionId: id, sessionName, qrCode: qr.qrCode }); } catch (err) { console.error('Failed to get QR:', err); - setError(t('sessions.qr.unavailable')); + // Do not clear qrData here — keep the loading modal open so the + // polling interval (every 5 s) retries until the QR becomes available. } }; From 5a1d966356ff17c7ee79d21628f056c079ad3ac1 Mon Sep 17 00:00:00 2001 From: MrViSiOn <> Date: Tue, 19 May 2026 13:33:01 +0200 Subject: [PATCH 2/2] fix: replace 'failed' status with type-safe initializing check --- dashboard/src/pages/Sessions.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dashboard/src/pages/Sessions.tsx b/dashboard/src/pages/Sessions.tsx index f63c60f..db2a001 100644 --- a/dashboard/src/pages/Sessions.tsx +++ b/dashboard/src/pages/Sessions.tsx @@ -75,7 +75,9 @@ export function Sessions() { // Keep qrData alive so the polling interval keeps retrying until the QR // is ready. Only stop polling if the session itself has failed. const currentSession = await sessionApi.get(sessionId).catch(() => null); - if (!currentSession || currentSession.status === 'failed' || currentSession.status === 'disconnected') { + const stillInitializing = currentSession && + ['initializing', 'connecting', 'qr_ready'].includes(currentSession.status); + if (!stillInitializing) { setQrData(null); currentSessionName.current = ''; fetchSessions();