import { useEffect, useMemo } from 'react' import { useTabStore } from '../stores/tabStore' import { useSessionStore } from '../stores/sessionStore' import { useChatStore } from '../stores/chatStore' import { useCLITaskStore } from '../stores/cliTaskStore' import { useTeamStore } from '../stores/teamStore' import { useTranslation } from '../i18n' import { MessageList } from '../components/chat/MessageList' import { ChatInput } from '../components/chat/ChatInput' import { TeamStatusBar } from '../components/teams/TeamStatusBar' import { SessionTaskBar } from '../components/chat/SessionTaskBar' const TASK_POLL_INTERVAL_MS = 1000 export function ActiveSession() { const activeTabId = useTabStore((s) => s.activeTabId) const sessions = useSessionStore((s) => s.sessions) const connectToSession = useChatStore((s) => s.connectToSession) const sessionState = useChatStore((s) => activeTabId ? s.sessions[activeTabId] : undefined) const fetchSessionTasks = useCLITaskStore((s) => s.fetchSessionTasks) const trackedTaskSessionId = useCLITaskStore((s) => s.sessionId) const hasIncompleteTasks = useCLITaskStore((s) => s.tasks.some((task) => task.status !== 'completed')) const chatState = sessionState?.chatState ?? 'idle' const tokenUsage = sessionState?.tokenUsage ?? { input_tokens: 0, output_tokens: 0 } const session = sessions.find((s) => s.id === activeTabId) const memberInfo = useTeamStore((s) => activeTabId ? s.getMemberBySessionId(activeTabId) : null) const activeTeam = useTeamStore((s) => s.activeTeam) const isMemberSession = !!memberInfo useEffect(() => { if (activeTabId && !isMemberSession) { connectToSession(activeTabId) } }, [activeTabId, isMemberSession, connectToSession]) useEffect(() => { if (!activeTabId || isMemberSession) return const shouldPollTasks = chatState !== 'idle' || (trackedTaskSessionId === activeTabId && hasIncompleteTasks) if (!shouldPollTasks) return void fetchSessionTasks(activeTabId) const timer = setInterval(() => { void fetchSessionTasks(activeTabId) }, TASK_POLL_INTERVAL_MS) return () => clearInterval(timer) }, [ activeTabId, isMemberSession, chatState, trackedTaskSessionId, hasIncompleteTasks, fetchSessionTasks, ]) const t = useTranslation() const messages = sessionState?.messages ?? [] const streamingText = sessionState?.streamingText ?? '' const isEmpty = messages.length === 0 && !streamingText const isActive = chatState !== 'idle' const totalTokens = tokenUsage.input_tokens + tokenUsage.output_tokens const lastUpdated = useMemo(() => { if (!session?.modifiedAt) return '' const diff = Date.now() - new Date(session.modifiedAt).getTime() if (diff < 60000) return t('session.timeJustNow') if (diff < 3600000) return t('session.timeMinutes', { n: Math.floor(diff / 60000) }) if (diff < 86400000) return t('session.timeHours', { n: Math.floor(diff / 3600000) }) return t('session.timeDays', { n: Math.floor(diff / 86400000) }) }, [session?.modifiedAt, t]) if (!activeTabId) return null return (
{t('teams.memberSessionHint')}
{memberInfo?.status === 'running' ? `${memberInfo.role} ${t('teams.working')}` : t('teams.noMessages')}
> ) : ( <>{t('empty.subtitle')}
> )}