diff --git a/frontend/components/ClipboardApp.tsx b/frontend/components/ClipboardApp.tsx index 8c5115b..1b08972 100644 --- a/frontend/components/ClipboardApp.tsx +++ b/frontend/components/ClipboardApp.tsx @@ -51,40 +51,16 @@ const ClipboardApp = () => { // 简化的 WebRTC 连接初始化 const { - sharePeerCount, - retrievePeerCount, - broadcastDataToAllPeers, requestFile, requestFolder, setReceiverDirectoryHandle, getReceiverSaveType, - senderDisconnected, - resetReceiverConnection, - resetSenderConnection, manualSafeSave, } = useWebRTCConnection({ messages, putMessageInMs, }); - const resetAppState = useCallback(async () => { - try { - // Reset file transfer state - useFileTransferStore.getState().resetReceiverState(); - - // Reset WebRTC connection state - await resetReceiverConnection(); - - // Reset room input - setRetrieveRoomIdInput(""); - - console.log("Application state reset successfully"); - } catch (error) { - console.error("Error during state reset:", error); - window.location.reload(); - } - }, [resetReceiverConnection, setRetrieveRoomIdInput]); - // 大大简化的房间管理 - 不再需要传递任何 WebRTC 依赖 const { processRoomIdInput, diff --git a/frontend/components/ClipboardApp/FileListDisplay.tsx b/frontend/components/ClipboardApp/FileListDisplay.tsx index f66401a..65f204b 100644 --- a/frontend/components/ClipboardApp/FileListDisplay.tsx +++ b/frontend/components/ClipboardApp/FileListDisplay.tsx @@ -11,6 +11,8 @@ import { getDictionary } from "@/lib/dictionary"; import { useLocale } from "@/hooks/useLocale"; import type { Messages } from "@/types/messages"; import { useFileTransferStore } from "@/stores/fileTransferStore"; +import { supportsAutoDownload } from "@/lib/browserUtils"; +import { postLogToBackend } from "@/app/config/api"; function formatFolderDis(template: string, num: number, size: string) { return template.replace("{num}", num.toString()).replace("{size}", size); @@ -78,6 +80,11 @@ const FileListDisplay: React.FC = ({ // Add a ref to store the previous showFinished state const prevShowFinishedRef = useRef<{ [fileId: string]: boolean }>({}); + // 添加待保存状态 - 用于非Chrome浏览器的手动保存 + const [pendingSave, setPendingSave] = useState<{ + [fileId: string]: boolean; + }>({}); + const [pickedLocation, setPickedLocation] = useState(false); // Whether a save directory has been selected const [needPickLocation, setNeedPickLocation] = useState(false); // Whether a save directory needs to be selected -- for large files, folders, or user choice @@ -92,6 +99,19 @@ const FileListDisplay: React.FC = ({ [fileId: string]: number; }>({}); + // 处理手动保存 - 用于非Chrome浏览器 + const handleManualSave = (item: FileMeta) => { + if (onDownload) { + onDownload(item); + // 清除待保存状态,让UI显示为"已完成" + setPendingSave((prev) => { + const updated = { ...prev }; + delete updated[item.fileId]; + return updated; + }); + } + }; + useEffect(() => { getDictionary(locale) .then((dict) => setMessages(dict)) @@ -237,7 +257,29 @@ const FileListDisplay: React.FC = ({ // Detecting false -> true transitions if (!prevShowFinished && currentShowFinished) { if (!isSaveToDisk && onDownload) { - onDownload(item); + const isAutoDownloadSupported = supportsAutoDownload(); + + // 根据浏览器能力决定下载行为 + if (isAutoDownloadSupported) { + // Chrome等支持自动下载的浏览器:直接下载 + postLogToBackend( + `[Firefox Debug] Auto-downloading file: ${item.name}` + ); + onDownload(item); + } else { + // 非Chrome浏览器:设置为待保存状态,等待用户手动点击 + postLogToBackend( + `[Firefox Debug] Setting pendingSave for non-Chrome browser: ${item.name}` + ); + setPendingSave((prev) => ({ + ...prev, + [item.fileId]: true, + })); + } + } else { + postLogToBackend( + `[Firefox Debug] Skipping download logic - isSaveToDisk: ${isSaveToDisk}, onDownload: ${!!onDownload}` + ); } // Increase download count - 文件传输完成时增加下载次数 (只计算一次) @@ -250,22 +292,17 @@ const FileListDisplay: React.FC = ({ // Update the last status prevShowFinishedRef.current[item.fileId] = currentShowFinished; }); - }, [ - showFinished, - singleFiles, - folders, - saveType, - onDownload, - downloadCounts, - ]); + }, [showFinished, singleFiles, folders, saveType, onDownload]); //Actions corresponding to each file - progress, download, delete const renderItemActions = (item: FileMeta) => { const fileProgress = fileProgresses[item.fileId]; const activePeerId = activeTransfers[item.fileId]; const progress = activePeerId ? fileProgress?.[activePeerId] : null; - const showCompletion = showFinished[item.fileId]; + const showCompletion = + showFinished[item.fileId] && !pendingSave[item.fileId]; // 只有传输完成且不在待保存状态时才显示完成 const isSaveToDisk = saveType ? saveType[item.fileId] : false; + const isPendingSave = pendingSave[item.fileId] || false; // Get download count const downloadCount = downloadCounts[item.fileId] || 0; @@ -297,6 +334,7 @@ const FileListDisplay: React.FC = ({ onDownload && ( //Request && Download onRequest(item)} + onSave={() => handleManualSave(item)} isCurrentFileTransferring={ progress ? progress.progress > 0 && progress.progress < 1 @@ -304,6 +342,7 @@ const FileListDisplay: React.FC = ({ } isOtherFileTransferring={isAnyFileTransferring && !progress} isSavedToDisk={saveType ? saveType[item.fileId] : false} + isPendingSave={isPendingSave} /> )} {/* display download Num*/} diff --git a/frontend/components/ClipboardApp/FileTransferButton.tsx b/frontend/components/ClipboardApp/FileTransferButton.tsx index 8fdfbf9..7057167 100644 --- a/frontend/components/ClipboardApp/FileTransferButton.tsx +++ b/frontend/components/ClipboardApp/FileTransferButton.tsx @@ -13,22 +13,28 @@ import type { Messages } from "@/types/messages"; interface FileTransferButtonProps { onRequest: () => void; + onSave?: () => void; // 新增:处理手动保存 isCurrentFileTransferring: boolean; isOtherFileTransferring: boolean; isSavedToDisk: boolean; + isPendingSave?: boolean; // 新增:是否待保存状态 } // Manage buttons for different download statuses const FileTransferButton = ({ onRequest, + onSave, isCurrentFileTransferring, isOtherFileTransferring, isSavedToDisk, + isPendingSave = false, }: FileTransferButtonProps) => { const locale = useLocale(); const [messages, setMessages] = useState(null); - // Button status judgment + // Button status judgment - 待保存状态时按钮应该可点击 const isDisabled = - isCurrentFileTransferring || isSavedToDisk || isOtherFileTransferring; + isCurrentFileTransferring || + isSavedToDisk || + (isOtherFileTransferring && !isPendingSave); useEffect(() => { getDictionary(locale) @@ -41,6 +47,8 @@ const FileTransferButton = ({ return messages!.text.FileTransferButton.SavedToDisk_tips; if (isCurrentFileTransferring) return messages!.text.FileTransferButton.CurrentFileTransferring_tips; + if (isPendingSave) + return messages!.text.FileTransferButton.PendingSave_tips; if (isOtherFileTransferring) return messages!.text.FileTransferButton.OtherFileTransferring_tips; return messages!.text.FileTransferButton.download_tips; @@ -60,6 +68,12 @@ const FileTransferButton = ({ className: "mr-2 cursor-not-allowed", }; } + if (isPendingSave) { + return { + variant: "default" as const, // 使用更明显的样式 + className: "mr-2 bg-green-600 hover:bg-green-700 text-white", + }; + } if (isOtherFileTransferring) { return { variant: "outline" as const, @@ -83,7 +97,7 @@ const FileTransferButton = ({