diff --git a/frontend/src/components/features/file-explorer/file-explorer.tsx b/frontend/src/components/features/file-explorer/file-explorer.tsx index b033cfb62126..039fc1602003 100644 --- a/frontend/src/components/features/file-explorer/file-explorer.tsx +++ b/frontend/src/components/features/file-explorer/file-explorer.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import { useTranslation } from "react-i18next"; import AgentState from "#/types/agent-state"; import { ExplorerTree } from "#/components/features/file-explorer/explorer-tree"; @@ -14,6 +14,7 @@ import { Dropzone } from "./dropzone"; import { FileExplorerHeader } from "./file-explorer-header"; import { useVSCodeUrl } from "#/hooks/query/use-vscode-url"; import { OpenVSCodeButton } from "#/components/shared/buttons/open-vscode-button"; +import { addAssistantMessage } from "#/state/chat-slice"; interface FileExplorerProps { isOpen: boolean; @@ -22,15 +23,37 @@ interface FileExplorerProps { export function FileExplorer({ isOpen, onToggle }: FileExplorerProps) { const { t } = useTranslation(); + const dispatch = useDispatch(); const fileInputRef = React.useRef(null); const [isDragging, setIsDragging] = React.useState(false); const { curAgentState } = useSelector((state: RootState) => state.agent); + const agentIsReady = + curAgentState !== AgentState.INIT && curAgentState !== AgentState.LOADING; + const { data: paths, refetch, error } = useListFiles(); const { mutate: uploadFiles } = useUploadFiles(); - const { refetch: getVSCodeUrl } = useVSCodeUrl(); + const { data: vscodeUrl } = useVSCodeUrl({ enabled: agentIsReady }); + + const handleOpenVSCode = () => { + if (vscodeUrl?.vscode_url) { + dispatch( + addAssistantMessage( + "You opened VS Code. Please inform the agent of any changes you made to the workspace or environment. To avoid conflicts, it's best to pause the agent before making any changes.", + ), + ); + window.open(vscodeUrl.vscode_url, "_blank"); + } else if (vscodeUrl?.error) { + toast.error( + `open-vscode-error-${new Date().getTime()}`, + t(I18nKey.EXPLORER$VSCODE_SWITCHING_ERROR_MESSAGE, { + error: vscodeUrl.error, + }), + ); + } + }; const selectFileInput = () => { fileInputRef.current?.click(); // Trigger the file browser @@ -142,11 +165,8 @@ export function FileExplorer({ isOpen, onToggle }: FileExplorerProps) { )} {isOpen && ( )} diff --git a/frontend/src/hooks/query/use-vscode-url.ts b/frontend/src/hooks/query/use-vscode-url.ts index 9c913e57cf4b..9024876114c4 100644 --- a/frontend/src/hooks/query/use-vscode-url.ts +++ b/frontend/src/hooks/query/use-vscode-url.ts @@ -1,43 +1,13 @@ import { useQuery } from "@tanstack/react-query"; -import React from "react"; -import { useTranslation } from "react-i18next"; -import { useDispatch } from "react-redux"; -import toast from "#/utils/toast"; -import { addAssistantMessage } from "#/state/chat-slice"; -import { I18nKey } from "#/i18n/declaration"; import OpenHands from "#/api/open-hands"; -export const useVSCodeUrl = () => { - const { t } = useTranslation(); - const dispatch = useDispatch(); - +export const useVSCodeUrl = (config: { enabled: boolean }) => { const data = useQuery({ queryKey: ["vscode_url"], queryFn: OpenHands.getVSCodeUrl, - enabled: false, + enabled: config.enabled, + refetchOnMount: false, }); - const { data: vscodeUrlObject, isFetching } = data; - - React.useEffect(() => { - if (isFetching) return; - - if (vscodeUrlObject?.vscode_url) { - dispatch( - addAssistantMessage( - "You opened VS Code. Please inform the agent of any changes you made to the workspace or environment. To avoid conflicts, it's best to pause the agent before making any changes.", - ), - ); - window.open(vscodeUrlObject.vscode_url, "_blank"); - } else if (vscodeUrlObject?.error) { - toast.error( - `open-vscode-error-${new Date().getTime()}`, - t(I18nKey.EXPLORER$VSCODE_SWITCHING_ERROR_MESSAGE, { - error: vscodeUrlObject.error, - }), - ); - } - }, [vscodeUrlObject, isFetching]); - return data; };