'use client'; import React, { useState, useEffect } from 'react'; import { useDownload } from '@/contexts/DownloadContext'; export function DownloadBubble() { const { tasks, downloadingCount, setShowDownloadPanel } = useDownload(); // 拖动状态 const [position, setPosition] = useState({ x: 0, y: 0 }); const [isDragging, setIsDragging] = useState(false); const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 }); // 初始化位置(右下角) useEffect(() => { const initPosition = () => { setPosition({ x: window.innerWidth - 80, y: window.innerHeight - 80 }); }; initPosition(); window.addEventListener('resize', initPosition); return () => window.removeEventListener('resize', initPosition); }, []); // 处理拖动 useEffect(() => { const handleMouseMove = (e: MouseEvent) => { if (!isDragging) return; const newX = e.clientX - dragOffset.x; const newY = e.clientY - dragOffset.y; // 限制在视口范围内 const maxX = window.innerWidth - 64; const maxY = window.innerHeight - 64; setPosition({ x: Math.max(0, Math.min(newX, maxX)), y: Math.max(0, Math.min(newY, maxY)) }); }; const handleTouchMove = (e: TouchEvent) => { if (!isDragging) return; e.preventDefault(); const touch = e.touches[0]; const newX = touch.clientX - dragOffset.x; const newY = touch.clientY - dragOffset.y; // 限制在视口范围内 const maxX = window.innerWidth - 64; const maxY = window.innerHeight - 64; setPosition({ x: Math.max(0, Math.min(newX, maxX)), y: Math.max(0, Math.min(newY, maxY)) }); }; const handleEnd = () => { setIsDragging(false); }; if (isDragging) { document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleEnd); document.addEventListener('touchmove', handleTouchMove, { passive: false }); document.addEventListener('touchend', handleEnd); } return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleEnd); document.removeEventListener('touchmove', handleTouchMove); document.removeEventListener('touchend', handleEnd); }; }, [isDragging, dragOffset]); const handleMouseDown = (e: React.MouseEvent) => { if (e.button !== 0) return; setIsDragging(true); const rect = e.currentTarget.getBoundingClientRect(); setDragOffset({ x: e.clientX - rect.left, y: e.clientY - rect.top }); }; const handleTouchStart = (e: React.TouchEvent) => { setIsDragging(true); const touch = e.touches[0]; const rect = e.currentTarget.getBoundingClientRect(); setDragOffset({ x: touch.clientX - rect.left, y: touch.clientY - rect.top }); }; if (tasks.length === 0) { return null; } return (
); }