Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions ui/desktop/src/components/sessions/SessionListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
currentIndex: number;
} | null>(null);

const [visibleGroupsCount, setVisibleGroupsCount] = useState(15);

// Edit modal state
const [showEditModal, setShowEditModal] = useState(false);
const [editingSession, setEditingSession] = useState<Session | null>(null);
Expand All @@ -210,6 +212,33 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
}
};

const visibleDateGroups = useMemo(() => {
return dateGroups.slice(0, visibleGroupsCount);
}, [dateGroups, visibleGroupsCount]);

const handleScroll = useCallback(
(target: HTMLDivElement) => {
const { scrollTop, scrollHeight, clientHeight } = target;
const threshold = 200;

if (
scrollHeight - scrollTop - clientHeight < threshold &&
visibleGroupsCount < dateGroups.length
) {
setVisibleGroupsCount((prev) => Math.min(prev + 5, dateGroups.length));
}
},
[visibleGroupsCount, dateGroups.length]
);

useEffect(() => {
if (debouncedSearchTerm) {
setVisibleGroupsCount(dateGroups.length);
} else {
setVisibleGroupsCount(15);
}
}, [debouncedSearchTerm, dateGroups.length]);

const loadSessions = useCallback(async () => {
setIsLoading(true);
setShowSkeleton(true);
Expand Down Expand Up @@ -557,10 +586,9 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
);
}

// For regular rendering in grid layout
return (
<div className="space-y-8">
{dateGroups.map((group) => (
{visibleDateGroups.map((group) => (
<div key={group.label} className="space-y-4">
<div className="sticky top-0 z-10 bg-background-default/95 backdrop-blur-sm">
<h2 className="text-text-muted">{group.label}</h2>
Expand All @@ -577,6 +605,15 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
</div>
</div>
))}

{visibleGroupsCount < dateGroups.length && (
<div className="flex justify-center py-8">
<div className="flex items-center space-x-2 text-text-muted">
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-text-muted"></div>
<span>Loading more sessions...</span>
</div>
</div>
)}
</div>
);
};
Expand All @@ -597,7 +634,7 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
</div>

<div className="flex-1 min-h-0 relative px-8">
<ScrollArea className="h-full" data-search-scroll-area>
<ScrollArea handleScroll={handleScroll} className="h-full" data-search-scroll-area>
<div ref={containerRef} className="h-full relative">
<SearchView
onSearch={handleSearch}
Expand Down
20 changes: 18 additions & 2 deletions ui/desktop/src/components/ui/scroll-area.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ interface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAr
/* padding needs to be passed into the container inside ScrollArea to avoid pushing the scrollbar out */
paddingX?: number;
paddingY?: number;
handleScroll?: (viewport: HTMLDivElement) => void;
}

const ScrollArea = React.forwardRef<ScrollAreaHandle, ScrollAreaProps>(
({ className, children, autoScroll = false, paddingX, paddingY, ...props }, ref) => {
(
{
className,
children,
autoScroll = false,
paddingX,
paddingY,
handleScroll: handleScrollProp,
...props
},
ref
) => {
const rootRef = React.useRef<React.ElementRef<typeof ScrollAreaPrimitive.Root>>(null);
const viewportRef = React.useRef<HTMLDivElement>(null);
const viewportEndRef = React.useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -71,7 +83,11 @@ const ScrollArea = React.forwardRef<ScrollAreaHandle, ScrollAreaProps>(

setIsFollowing(isAtBottom);
setIsScrolled(scrollTop > 0);
}, []);

if (handleScrollProp) {
handleScrollProp(viewport);
}
}, [handleScrollProp]);

// Track previous scroll height to detect content changes
const prevScrollHeightRef = React.useRef<number>(0);
Expand Down
Loading