mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
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:
commit
f2bb6dbd55
1 changed files with 35 additions and 30 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue