From bb919e3b21c818dc8e3e05377513d65dfc7e30a5 Mon Sep 17 00:00:00 2001 From: scyyw24 Date: Thu, 18 Dec 2025 12:21:21 +0000 Subject: [PATCH] fix: session list pagination and scroll performance Improves session list pagination by correctly updating the total count when adding or deleting sessions. Optimizes the scroll event handler in the Sessions component by throttling loadMore calls to prevent excessive triggering. --- src/renderer/src/hooks/agents/useSessions.ts | 33 +++++++++++-------- .../pages/home/Tabs/components/Sessions.tsx | 33 ++++++++++++------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/renderer/src/hooks/agents/useSessions.ts b/src/renderer/src/hooks/agents/useSessions.ts index 7c1f21e969..84481b26e4 100644 --- a/src/renderer/src/hooks/agents/useSessions.ts +++ b/src/renderer/src/hooks/agents/useSessions.ts @@ -1,4 +1,9 @@ -import type { CreateAgentSessionResponse, CreateSessionForm, GetAgentSessionResponse } from '@renderer/types' +import type { + CreateAgentSessionResponse, + CreateSessionForm, + GetAgentSessionResponse, + ListAgentSessionsResponse +} from '@renderer/types' import { formatErrorMessageWithPrefix } from '@renderer/utils/error' import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' @@ -12,7 +17,7 @@ export const useSessions = (agentId: string | null) => { const { t } = useTranslation() const client = useAgentClient() - const getKey = (pageIndex: number, previousPageData: any) => { + const getKey = (pageIndex: number, previousPageData: ListAgentSessionsResponse | null) => { if (!agentId) return null if (previousPageData && previousPageData.data.length === 0) return null return [client.getSessionPaths(agentId).base, pageIndex] @@ -53,13 +58,12 @@ export const useSessions = (agentId: string | null) => { if (!prev || prev.length === 0) { return [{ data: [result], total: 1, limit: PAGE_SIZE, offset: 0 }] } - const newData = [...prev] - newData[0] = { - ...newData[0], - data: [result, ...newData[0].data], - total: newData[0].total + 1 - } - return newData + const newTotal = prev[0].total + 1 + return prev.map((page, index) => ({ + ...page, + data: index === 0 ? [result, ...page.data] : page.data, + total: newTotal + })) }, { revalidate: false } ) @@ -100,12 +104,15 @@ export const useSessions = (agentId: string | null) => { try { await client.deleteSession(agentId, id) mutate( - (prev) => - prev?.map((page) => ({ + (prev) => { + if (!prev || prev.length === 0) return prev + const newTotal = prev[0].total - 1 + return prev.map((page) => ({ ...page, data: page.data.filter((session) => session.id !== id), - total: page.total - 1 - })), + total: newTotal + })) + }, { revalidate: false } ) return true diff --git a/src/renderer/src/pages/home/Tabs/components/Sessions.tsx b/src/renderer/src/pages/home/Tabs/components/Sessions.tsx index 5b9f1360c6..a8014868cd 100644 --- a/src/renderer/src/pages/home/Tabs/components/Sessions.tsx +++ b/src/renderer/src/pages/home/Tabs/components/Sessions.tsx @@ -12,7 +12,8 @@ import { import { buildAgentSessionTopicId } from '@renderer/utils/agentSession' import { Alert, Spin } from 'antd' import { motion } from 'framer-motion' -import { memo, useCallback, useEffect, useRef } from 'react' +import { throttle } from 'lodash' +import { memo, useCallback, useEffect, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -32,22 +33,32 @@ const Sessions: React.FC = ({ agentId }) => { const { createDefaultSession, creatingSession } = useCreateDefaultSession(agentId) const listRef = useRef(null) + // Throttled scroll handler to avoid excessive calls + const handleScroll = useMemo( + () => + throttle(() => { + const scrollElement = listRef.current?.scrollElement() + if (!scrollElement) return + + const { scrollTop, scrollHeight, clientHeight } = scrollElement + if (scrollHeight - scrollTop - clientHeight < 100 && hasMore && !isLoadingMore) { + loadMore() + } + }, 150), + [hasMore, isLoadingMore, loadMore] + ) + // Handle scroll to load more useEffect(() => { const scrollElement = listRef.current?.scrollElement() if (!scrollElement) return - const handleScroll = () => { - const { scrollTop, scrollHeight, clientHeight } = scrollElement - // Load more when scrolled to bottom (with 100px threshold) - if (scrollHeight - scrollTop - clientHeight < 100 && hasMore && !isLoadingMore) { - loadMore() - } - } - scrollElement.addEventListener('scroll', handleScroll) - return () => scrollElement.removeEventListener('scroll', handleScroll) - }, [hasMore, isLoadingMore, loadMore]) + return () => { + handleScroll.cancel() + scrollElement.removeEventListener('scroll', handleScroll) + } + }, [handleScroll]) const setActiveSessionId = useCallback( (agentId: string, sessionId: string | null) => {