mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-20 21:18:13 +02:00
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.
This commit is contained in:
parent
03e57bdf7e
commit
37559fcc6d
4 changed files with 28 additions and 14 deletions
|
|
@ -1577,7 +1577,7 @@ const ComposerAction: FC<ComposerActionProps> = ({
|
|||
<span>Select a model</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="ml-auto flex min-w-0 shrink-0 items-center gap-2">
|
||||
<ChatHeader
|
||||
searchSpaceId={searchSpaceId}
|
||||
className="h-9 max-w-[44vw] px-2 sm:max-w-[220px] sm:px-3"
|
||||
|
|
@ -1600,7 +1600,7 @@ const ComposerAction: FC<ComposerActionProps> = ({
|
|||
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<ComposerActionProps> = ({
|
|||
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"
|
||||
>
|
||||
<SquareIcon className="aui-composer-cancel-icon size-3.5 fill-current" />
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ interface ChatHeaderProps {
|
|||
|
||||
export function ChatHeader({ searchSpaceId, className, onChatModelSelected }: ChatHeaderProps) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex min-w-0 shrink-0 items-center gap-2">
|
||||
<ModelSelector
|
||||
searchSpaceId={searchSpaceId}
|
||||
className={className}
|
||||
onChatModelSelected={onChatModelSelected}
|
||||
/>
|
||||
<ImageModelSelector searchSpaceId={searchSpaceId} className={className} />
|
||||
<ImageModelSelector searchSpaceId={searchSpaceId} className={className} mobileIconOnly />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|||
) : (
|
||||
<ImagePlus className="size-4 shrink-0" />
|
||||
)}
|
||||
<span className="min-w-0 flex-1 truncate text-sm">
|
||||
{selected ? modelName(selected) : "Auto"}
|
||||
</span>
|
||||
{showIconOnlyTrigger ? null : (
|
||||
<span className="min-w-0 flex-1 truncate text-sm">
|
||||
{selected ? modelName(selected) : "Auto"}
|
||||
</span>
|
||||
)}
|
||||
<ChevronDown className="h-3.5 w-3.5 shrink-0" />
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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" })}
|
||||
<span className="min-w-0 flex-1 truncate text-sm">
|
||||
{selected ? modelName(selected) : "Auto"}
|
||||
</span>
|
||||
{showIconOnlyTrigger ? null : (
|
||||
<span className="min-w-0 flex-1 truncate text-sm">
|
||||
{selected ? modelName(selected) : "Auto"}
|
||||
</span>
|
||||
)}
|
||||
<ChevronDown className="h-3.5 w-3.5 shrink-0" />
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue