diff --git a/site/src/pages/AgentsPage/AgentChatInput.tsx b/site/src/pages/AgentsPage/AgentChatInput.tsx index c21db17eb4..225f27e27e 100644 --- a/site/src/pages/AgentsPage/AgentChatInput.tsx +++ b/site/src/pages/AgentsPage/AgentChatInput.tsx @@ -34,6 +34,7 @@ import { useState, } from "react"; import { cn } from "utils/cn"; +import { isMobileViewport } from "utils/mobile"; import { ImageLightbox } from "./ImageLightbox"; import { formatProviderLabel } from "./modelOptions"; import { QueuedMessagesList } from "./QueuedMessagesList"; @@ -473,7 +474,9 @@ export const AgentChatInput = memo( if (prevIsLoading !== isLoading) { setPrevIsLoading(isLoading); if (prevIsLoading && !isLoading) { - internalRef.current?.focus(); + if (!isMobileViewport()) { + internalRef.current?.focus(); + } } } @@ -518,7 +521,9 @@ export const AgentChatInput = memo( return; } onSend(text); - internalRef.current?.focus(); + if (!isMobileViewport()) { + internalRef.current?.focus(); + } }, [ isDisabled, isLoading, diff --git a/site/src/pages/AgentsPage/AgentDetail.tsx b/site/src/pages/AgentsPage/AgentDetail.tsx index be0201bb3f..a8792c603a 100644 --- a/site/src/pages/AgentsPage/AgentDetail.tsx +++ b/site/src/pages/AgentsPage/AgentDetail.tsx @@ -39,6 +39,7 @@ import { import { useNavigate, useOutletContext, useParams } from "react-router"; import { toast } from "sonner"; import type { UrlTransform } from "streamdown"; +import { isMobileViewport } from "utils/mobile"; import { pageTitle } from "utils/page"; import { portForwardURL } from "utils/portForward"; import type { ChatMessageInputRef } from "./AgentChatInput"; @@ -171,7 +172,9 @@ export function useConversationEditingState(deps: { await onSend(message, fileIds, editedMessageID); // Clear input and editing state on success. chatInputRef.current?.clear(); - chatInputRef.current?.focus(); + if (!isMobileViewport()) { + chatInputRef.current?.focus(); + } inputValueRef.current = ""; if (typeof window !== "undefined" && draftStorageKey) { localStorage.removeItem(draftStorageKey); diff --git a/site/src/utils/mobile.ts b/site/src/utils/mobile.ts new file mode 100644 index 0000000000..8873ce0fcd --- /dev/null +++ b/site/src/utils/mobile.ts @@ -0,0 +1,12 @@ +/** + * Returns `true` when the viewport width is at or below the `sm` + * Tailwind breakpoint (< 640 px), which is a reasonable proxy for a + * mobile / touch device where auto-focusing an input would cause the + * virtual keyboard to pop up unexpectedly. + */ +export const isMobileViewport = (): boolean => { + if (typeof window === "undefined" || !window.matchMedia) { + return false; + } + return window.matchMedia("(max-width: 639px)").matches; +};