diff --git a/chuan-next/src/app/HomePage.tsx b/chuan-next/src/app/HomePage.tsx
index d7a7151..ba56dfb 100644
--- a/chuan-next/src/app/HomePage.tsx
+++ b/chuan-next/src/app/HomePage.tsx
@@ -1,6 +1,6 @@
"use client";
-import React, { useEffect, useState } from 'react';
+import React from 'react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Upload, MessageSquare, Monitor, Users } from 'lucide-react';
import Hero from '@/components/Hero';
@@ -18,8 +18,6 @@ export default function HomePage() {
const {
activeTab,
handleTabChange,
- getConnectionInfo,
- hasInitialized,
confirmDialogState,
closeConfirmDialog
} = useTabNavigation();
@@ -34,18 +32,6 @@ export default function HomePage() {
showUnsupportedModalManually,
} = useWebRTCSupport();
- // 桌面共享功能的占位符函数(保持向后兼容)
- const handleStartSharing = async () => {
- console.log('开始桌面共享');
- };
-
- const handleStopSharing = async () => {
- console.log('停止桌面共享');
- };
-
- const handleJoinSharing = async (code: string) => {
- console.log('加入桌面共享:', code);
- };
// 处理Tabs组件的字符串参数
const handleTabChangeWrapper = (value: string) => {
diff --git a/chuan-next/src/components/ConnectionStatus.tsx b/chuan-next/src/components/ConnectionStatus.tsx
index ca0af37..a793336 100644
--- a/chuan-next/src/components/ConnectionStatus.tsx
+++ b/chuan-next/src/components/ConnectionStatus.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useMemo } from 'react';
+import React, { useMemo } from 'react';
import { cn } from '@/lib/utils';
import { useWebRTCStore } from '@/hooks/index';
@@ -14,7 +14,7 @@ interface ConnectionStatusProps {
}
// 连接状态枚举
-const getConnectionStatus = (connection: any, currentRoom: any) => {
+const getConnectionStatus = (connection: { isWebSocketConnected?: boolean; isPeerConnected?: boolean; isConnecting?: boolean; error?: string | null }, currentRoom: { code: string; role: 'sender' | 'receiver' } | null) => {
const isWebSocketConnected = connection?.isWebSocketConnected || false;
const isPeerConnected = connection?.isPeerConnected || false;
const isConnecting = connection?.isConnecting || false;
@@ -116,7 +116,7 @@ const StatusIcon = ({ type, className = 'w-3 h-3' }: { type: string; className?:
};
// 获取连接状态文字描述
-const getConnectionStatusText = (connection: any) => {
+const getConnectionStatusText = (connection: { isWebSocketConnected?: boolean; isPeerConnected?: boolean; isConnecting?: boolean; error?: string | null }) => {
const isWebSocketConnected = connection?.isWebSocketConnected || false;
const isPeerConnected = connection?.isPeerConnected || false;
const isConnecting = connection?.isConnecting || false;
@@ -155,12 +155,14 @@ export function ConnectionStatus(props: ConnectionStatusProps) {
error: webrtcState.error,
};
+ const isConnected = webrtcState.isWebSocketConnected && webrtcState.isPeerConnected;
+
// 如果是内联模式,只返回状态文字
if (inline) {
return {getConnectionStatusText(connection)};
}
- const status = getConnectionStatus(connection, currentRoom);
+ const status = getConnectionStatus(connection, currentRoom ?? null);
if (compact) {
return (
@@ -244,7 +246,7 @@ export function ConnectionStatus(props: ConnectionStatusProps) {
}
// 简化版本的 Hook,用于快速集成 - 现在已经不需要了,但保留兼容性
-export function useConnectionStatus(webrtcConnection?: any) {
+export function useConnectionStatus(webrtcConnection?: { isWebSocketConnected?: boolean; isPeerConnected?: boolean; isConnecting?: boolean; currentRoom?: { code: string; role: 'sender' | 'receiver' } | null; error?: string | null }) {
// 这个hook现在不再需要,因为ConnectionStatus组件直接使用底层连接
// 但为了向后兼容,保留这个接口
return useMemo(() => ({
diff --git a/chuan-next/src/components/DesktopShare.tsx b/chuan-next/src/components/DesktopShare.tsx
index e16725c..3091de1 100644
--- a/chuan-next/src/components/DesktopShare.tsx
+++ b/chuan-next/src/components/DesktopShare.tsx
@@ -6,26 +6,18 @@ import { Button } from '@/components/ui/button';
import { Share, Monitor } from 'lucide-react';
import WebRTCDesktopReceiver from '@/components/webrtc/WebRTCDesktopReceiver';
import WebRTCDesktopSender from '@/components/webrtc/WebRTCDesktopSender';
-import { useWebRTCStore } from '@/hooks/index';
interface DesktopShareProps {
// 保留向后兼容性的props(已废弃,但保留接口)
- onStartSharing?: () => Promise;
- onStopSharing?: () => Promise;
onJoinSharing?: (code: string) => Promise;
}
export default function DesktopShare({
- onStartSharing,
- onStopSharing,
onJoinSharing
}: DesktopShareProps) {
const [mode, setMode] = useState<'share' | 'view'>('share');
- // 使用全局WebRTC状态
- const webrtcState = useWebRTCStore();
-
// 使用统一的URL处理器,带模式转换
const { updateMode, getCurrentRoomCode } = useURLHandler({
featureType: 'desktop',
@@ -44,9 +36,8 @@ export default function DesktopShare({
return code;
}, [getCurrentRoomCode]);
- // 连接状态变化处理 - 现在不需要了,因为使用全局状态
- const handleConnectionChange = useCallback((connection: any) => {
- // 这个函数现在可能不需要了,但为了兼容现有的子组件接口,保留它
+ // 连接状态变化处理 - 为了兼容现有的子组件接口,保留它
+ const handleConnectionChange = useCallback((connection: { isConnected: boolean; isWebSocketConnected: boolean }) => {
console.log('桌面共享连接状态变化:', connection);
}, []);
diff --git a/chuan-next/src/components/WebRTCFileTransfer.tsx b/chuan-next/src/components/WebRTCFileTransfer.tsx
index 02e82ff..db9426c 100644
--- a/chuan-next/src/components/WebRTCFileTransfer.tsx
+++ b/chuan-next/src/components/WebRTCFileTransfer.tsx
@@ -83,7 +83,7 @@ export const WebRTCFileTransfer: React.FC = () => {
isPeerConnected: connection.isPeerConnected
});
- const { joinRoom: originalJoinRoom, isJoiningRoom } = useRoomConnection({
+ const { joinRoom: originalJoinRoom } = useRoomConnection({
connect,
isConnecting,
isConnected
@@ -264,28 +264,33 @@ export const WebRTCFileTransfer: React.FC = () => {
return;
}
+ console.log('当前选中的文件列表:', selectedFiles.map(f => f.name));
+
// 在发送方的selectedFiles中查找对应文件
const file = selectedFiles.find(f => f.name === fileName);
if (!file) {
console.error('找不到匹配的文件:', fileName);
+ console.log('可用文件:', selectedFiles.map(f => `${f.name} (${f.size} bytes)`));
showToast(`无法找到文件: ${fileName}`, "error");
return;
}
console.log('找到匹配文件,开始发送:', file.name, 'ID:', fileId, '文件大小:', file.size);
- // 更新发送方文件状态为downloading
+ // 更新发送方文件状态为downloading - 统一使用updateFileStatus
updateFileStatus(fileId, 'downloading', 0);
// 发送文件
try {
sendFile(file, fileId);
+
+ // 移除不必要的Toast - 传输开始状态在UI中已经显示
} catch (sendError) {
console.error('发送文件失败:', sendError);
showToast(`发送文件失败: ${fileName}`, "error");
- // 重置文件状态
+ // 重置文件状态 - 统一使用updateFileStatus
updateFileStatus(fileId, 'ready', 0);
}
} else {
@@ -340,86 +345,7 @@ export const WebRTCFileTransfer: React.FC = () => {
}
}, [error, mode, showToast, lastError]);
- // 处理文件接收
- useEffect(() => {
- const cleanup = onFileReceived((fileData: { id: string; file: File }) => {
- console.log('=== 接收到文件 ===');
- console.log('文件:', fileData.file.name, 'ID:', fileData.id);
-
- // 更新下载的文件
- setDownloadedFiles(prev => new Map(prev.set(fileData.id, fileData.file)));
-
- // 更新文件状态
- setFileList(prev => prev.map(item =>
- item.id === fileData.id
- ? { ...item, status: 'completed' as const, progress: 100 }
- : item
- ));
-
- // 移除不必要的Toast - 文件完成状态在UI中已经显示
- });
- return cleanup;
- }, [onFileReceived]);
-
- // 处理文件请求(发送方监听)
- useEffect(() => {
- const cleanup = onFileRequested((fileId: string, fileName: string) => {
- console.log('=== 收到文件请求 ===');
- console.log('文件:', fileName, 'ID:', fileId, '当前模式:', mode);
-
- if (mode === 'send') {
- // 检查连接状态
- if (!isConnected || error) {
- console.log('连接已断开,无法发送文件');
- showToast('连接已断开,无法发送文件', "error");
- return;
- }
-
- console.log('当前选中的文件列表:', selectedFiles.map(f => f.name));
-
- // 在发送方的selectedFiles中查找对应文件
- const file = selectedFiles.find(f => f.name === fileName);
-
- if (!file) {
- console.error('找不到匹配的文件:', fileName);
- console.log('可用文件:', selectedFiles.map(f => `${f.name} (${f.size} bytes)`));
- showToast(`无法找到文件: ${fileName}`, "error");
- return;
- }
-
- console.log('找到匹配文件,开始发送:', file.name, 'ID:', fileId, '文件大小:', file.size);
-
- // 更新发送方文件状态为downloading
- setFileList(prev => prev.map(item =>
- item.id === fileId || item.name === fileName
- ? { ...item, status: 'downloading' as const, progress: 0 }
- : item
- ));
-
- // 发送文件
- try {
- sendFile(file, fileId);
-
- // 移除不必要的Toast - 传输开始状态在UI中已经显示
- } catch (sendError) {
- console.error('发送文件失败:', sendError);
- showToast(`发送文件失败: ${fileName}`, "error");
-
- // 重置文件状态
- setFileList(prev => prev.map(item =>
- item.id === fileId || item.name === fileName
- ? { ...item, status: 'ready' as const, progress: 0 }
- : item
- ));
- }
- } else {
- console.warn('接收模式下收到文件请求,忽略');
- }
- });
-
- return cleanup;
- }, [onFileRequested, mode, selectedFiles, sendFile, isConnected, error]);
// 监听连接状态变化和清理传输状态
useEffect(() => {
diff --git a/chuan-next/src/hooks/file-transfer/useFileStateManager.ts b/chuan-next/src/hooks/file-transfer/useFileStateManager.ts
index 56e325a..0583839 100644
--- a/chuan-next/src/hooks/file-transfer/useFileStateManager.ts
+++ b/chuan-next/src/hooks/file-transfer/useFileStateManager.ts
@@ -115,40 +115,45 @@ export const useFileStateManager = ({
console.log('=== selectedFiles变化,同步文件列表 ===', {
selectedFilesCount: selectedFiles.length,
- fileListCount: fileList.length,
selectedFileNames: selectedFiles.map(f => f.name)
});
- // 根据selectedFiles创建新的文件信息列表
- const newFileInfos: FileInfo[] = selectedFiles.map(file => {
- // 尝试找到现有的文件信息,保持已有的状态
- const existingFileInfo = fileList.find(info => info.name === file.name && info.size === file.size);
- return existingFileInfo || {
- id: generateFileId(),
- name: file.name,
- size: file.size,
- type: file.type,
- status: 'ready' as const,
- progress: 0
- };
- });
-
- // 检查文件列表是否真正发生变化
- const fileListChanged =
- newFileInfos.length !== fileList.length ||
- newFileInfos.some(newFile =>
- !fileList.find(oldFile => oldFile.name === newFile.name && oldFile.size === newFile.size)
- );
-
- if (fileListChanged) {
- console.log('文件列表发生变化,更新:', {
- before: fileList.map(f => f.name),
- after: newFileInfos.map(f => f.name)
+ // 使用函数式更新获取当前fileList,避免依赖fileList
+ setFileList(currentFileList => {
+ // 根据selectedFiles创建新的文件信息列表
+ const newFileInfos: FileInfo[] = selectedFiles.map(file => {
+ // 尝试在当前fileList中找到现有的文件信息,保持已有的状态
+ const existingFileInfo = currentFileList.find(info => info.name === file.name && info.size === file.size);
+ return existingFileInfo || {
+ id: generateFileId(),
+ name: file.name,
+ size: file.size,
+ type: file.type,
+ status: 'ready' as const,
+ progress: 0
+ };
});
-
- setFileList(newFileInfos);
- }
- }, [selectedFiles, mode, pickupCode, fileList, generateFileId]);
+
+ // 检查文件列表是否真正发生变化
+ const fileListChanged =
+ newFileInfos.length !== currentFileList.length ||
+ newFileInfos.some(newFile =>
+ !currentFileList.find(oldFile => oldFile.name === newFile.name && oldFile.size === newFile.size)
+ );
+
+ if (fileListChanged) {
+ console.log('文件列表发生变化,更新:', {
+ before: currentFileList.map(f => f.name),
+ after: newFileInfos.map(f => f.name)
+ });
+
+ return newFileInfos;
+ }
+
+ // 如果没有变化,返回当前的fileList
+ return currentFileList;
+ });
+ }, [selectedFiles, mode, pickupCode, generateFileId]); // 移除fileList依赖,避免无限循环
return {
selectedFiles,
diff --git a/chuan-next/src/hooks/webrtc/WebSocketManager.ts b/chuan-next/src/hooks/webrtc/WebSocketManager.ts
index 117eb4a..f6df874 100644
--- a/chuan-next/src/hooks/webrtc/WebSocketManager.ts
+++ b/chuan-next/src/hooks/webrtc/WebSocketManager.ts
@@ -1,5 +1,5 @@
import { EventEmitter } from 'events';
-import { WebRTCError, WebRTCMessage, ConnectionEvent, EventHandler } from './types';
+import { WebRTCError, ConnectionEvent, EventHandler } from './types';
interface WebSocketManagerConfig {
url: string;
diff --git a/chuan-next/src/lib/webrtc-support.ts b/chuan-next/src/lib/webrtc-support.ts
index 80840ee..5ffbce4 100644
--- a/chuan-next/src/lib/webrtc-support.ts
+++ b/chuan-next/src/lib/webrtc-support.ts
@@ -43,6 +43,7 @@ export function detectWebRTCSupport(): WebRTCSupport {
pc.close();
}
} catch (error) {
+ console.warn(error);
missing.push('DataChannel');
}