'use client'; import { useEffect, useState, useCallback, useRef } from 'react'; import { SignalRConnectionManager } from '@/lib/signalr/ConnectionManager'; import { SIGNALR_CONFIG } from '@/lib/signalr/config'; import { useAuthStore } from '@/stores/authStore'; export function useProjectHub(projectId?: string) { const isAuthenticated = useAuthStore((state) => state.isAuthenticated); const [connectionState, setConnectionState] = useState< 'disconnected' | 'connecting' | 'connected' | 'reconnecting' >('disconnected'); const managerRef = useRef(null); useEffect(() => { if (!isAuthenticated) return; const manager = new SignalRConnectionManager( SIGNALR_CONFIG.HUB_URLS.PROJECT ); managerRef.current = manager; const unsubscribe = manager.onStateChange(setConnectionState); // 监听项目事件 manager.on('ProjectUpdated', (data: any) => { console.log('[ProjectHub] Project updated:', data); // TODO: 触发项目数据重新加载 }); manager.on('IssueCreated', (issue: any) => { console.log('[ProjectHub] Issue created:', issue); // TODO: 添加到看板 }); manager.on('IssueUpdated', (issue: any) => { console.log('[ProjectHub] Issue updated:', issue); // TODO: 更新看板 }); manager.on('IssueDeleted', (data: { IssueId: string }) => { console.log('[ProjectHub] Issue deleted:', data); // TODO: 从看板移除 }); manager.on('IssueStatusChanged', (data: any) => { console.log('[ProjectHub] Issue status changed:', data); // TODO: 移动看板卡片 }); manager.on('UserJoinedProject', (data: any) => { console.log('[ProjectHub] User joined:', data); }); manager.on('UserLeftProject', (data: any) => { console.log('[ProjectHub] User left:', data); }); manager.on( 'TypingIndicator', (data: { UserId: string; IssueId: string; IsTyping: boolean }) => { console.log('[ProjectHub] Typing indicator:', data); // TODO: 显示正在输入提示 } ); manager.start(); return () => { unsubscribe(); manager.stop(); }; }, [isAuthenticated]); // 加入项目房间 const joinProject = useCallback(async (projectId: string) => { if (!managerRef.current) return; try { await managerRef.current.invoke('JoinProject', projectId); console.log(`[ProjectHub] Joined project ${projectId}`); } catch (error) { console.error('[ProjectHub] Error joining project:', error); } }, []); // 离开项目房间 const leaveProject = useCallback(async (projectId: string) => { if (!managerRef.current) return; try { await managerRef.current.invoke('LeaveProject', projectId); console.log(`[ProjectHub] Left project ${projectId}`); } catch (error) { console.error('[ProjectHub] Error leaving project:', error); } }, []); // 发送正在输入指示器 const sendTypingIndicator = useCallback( async (projectId: string, issueId: string, isTyping: boolean) => { if (!managerRef.current) return; try { await managerRef.current.invoke( 'SendTypingIndicator', projectId, issueId, isTyping ); } catch (error) { console.error('[ProjectHub] Error sending typing indicator:', error); } }, [] ); // 当 projectId 变化时自动加入/离开 useEffect(() => { if (connectionState === 'connected' && projectId) { joinProject(projectId); return () => { leaveProject(projectId); }; } }, [connectionState, projectId, joinProject, leaveProject]); return { connectionState, joinProject, leaveProject, sendTypingIndicator, isConnected: connectionState === 'connected', }; }