diff --git a/src/renderer/src/pages/home/Tabs/components/SessionItem.tsx b/src/renderer/src/pages/home/Tabs/components/SessionItem.tsx index af0a8c037d..f71b9ef149 100644 --- a/src/renderer/src/pages/home/Tabs/components/SessionItem.tsx +++ b/src/renderer/src/pages/home/Tabs/components/SessionItem.tsx @@ -8,11 +8,15 @@ import { useSettings } from '@renderer/hooks/useSettings' import { useTimer } from '@renderer/hooks/useTimer' import { SessionSettingsPopup } from '@renderer/pages/settings/AgentSettings' import { SessionLabel } from '@renderer/pages/settings/AgentSettings/shared' +import { useAppDispatch, useAppSelector } from '@renderer/store' +import { newMessagesActions } from '@renderer/store/newMessage' import { AgentSessionEntity } from '@renderer/types' import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@renderer/ui/context-menu' +import { buildAgentSessionTopicId } from '@renderer/utils/agentSession' import { XIcon } from 'lucide-react' -import React, { FC, memo, startTransition, useState } from 'react' +import React, { FC, memo, startTransition, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' +import styled from 'styled-components' // const logger = loggerService.withContext('AgentItem') @@ -33,6 +37,7 @@ const SessionItem: FC = ({ session, agentId, isDisabled, isLoa const activeSessionId = chat.activeSessionId[agentId] const [isConfirmingDeletion, setIsConfirmingDeletion] = useState(false) const { setTimeoutTimer } = useTimer() + const dispatch = useAppDispatch() const { isEditing, isSaving, editValue, inputRef, startEdit, handleKeyDown, handleValueChange } = useInPlaceEdit({ onSave: async (value) => { @@ -86,6 +91,11 @@ const SessionItem: FC = ({ session, agentId, isDisabled, isLoa } const isActive = activeSessionId === session.id + const topicLoadingQuery = useAppSelector((state) => state.messages.loadingByTopic) + const topicFulfilledQuery = useAppSelector((state) => state.messages.fulfilledByTopic) + const sessionTopicId = buildAgentSessionTopicId(session.id) + const isPending = useMemo(() => topicLoadingQuery[sessionTopicId], [sessionTopicId, topicLoadingQuery]) + const isFulfilled = useMemo(() => topicFulfilledQuery[sessionTopicId], [sessionTopicId, topicFulfilledQuery]) return ( <> @@ -94,11 +104,16 @@ const SessionItem: FC = ({ session, agentId, isDisabled, isLoa { + dispatch(newMessagesActions.setTopicFulfilled({ topicId: sessionTopicId, fulfilled: false })) + onPress() + }} isActive={isActive} onDoubleClick={() => startEdit(session.name ?? '')} className="group"> - + + {isPending && !isActive && } + {isFulfilled && !isActive && } {isEditing && ( > = ({ /> ) +const PendingIndicator = styled.div.attrs({ + className: 'animation-pulse' +})` + --pulse-size: 5px; + width: 5px; + height: 5px; + position: absolute; + left: 3px; + top: 15px; + border-radius: 50%; + background-color: var(--color-status-warning); +` + +const FulfilledIndicator = styled.div.attrs({ + className: 'animation-pulse' +})` + --pulse-size: 5px; + width: 5px; + height: 5px; + position: absolute; + left: 3px; + top: 15px; + border-radius: 50%; + background-color: var(--color-status-success); +` + export default memo(SessionItem) diff --git a/src/renderer/src/store/thunk/messageThunk.v2.ts b/src/renderer/src/store/thunk/messageThunk.v2.ts index 3dc0ea7847..ec0aed947b 100644 --- a/src/renderer/src/store/thunk/messageThunk.v2.ts +++ b/src/renderer/src/store/thunk/messageThunk.v2.ts @@ -55,7 +55,6 @@ export const loadTopicMessagesThunkV2 = // Could dispatch an error action here if needed } finally { dispatch(newMessagesActions.setTopicLoading({ topicId, loading: false })) - dispatch(newMessagesActions.setTopicFulfilled({ topicId, fulfilled: true })) } }