From dec1e455aeed47b80ae020b89b1f9aac7247216c Mon Sep 17 00:00:00 2001 From: iamjr15 Date: Fri, 24 Jul 2026 16:58:27 +0530 Subject: [PATCH] fix(files): refresh preview handoff on open Mount Files only while Computer is active and discard its short-lived IDE capability on close. Reopening now obtains a fresh handoff instead of replaying an expired URL. --- .../components/home/home-computer-pane.tsx | 25 +++++++++++-- .../components/preview/sandbox-ide-tab.tsx | 37 +++++++++++-------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/apps/web/src/components/home/home-computer-pane.tsx b/apps/web/src/components/home/home-computer-pane.tsx index 3a3f328b..3602a52e 100644 --- a/apps/web/src/components/home/home-computer-pane.tsx +++ b/apps/web/src/components/home/home-computer-pane.tsx @@ -54,17 +54,24 @@ function HomeComputerAside({ className={homeComputerClass(computerOpen)} inert={computerOpen ? undefined : true} > - + ); } function HomeComputerBody({ activeTab, + computerOpen, onClose, setActiveTab, }: { activeTab: PreviewTab; + computerOpen: boolean; onClose: () => void; setActiveTab: (tab: PreviewTab) => void; }) { @@ -85,17 +92,27 @@ function HomeComputerBody({ activeTab === "files" ? : null } > - + ); } -function HomeComputerTabContent({ activeTab }: { activeTab: PreviewTab }) { +function HomeComputerTabContent({ + activeTab, + computerOpen, +}: { + activeTab: PreviewTab; + computerOpen: boolean; +}) { return (
- + diff --git a/apps/web/src/components/preview/sandbox-ide-tab.tsx b/apps/web/src/components/preview/sandbox-ide-tab.tsx index 971322bf..54d51efd 100644 --- a/apps/web/src/components/preview/sandbox-ide-tab.tsx +++ b/apps/web/src/components/preview/sandbox-ide-tab.tsx @@ -43,11 +43,24 @@ export function SandboxIdeTab({ active: boolean; previewReloadToken: number; threadId: string | null; +}) { + if (!active) { + return null; + } + return ; +} + +function ActiveSandboxIdeTab({ + previewReloadToken, + threadId, +}: { + previewReloadToken: number; + threadId: string | null; }) { const { getToken } = useAuth(); const { resolvedTheme } = useTheme(); const [frameReloadToken, setFrameReloadToken] = useState(0); - const ideQuery = useSandboxIdeQuery(active, threadId, getToken); + const ideQuery = useSandboxIdeQuery(threadId, getToken); const requestedIframeUrl = ideQuery.data ? codeServerIframeUrl( ideQuery.data.url, @@ -57,7 +70,7 @@ export function SandboxIdeTab({ ) : null; const iframeUrl = useStablePreviewSource(requestedIframeUrl); - const bridge = useCodeServerBridge(active, iframeUrl, threadId); + const bridge = useCodeServerBridge(iframeUrl, threadId); const refetchSession = () => void ideQuery.refetch(); const reloadFrame = () => setFrameReloadToken((current) => current + 1); return ( @@ -72,14 +85,10 @@ export function SandboxIdeTab({ ); } -function useSandboxIdeQuery( - active: boolean, - threadId: string | null, - getToken: () => Promise, -) { +function useSandboxIdeQuery(threadId: string | null, getToken: () => Promise) { // Files resolves either the per-user computer root or the active project folder. return useQuery({ - enabled: active, + gcTime: 0, queryFn: ({ signal }) => threadId === null ? openComputerIde(getToken, signal) @@ -90,7 +99,7 @@ function useSandboxIdeQuery( refetchIntervalInBackground: false, refetchOnWindowFocus: false, retry: 1, - staleTime: 40 * 60 * 1000, + staleTime: 0, }); } @@ -192,7 +201,7 @@ function SandboxIdeFrame({ ); } -function useCodeServerBridge(active: boolean, iframeUrl: string | null, threadId: string | null) { +function useCodeServerBridge(iframeUrl: string | null, threadId: string | null) { const iframeRef = useRef(null); const [readyIframeUrl, setReadyIframeUrl] = useState(null); const [timedOutIframeUrl, setTimedOutIframeUrl] = useState(null); @@ -216,7 +225,6 @@ function useCodeServerBridge(active: boolean, iframeUrl: string | null, threadId const isReady = iframeUrl !== null && readyIframeUrl === iframeUrl; const requestReadyState = () => requestCodeServerState(iframeOrigin, iframeRef); useCodeServerHandshake({ - active, iframeOrigin, iframeRef, iframeUrl, @@ -241,16 +249,15 @@ function useCodeServerBridge(active: boolean, iframeUrl: string | null, threadId } function useCodeServerHandshake(input: { - active: boolean; iframeOrigin: string | null; iframeRef: RefObject; iframeUrl: string | null; isReady: boolean; setTimedOutIframeUrl: (iframeUrl: string | null) => void; }): void { - const { active, iframeOrigin, iframeRef, iframeUrl, isReady, setTimedOutIframeUrl } = input; + const { iframeOrigin, iframeRef, iframeUrl, isReady, setTimedOutIframeUrl } = input; useEffect(() => { - if (!active || !iframeOrigin || !iframeUrl || isReady) return; + if (!iframeOrigin || !iframeUrl || isReady) return; setTimedOutIframeUrl(null); requestCodeServerState(iframeOrigin, iframeRef); const interval = window.setInterval( @@ -265,7 +272,7 @@ function useCodeServerHandshake(input: { window.clearInterval(interval); window.clearTimeout(timeout); }; - }, [active, iframeOrigin, iframeRef, iframeUrl, isReady, setTimedOutIframeUrl]); + }, [iframeOrigin, iframeRef, iframeUrl, isReady, setTimedOutIframeUrl]); } function requestCodeServerState(