Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions apps/web/src/components/home/home-computer-pane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,24 @@ function HomeComputerAside({
className={homeComputerClass(computerOpen)}
inert={computerOpen ? undefined : true}
>
<HomeComputerBody activeTab={activeTab} onClose={onClose} setActiveTab={setActiveTab} />
<HomeComputerBody
activeTab={activeTab}
computerOpen={computerOpen}
onClose={onClose}
setActiveTab={setActiveTab}
/>
</aside>
);
}

function HomeComputerBody({
activeTab,
computerOpen,
onClose,
setActiveTab,
}: {
activeTab: PreviewTab;
computerOpen: boolean;
onClose: () => void;
setActiveTab: (tab: PreviewTab) => void;
}) {
Expand All @@ -85,17 +92,27 @@ function HomeComputerBody({
activeTab === "files" ? <ConsoleStrip sandboxAvailable threadId={null} /> : null
}
>
<HomeComputerTabContent activeTab={activeTab} />
<HomeComputerTabContent activeTab={activeTab} computerOpen={computerOpen} />
</ComputerSurfaceFrame>
</div>
);
}

function HomeComputerTabContent({ activeTab }: { activeTab: PreviewTab }) {
function HomeComputerTabContent({
activeTab,
computerOpen,
}: {
activeTab: PreviewTab;
computerOpen: boolean;
}) {
return (
<div className="h-full min-h-0">
<Activity mode={activeTab === "files" ? "visible" : "hidden"}>
<SandboxIdeTab active previewReloadToken={0} threadId={null} />
<SandboxIdeTab
active={computerOpen && activeTab === "files"}
previewReloadToken={0}
threadId={null}
/>
</Activity>
<Activity mode={activeTab === "app" ? "visible" : "hidden"}>
<HomeBrowserEmpty />
Expand Down
37 changes: 22 additions & 15 deletions apps/web/src/components/preview/sandbox-ide-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,24 @@ export function SandboxIdeTab({
active: boolean;
previewReloadToken: number;
threadId: string | null;
}) {
if (!active) {
return null;
}
return <ActiveSandboxIdeTab previewReloadToken={previewReloadToken} threadId={threadId} />;
}

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,
Expand All @@ -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 (
Expand All @@ -72,14 +85,10 @@ export function SandboxIdeTab({
);
}

function useSandboxIdeQuery(
active: boolean,
threadId: string | null,
getToken: () => Promise<null | string>,
) {
function useSandboxIdeQuery(threadId: string | null, getToken: () => Promise<null | string>) {
// 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)
Expand All @@ -90,7 +99,7 @@ function useSandboxIdeQuery(
refetchIntervalInBackground: false,
refetchOnWindowFocus: false,
retry: 1,
staleTime: 40 * 60 * 1000,
staleTime: 0,
});
}

Expand Down Expand Up @@ -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<HTMLIFrameElement | null>(null);
const [readyIframeUrl, setReadyIframeUrl] = useState<string | null>(null);
const [timedOutIframeUrl, setTimedOutIframeUrl] = useState<string | null>(null);
Expand All @@ -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,
Expand All @@ -241,16 +249,15 @@ function useCodeServerBridge(active: boolean, iframeUrl: string | null, threadId
}

function useCodeServerHandshake(input: {
active: boolean;
iframeOrigin: string | null;
iframeRef: RefObject<HTMLIFrameElement | null>;
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(
Expand All @@ -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(
Expand Down