import { useState, useCallback, useRef, useEffect } from 'react'; import type { WebRTCConnection } from './useSharedWebRTCManager'; // 文本传输状态 interface TextTransferState { isConnecting: boolean; isConnected: boolean; isWebSocketConnected: boolean; connectionError: string | null; currentText: string; // 当前文本内容 isTyping: boolean; // 对方是否在输入 } // 回调类型 type TextSyncCallback = (text: string) => void; type TypingStatusCallback = (isTyping: boolean) => void; const CHANNEL_NAME = 'text-transfer'; /** * 文本传输业务层 * 必须传入共享的 WebRTC 连接 */ export function useTextTransferBusiness(connection: WebRTCConnection) { const [state, setState] = useState({ isConnecting: false, isConnected: false, isWebSocketConnected: false, connectionError: null, currentText: '', isTyping: false }); // 回调引用 const textSyncCallbackRef = useRef(null); const typingCallbackRef = useRef(null); // 更新状态的辅助函数 const updateState = useCallback((updates: Partial) => { setState(prev => ({ ...prev, ...updates })); }, []); // 消息处理器 const handleMessage = useCallback((message: any) => { if (!message.type.startsWith('text-')) return; console.log('文本传输收到消息:', message.type, message); switch (message.type) { case 'text-sync': // 实时文本同步 - 接收方看到发送方的实时编辑 if (message.payload && typeof message.payload.text === 'string') { updateState({ currentText: message.payload.text }); // 触发文本同步回调 if (textSyncCallbackRef.current) { textSyncCallbackRef.current(message.payload.text); } } break; case 'text-typing': // 打字状态 if (typeof message.payload?.typing === 'boolean') { updateState({ isTyping: message.payload.typing }); // 触发打字状态回调 if (typingCallbackRef.current) { typingCallbackRef.current(message.payload.typing); } } break; default: console.warn('未知的文本消息类型:', message.type); } }, [updateState]); // 注册消息处理器 useEffect(() => { const unregister = connection.registerMessageHandler(CHANNEL_NAME, handleMessage); return unregister; }, [handleMessage]); // 监听连接状态变化 (直接使用 connection 的状态) useEffect(() => { // 这里我们直接依赖 connection 的状态变化 // 由于我们使用共享连接,状态会自动同步 }, []); // 连接 const connect = useCallback((roomCode: string, role: 'sender' | 'receiver') => { return connection.connect(roomCode, role); }, [connection]); // 断开连接 const disconnect = useCallback(() => { return connection.disconnect(); }, [connection]); // 发送实时文本同步 (替代原来的 sendMessage) const sendTextSync = useCallback((text: string) => { if (!connection) return; const message = { type: 'text-sync', payload: { text } }; connection.sendMessage(message, CHANNEL_NAME); console.log('发送实时文本同步:', text.length, '字符'); }, [connection]); // 发送打字状态 const sendTypingStatus = useCallback((isTyping: boolean) => { if (!connection) return; const message = { type: 'text-typing', payload: { typing: isTyping } }; connection.sendMessage(message, CHANNEL_NAME); console.log('发送打字状态:', isTyping); }, [connection]); // 设置文本同步回调 const onTextSync = useCallback((callback: TextSyncCallback) => { textSyncCallbackRef.current = callback; // 返回清理函数 return () => { textSyncCallbackRef.current = null; }; }, []); // 设置打字状态回调 const onTypingStatus = useCallback((callback: TypingStatusCallback) => { typingCallbackRef.current = callback; // 返回清理函数 return () => { typingCallbackRef.current = null; }; }, []); return { // 状态 - 直接从 connection 获取 isConnecting: connection.isConnecting, isConnected: connection.isConnected, isWebSocketConnected: connection.isWebSocketConnected, connectionError: connection.error, currentText: state.currentText, isTyping: state.isTyping, // 操作方法 connect, disconnect, sendTextSync, sendTypingStatus, // 回调设置 onTextSync, onTypingStatus }; }