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) => {