diff --git a/skyvern-frontend/src/components/BrowserStream.tsx b/skyvern-frontend/src/components/BrowserStream.tsx index 3733257d..9456c581 100644 --- a/skyvern-frontend/src/components/BrowserStream.tsx +++ b/skyvern-frontend/src/components/BrowserStream.tsx @@ -1,18 +1,26 @@ -import { Status } from "@/api/types"; -import { useEffect, useState, useRef, useCallback } from "react"; -import { Skeleton } from "@/components/ui/skeleton"; -import { statusIsNotFinalized } from "@/routes/tasks/types"; -import { useCredentialGetter } from "@/hooks/useCredentialGetter"; -import { envCredential } from "@/util/env"; -import { toast } from "@/components/ui/use-toast"; import RFB from "@novnc/novnc/lib/rfb.js"; -import { environment, wssBaseUrl, newWssBaseUrl } from "@/util/env"; -import { cn } from "@/util/utils"; -import { useClientIdStore } from "@/store/useClientIdStore"; +import { ExitIcon, HandIcon } from "@radix-ui/react-icons"; +import { useEffect, useState, useRef, useCallback } from "react"; + +import { Status } from "@/api/types"; import type { TaskApiResponse, WorkflowRunStatusApiResponse, } from "@/api/types"; +import { Button } from "@/components/ui/button"; +import { Skeleton } from "@/components/ui/skeleton"; +import { toast } from "@/components/ui/use-toast"; +import { useCredentialGetter } from "@/hooks/useCredentialGetter"; +import { statusIsNotFinalized } from "@/routes/tasks/types"; +import { useClientIdStore } from "@/store/useClientIdStore"; +import { + envCredential, + environment, + wssBaseUrl, + newWssBaseUrl, +} from "@/util/env"; +import { cn } from "@/util/utils"; + import "./browser-stream.css"; interface CommandTakeControl { @@ -28,6 +36,7 @@ type Command = CommandTakeControl | CommandCedeControl; type Props = { browserSessionId?: string; interactive?: boolean; + showControlButtons?: boolean; task?: { run: TaskApiResponse; }; @@ -41,6 +50,7 @@ type Props = { function BrowserStream({ browserSessionId = undefined, interactive = true, + showControlButtons = undefined, task = undefined, workflow = undefined, // -- @@ -65,7 +75,7 @@ function BrowserStream({ } else { throw new Error("No browser session, task or workflow provided"); } - + const [userIsControlling, setUserIsControlling] = useState(false); const [commandSocket, setCommandSocket] = useState(null); const [vncDisconnectedTrigger, setVncDisconnectedTrigger] = useState(0); const prevVncConnectedRef = useRef(false); @@ -312,14 +322,51 @@ function BrowserStream({ } }, [task, workflow]); + const theUserIsControlling = + userIsControlling || (interactive && !showControlButtons); + return (
- {isVncConnected &&
} + {isVncConnected && ( +
+ {showControlButtons && ( +
+ + +
+ )} +
+ )} {!isVncConnected && (
diff --git a/skyvern-frontend/src/components/browser-stream.css b/skyvern-frontend/src/components/browser-stream.css index fe3b9237..52f54b28 100644 --- a/skyvern-frontend/src/components/browser-stream.css +++ b/skyvern-frontend/src/components/browser-stream.css @@ -73,6 +73,17 @@ background: transparent !important; } +.browser-stream .control-button { + transition: 0.3s all ease-in-out; + transform: translateY(0px); +} + +.browser-stream .control-button.hide { + opacity: 0; + pointer-events: none; + transform: translateY(15px); +} + @keyframes skyvern-anim-fadeIn { from { opacity: 0; diff --git a/skyvern-frontend/src/routes/browserSession/BrowserSession.tsx b/skyvern-frontend/src/routes/browserSession/BrowserSession.tsx index fded8e38..e4f10ea1 100644 --- a/skyvern-frontend/src/routes/browserSession/BrowserSession.tsx +++ b/skyvern-frontend/src/routes/browserSession/BrowserSession.tsx @@ -1,9 +1,10 @@ import { useState } from "react"; import { useParams } from "react-router-dom"; -import { BrowserStream } from "@/components/BrowserStream"; -import { getClient } from "@/api/AxiosClient"; - import { useQuery } from "@tanstack/react-query"; + +import { getClient } from "@/api/AxiosClient"; +import { BrowserStream } from "@/components/BrowserStream"; +import { LogoMinimized } from "@/components/LogoMinimized"; import { useCredentialGetter } from "@/hooks/useCredentialGetter"; function BrowserSession() { @@ -52,8 +53,20 @@ function BrowserSession() { return (
-
- +
+
+
+ +
browser session
+
+
+
+ +
);