mirror of
https://github.com/MatrixSeven/file-transfer-go.git
synced 2026-05-18 01:57:28 +08:00
feat:拆分hooks
This commit is contained in:
166
chuan-next/src/hooks/file-transfer/useFileStateManager.ts
Normal file
166
chuan-next/src/hooks/file-transfer/useFileStateManager.ts
Normal 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
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user