feat:拆分hooks

This commit is contained in:
MatrixSeven
2025-08-28 16:19:09 +08:00
parent bc01224c11
commit 4bf0ce447d
36 changed files with 855 additions and 451 deletions

View File

@@ -0,0 +1,166 @@
import { useState, useCallback, useEffect } from 'react';
interface FileInfo {
id: string;
name: string;
size: number;
type: string;
status: 'ready' | 'downloading' | 'completed';
progress: number;
}
interface UseFileStateManagerProps {
mode: 'send' | 'receive';
pickupCode: string;
syncFileListToReceiver: (fileInfos: FileInfo[], reason: string) => void;
isPeerConnected: boolean;
}
export const useFileStateManager = ({
mode,
pickupCode,
syncFileListToReceiver,
isPeerConnected
}: UseFileStateManagerProps) => {
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
const [fileList, setFileList] = useState<FileInfo[]>([]);
const [downloadedFiles, setDownloadedFiles] = useState<Map<string, File>>(new Map());
// 生成文件ID
const generateFileId = useCallback(() => {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}, []);
// 文件选择处理
const handleFileSelect = useCallback((files: File[]) => {
console.log('=== 文件选择 ===');
console.log('新文件:', files.map(f => f.name));
// 更新选中的文件
setSelectedFiles(prev => [...prev, ...files]);
// 创建对应的文件信息
const newFileInfos: FileInfo[] = files.map(file => ({
id: generateFileId(),
name: file.name,
size: file.size,
type: file.type,
status: 'ready',
progress: 0
}));
setFileList(prev => {
const updatedList = [...prev, ...newFileInfos];
console.log('更新后的文件列表:', updatedList);
return updatedList;
});
}, [generateFileId]);
// 清空文件
const clearFiles = useCallback(() => {
console.log('=== 清空文件 ===');
setSelectedFiles([]);
setFileList([]);
}, []);
// 重置状态
const resetFiles = useCallback(() => {
console.log('=== 重置文件状态 ===');
setSelectedFiles([]);
setFileList([]);
setDownloadedFiles(new Map());
}, []);
// 更新文件状态
const updateFileStatus = useCallback((fileId: string, status: FileInfo['status'], progress?: number) => {
setFileList(prev => prev.map(item =>
item.id === fileId
? { ...item, status, progress: progress ?? item.progress }
: item
));
}, []);
// 更新文件进度
const updateFileProgress = useCallback((fileId: string, fileName: string, progress: number) => {
const newStatus = progress >= 100 ? 'completed' as const : 'downloading' as const;
setFileList(prev => prev.map(item => {
if (item.id === fileId || item.name === fileName) {
console.log(`更新文件 ${item.name} 进度: ${item.progress} -> ${progress}`);
return { ...item, progress, status: newStatus };
}
return item;
}));
}, []);
// 数据通道第一次打开时初始化
useEffect(() => {
if (isPeerConnected && mode === 'send' && fileList.length > 0) {
console.log('P2P连接已建立数据通道首次打开初始化文件列表');
syncFileListToReceiver(fileList, '数据通道初始化');
}
}, [isPeerConnected, mode, syncFileListToReceiver]);
// 监听fileList大小变化并同步
useEffect(() => {
if (isPeerConnected && mode === 'send' && pickupCode) {
console.log('fileList大小变化同步到接收方:', fileList.length);
syncFileListToReceiver(fileList, 'fileList大小变化');
}
}, [fileList.length, isPeerConnected, mode, pickupCode, syncFileListToReceiver]);
// 监听selectedFiles变化同步更新fileList
useEffect(() => {
// 只有在发送模式下且已有房间时才处理文件列表同步
if (mode !== 'send' || !pickupCode) return;
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)
});
setFileList(newFileInfos);
}
}, [selectedFiles, mode, pickupCode, fileList, generateFileId]);
return {
selectedFiles,
setSelectedFiles,
fileList,
setFileList,
downloadedFiles,
setDownloadedFiles,
handleFileSelect,
clearFiles,
resetFiles,
updateFileStatus,
updateFileProgress
};
};