| import React, { useState } from 'react'; |
| import PropTypes from 'prop-types'; |
| import axios from 'axios'; |
| import { saveAs } from 'file-saver'; |
| import Button from '@mui/material/Button'; |
| import LinearProgress from '@mui/material/LinearProgress'; |
| import Box from '@mui/material/Box'; |
| import Typography from '@mui/material/Typography'; |
| |
| function TorrentDownloadButton({ infoHash, title }) { |
| // 新增状态:下载进度(0~100) |
| const [progress, setProgress] = useState(0); |
| // 新增状态:是否正在下载 |
| const [downloading, setDownloading] = useState(false); |
| |
| const handleDownload = async () => { |
| try { |
| setDownloading(true); |
| setProgress(0); |
| // 1) 启动下载 |
| await axios.post('/api/torrents/download', null, { params: { infoHash } }); |
| |
| // 2) 轮询进度 |
| let p = 0; |
| while (p < 1) { |
| await new Promise(resolve => setTimeout(resolve, 1000)); |
| const res = await axios.get(`/api/torrents/download/status/${infoHash}`); |
| p = res.data; |
| setProgress(Math.round(p * 100)); |
| } |
| |
| // 3) 下载文件流 |
| const fileRes = await axios.get( |
| `/api/torrents/download/file/${infoHash}`, |
| { responseType: 'blob' } |
| ); |
| |
| // 4) 保存文件 |
| saveAs(fileRes.data, title); |
| } catch (err) { |
| console.error('下载过程中出错', err); |
| } finally { |
| setDownloading(false); |
| } |
| }; |
| |
| return ( |
| <Box sx={{ width: 200 }}> |
| <Button |
| variant="outlined" |
| color="success" |
| onClick={handleDownload} |
| disabled={downloading} |
| sx={{ |
| width: '100%', |
| fontSize: '0.85rem', |
| borderColor: '#4caf50', |
| '&:hover': { |
| backgroundColor: 'rgba(76, 175, 80, 0.15)', |
| borderColor: '#388e3c', |
| }, |
| }} |
| > |
| {downloading ? `下载中 ${progress}%` : '下载'} |
| </Button> |
| |
| {downloading && ( |
| <Box sx={{ mt: 1 }}> |
| <LinearProgress variant="determinate" value={progress} /> |
| <Typography variant="caption" display="block" align="center"> |
| {progress}% |
| </Typography> |
| </Box> |
| )} |
| </Box> |
| ); |
| } |
| |
| TorrentDownloadButton.propTypes = { |
| infoHash: PropTypes.string.isRequired, |
| title: PropTypes.string.isRequired, |
| }; |
| |
| export default TorrentDownloadButton; |