blob: a8a6177fcab70032ded1ba6f31b7372098053f2f [file] [log] [blame]
ZBD4b0e05a2025-06-08 18:11:26 +08001import React, { useState } from 'react';
2import PropTypes from 'prop-types';
3import axios from 'axios';
4import { saveAs } from 'file-saver';
5import Button from '@mui/material/Button';
6import LinearProgress from '@mui/material/LinearProgress';
7import Box from '@mui/material/Box';
8import Typography from '@mui/material/Typography';
9
10function TorrentDownloadButton({ infoHash, title }) {
11 // 新增状态:下载进度(0~100)
12 const [progress, setProgress] = useState(0);
13 // 新增状态:是否正在下载
14 const [downloading, setDownloading] = useState(false);
15
16 const handleDownload = async () => {
17 try {
18 setDownloading(true);
19 setProgress(0);
20 // 1) 启动下载
21 await axios.post('/api/torrents/download', null, { params: { infoHash } });
22
23 // 2) 轮询进度
24 let p = 0;
25 while (p < 1) {
26 await new Promise(resolve => setTimeout(resolve, 1000));
27 const res = await axios.get(`/api/torrents/download/status/${infoHash}`);
28 p = res.data;
29 setProgress(Math.round(p * 100));
30 }
31
32 // 3) 下载文件流
33 const fileRes = await axios.get(
34 `/api/torrents/download/file/${infoHash}`,
35 { responseType: 'blob' }
36 );
37
38 // 4) 保存文件
39 saveAs(fileRes.data, title);
40 } catch (err) {
41 console.error('下载过程中出错', err);
42 } finally {
43 setDownloading(false);
44 }
45 };
46
47 return (
48 <Box sx={{ width: 200 }}>
49 <Button
50 variant="outlined"
51 color="success"
52 onClick={handleDownload}
53 disabled={downloading}
54 sx={{
55 width: '100%',
56 fontSize: '0.85rem',
57 borderColor: '#4caf50',
58 '&:hover': {
59 backgroundColor: 'rgba(76, 175, 80, 0.15)',
60 borderColor: '#388e3c',
61 },
62 }}
63 >
64 {downloading ? `下载中 ${progress}%` : '下载'}
65 </Button>
66
67 {downloading && (
68 <Box sx={{ mt: 1 }}>
69 <LinearProgress variant="determinate" value={progress} />
70 <Typography variant="caption" display="block" align="center">
71 {progress}%
72 </Typography>
73 </Box>
74 )}
75 </Box>
76 );
77}
78
79TorrentDownloadButton.propTypes = {
80 infoHash: PropTypes.string.isRequired,
81 title: PropTypes.string.isRequired,
82};
83
84export default TorrentDownloadButton;