Merge pull request #1275 from Tacite243/fix/move-modelSelector-reset-effects-into-the-openTab-event-handlers-1252

refactor: move model selector reset logic to event handlers
This commit is contained in:
Rohan Verma 2026-04-20 21:01:42 -07:00 committed by GitHub
commit f2bb6dbd55
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -269,6 +269,34 @@ export function ModelSelector({
const searchInputRef = useRef<HTMLInputElement>(null); const searchInputRef = useRef<HTMLInputElement>(null);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const handleOpenChange = useCallback(
(next: boolean) => {
if (next) {
setSearchQuery("");
setSelectedProvider("all");
if (!isMobile) {
requestAnimationFrame(() => searchInputRef.current?.focus());
}
}
setOpen(next);
},
[isMobile]
);
const handleTabChange = useCallback(
(next: "llm" | "image" | "vision") => {
setActiveTab(next);
setSelectedProvider("all");
setSearchQuery("");
setFocusedIndex(-1);
setModelScrollPos("top");
if (open && !isMobile) {
requestAnimationFrame(() => searchInputRef.current?.focus());
}
},
[open, isMobile]
);
const handleModelListScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => { const handleModelListScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
const el = e.currentTarget; const el = e.currentTarget;
const atTop = el.scrollTop <= 2; const atTop = el.scrollTop <= 2;
@ -292,43 +320,19 @@ export function ModelSelector({
[isMobile] [isMobile]
); );
// Reset search + provider when tab changes
// biome-ignore lint/correctness/useExhaustiveDependencies: activeTab is intentionally used as a trigger
useEffect(() => {
setSelectedProvider("all");
setSearchQuery("");
setFocusedIndex(-1);
setModelScrollPos("top");
}, [activeTab]);
// Reset on open
useEffect(() => {
if (open) {
setSearchQuery("");
setSelectedProvider("all");
}
}, [open]);
// Cmd/Ctrl+M shortcut (desktop only) // Cmd/Ctrl+M shortcut (desktop only)
useEffect(() => { useEffect(() => {
if (isMobile) return; if (isMobile) return;
const handler = (e: KeyboardEvent) => { const handler = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === "m") { if ((e.metaKey || e.ctrlKey) && e.key === "m") {
e.preventDefault(); e.preventDefault();
setOpen((prev) => !prev); // setOpen((prev) => !prev);
handleOpenChange(!open);
} }
}; };
document.addEventListener("keydown", handler); document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler); return () => document.removeEventListener("keydown", handler);
}, [isMobile]); }, [isMobile, open, handleOpenChange]);
// Focus search input on open
// biome-ignore lint/correctness/useExhaustiveDependencies: activeTab is intentionally used as a trigger to re-focus on tab switch
useEffect(() => {
if (open && !isMobile) {
requestAnimationFrame(() => searchInputRef.current?.focus());
}
}, [open, isMobile, activeTab]);
// ─── Data ─── // ─── Data ───
const { data: llmUserConfigs, isLoading: llmUserLoading } = useAtomValue(newLLMConfigsAtom); const { data: llmUserConfigs, isLoading: llmUserLoading } = useAtomValue(newLLMConfigsAtom);
@ -971,7 +975,8 @@ export function ModelSelector({
<button <button
key={value} key={value}
type="button" type="button"
onClick={() => setActiveTab(value)} // onClick={() => setActiveTab(value)}
onClick={() => handleTabChange(value)}
className={cn( className={cn(
"flex items-center justify-center gap-1.5 text-sm font-medium transition-all duration-200 border-b-[1.5px]", "flex items-center justify-center gap-1.5 text-sm font-medium transition-all duration-200 border-b-[1.5px]",
activeTab === value activeTab === value
@ -1208,7 +1213,7 @@ export function ModelSelector({
// ─── Shell: Drawer on mobile, Popover on desktop ─── // ─── Shell: Drawer on mobile, Popover on desktop ───
if (isMobile) { if (isMobile) {
return ( return (
<Drawer open={open} onOpenChange={setOpen}> <Drawer open={open} onOpenChange={handleOpenChange}>
<DrawerTrigger asChild>{triggerButton}</DrawerTrigger> <DrawerTrigger asChild>{triggerButton}</DrawerTrigger>
<DrawerContent className="max-h-[85vh]"> <DrawerContent className="max-h-[85vh]">
<DrawerHandle /> <DrawerHandle />
@ -1222,7 +1227,7 @@ export function ModelSelector({
} }
return ( return (
<Popover open={open} onOpenChange={setOpen}> <Popover open={open} onOpenChange={handleOpenChange}>
<PopoverTrigger asChild>{triggerButton}</PopoverTrigger> <PopoverTrigger asChild>{triggerButton}</PopoverTrigger>
<PopoverContent <PopoverContent
className="w-[300px] md:w-[380px] p-0 rounded-lg shadow-lg overflow-hidden bg-white border-border/60 dark:bg-neutral-900 dark:border dark:border-white/5 select-none" className="w-[300px] md:w-[380px] p-0 rounded-lg shadow-lg overflow-hidden bg-white border-border/60 dark:bg-neutral-900 dark:border dark:border-white/5 select-none"