From 37559fcc6d5028ea568e9ff2fb5d645603dbbb66 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:41:21 +0530 Subject: [PATCH] refactor: enhance chat UI components for mobile responsiveness - Updated the layout of the ComposerAction and ChatHeader components to improve mobile compatibility. - Added a new prop to ImageModelSelector for mobile-specific rendering. - Adjusted ModelSelector to conditionally render elements based on mobile view, enhancing user experience on smaller screens. --- .../components/assistant-ui/thread.tsx | 6 +++--- .../components/new-chat/chat-header.tsx | 4 ++-- .../new-chat/image-model-selector.tsx | 20 ++++++++++++++----- .../components/new-chat/model-selector.tsx | 12 +++++++---- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/surfsense_web/components/assistant-ui/thread.tsx b/surfsense_web/components/assistant-ui/thread.tsx index 9f74895d1..c8da125f4 100644 --- a/surfsense_web/components/assistant-ui/thread.tsx +++ b/surfsense_web/components/assistant-ui/thread.tsx @@ -1577,7 +1577,7 @@ const ComposerAction: FC = ({ Select a model )} -
+
= ({ variant="default" size="icon" className={cn( - "aui-composer-send size-9 rounded-full", + "aui-composer-send size-9 shrink-0 rounded-full", isSendDisabled && "cursor-not-allowed opacity-50" )} aria-label="Send message" @@ -1617,7 +1617,7 @@ const ComposerAction: FC = ({ type="button" variant="default" size="icon" - className="aui-composer-cancel size-9 rounded-full" + className="aui-composer-cancel size-9 shrink-0 rounded-full" aria-label="Stop generating" > diff --git a/surfsense_web/components/new-chat/chat-header.tsx b/surfsense_web/components/new-chat/chat-header.tsx index 9882530d4..99d56eb02 100644 --- a/surfsense_web/components/new-chat/chat-header.tsx +++ b/surfsense_web/components/new-chat/chat-header.tsx @@ -11,13 +11,13 @@ interface ChatHeaderProps { export function ChatHeader({ searchSpaceId, className, onChatModelSelected }: ChatHeaderProps) { return ( -
+
- +
); } diff --git a/surfsense_web/components/new-chat/image-model-selector.tsx b/surfsense_web/components/new-chat/image-model-selector.tsx index e90a46c09..5cd898afc 100644 --- a/surfsense_web/components/new-chat/image-model-selector.tsx +++ b/surfsense_web/components/new-chat/image-model-selector.tsx @@ -33,6 +33,7 @@ import { providerDisplay } from "../settings/model-connections/provider-metadata interface ImageModelSelectorProps { searchSpaceId: number; className?: string; + mobileIconOnly?: boolean; } type ImageModel = ModelRead & { @@ -95,7 +96,11 @@ function groupedModels(models: ImageModel[]) { }, {}); } -export function ImageModelSelector({ searchSpaceId, className }: ImageModelSelectorProps) { +export function ImageModelSelector({ + searchSpaceId, + className, + mobileIconOnly = false, +}: ImageModelSelectorProps) { const router = useRouter(); const isMobile = useIsMobile(); const [open, setOpen] = useState(false); @@ -126,6 +131,7 @@ export function ImageModelSelector({ searchSpaceId, className }: ImageModelSelec const groups = useMemo(() => groupedModels(visibleImageModels), [visibleImageModels]); const loading = globalLoading || connectionsLoading; const hasSearchQuery = search.trim().length > 0; + const showIconOnlyTrigger = isMobile && mobileIconOnly; function handleOpenChange(nextOpen: boolean) { if (!nextOpen) setSearch(""); @@ -252,12 +258,14 @@ export function ImageModelSelector({ searchSpaceId, className }: ImageModelSelec type="button" variant="ghost" size="sm" + aria-label="Select image model" className={cn( "h-8 min-w-0 gap-2 rounded-md px-3 text-muted-foreground transition-colors", "select-none", "hover:bg-foreground/10 hover:text-foreground", "data-[state=open]:bg-foreground/10 data-[state=open]:text-foreground", - className + className, + showIconOnlyTrigger && "h-9 w-auto shrink-0 justify-center gap-1 px-2" )} > {selected ? ( @@ -265,9 +273,11 @@ export function ImageModelSelector({ searchSpaceId, className }: ImageModelSelec ) : ( )} - - {selected ? modelName(selected) : "Auto"} - + {showIconOnlyTrigger ? null : ( + + {selected ? modelName(selected) : "Auto"} + + )} ); diff --git a/surfsense_web/components/new-chat/model-selector.tsx b/surfsense_web/components/new-chat/model-selector.tsx index 22d86aa92..c10bfd862 100644 --- a/surfsense_web/components/new-chat/model-selector.tsx +++ b/surfsense_web/components/new-chat/model-selector.tsx @@ -131,6 +131,7 @@ export function ModelSelector({ const groups = useMemo(() => groupedModels(visibleChatModels), [visibleChatModels]); const loading = globalLoading || connectionsLoading; const hasSearchQuery = search.trim().length > 0; + const showIconOnlyTrigger = isMobile; function handleOpenChange(nextOpen: boolean) { if (!nextOpen) setSearch(""); @@ -276,15 +277,18 @@ export function ModelSelector({ "select-none", "hover:bg-foreground/10 hover:text-foreground", "data-[state=open]:bg-foreground/10 data-[state=open]:text-foreground", - className + className, + showIconOnlyTrigger && "h-9 w-auto shrink-0 justify-center gap-1 px-2" )} > {selected ? getProviderIcon(selected.provider, { className: "size-4 shrink-0" }) : getProviderIcon(AUTO_PROVIDER_ICON_KEY, { className: "size-4 shrink-0" })} - - {selected ? modelName(selected) : "Auto"} - + {showIconOnlyTrigger ? null : ( + + {selected ? modelName(selected) : "Auto"} + + )} );