import React, { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { useSelector } from "react-redux"; import { I18nKey } from "#/i18n/declaration"; import { RootState } from "#/store"; import { RUNTIME_INACTIVE_STATES } from "#/types/agent-state"; import { useVSCodeUrl } from "#/hooks/query/use-vscode-url"; import { VSCODE_IN_NEW_TAB } from "#/utils/feature-flags"; function VSCodeTab() { const { t } = useTranslation(); const { data, isLoading, error } = useVSCodeUrl(); const { curAgentState } = useSelector((state: RootState) => state.agent); const isRuntimeInactive = RUNTIME_INACTIVE_STATES.includes(curAgentState); const iframeRef = React.useRef(null); const [isCrossProtocol, setIsCrossProtocol] = useState(false); const [iframeError, setIframeError] = useState(null); useEffect(() => { if (data?.url) { try { const iframeProtocol = new URL(data.url).protocol; const currentProtocol = window.location.protocol; // Check if the iframe URL has a different protocol than the current page setIsCrossProtocol( VSCODE_IN_NEW_TAB() || iframeProtocol !== currentProtocol, ); } catch (e) { // Silently handle URL parsing errors setIframeError(t("VSCODE$URL_PARSE_ERROR")); } } }, [data?.url]); const handleOpenInNewTab = () => { if (data?.url) { window.open(data.url, "_blank", "noopener,noreferrer"); } }; if (isRuntimeInactive) { return (
{t("DIFF_VIEWER$WAITING_FOR_RUNTIME")}
); } if (isLoading) { return (
{t("DIFF_VIEWER$WAITING_FOR_RUNTIME")}
); } if (error || (data && data.error) || !data?.url || iframeError) { return (
{iframeError || data?.error || String(error) || t(I18nKey.VSCODE$URL_NOT_AVAILABLE)}
); } // If cross-origin, show a button to open in new tab if (isCrossProtocol) { return (
{t("VSCODE$CROSS_ORIGIN_WARNING")}
); } // If same origin, use the iframe return (