import { message, Progress, Spin, theme } from 'antd'; import React, { useState, useEffect, useRef, ReactNode, CSSProperties } from 'react'; import { useLocalSettings } from '@web/src/hooks/useLocalSetting'; import { uploaderPromise } from '@web/src/io'; interface ImageUploaderProps { value?: string; onChange?: (url: string) => void; className?: string; // Add className prop placeholder?: ReactNode style?: CSSProperties } const ImageUploader: React.FC = ({ style, value, onChange, className, placeholder = '点击上传' }) => { const [file, setFile] = useState(null); const [previewUrl, setPreviewUrl] = useState(value || ''); const [uploadProgress, setUploadProgress] = useState(0); const [uploadSpeed, setUploadSpeed] = useState(0); const [uploading, setUploading] = useState(false) const inputRef = useRef(null); const { token } = theme.useToken() const { tusUrl } = useLocalSettings() const handleFileChange = async (event: React.ChangeEvent) => { const selectedFile = event.target.files?.[0]; if (selectedFile) { setFile(selectedFile); setPreviewUrl(URL.createObjectURL(selectedFile)); } }; useEffect(() => { const handleUpload = async () => { if (!file) return; try { const endpoint = tusUrl; setUploading(true) const resultUrl = await uploaderPromise(endpoint, file, (percentage, speed) => { setUploadProgress(percentage); setUploadSpeed(speed); }); setUploadProgress(0); // Reset upload progress to hide overlay // Call the onChange callback with the uploaded URL if (onChange) { onChange(resultUrl); } } catch (error) { message.error('图片上传失败'); } finally { setUploading(false) } }; if (file) { handleUpload(); } }, [file]); // Effect to update previewUrl when the value prop changes useEffect(() => { if (!value) { setFile(null); setPreviewUrl(''); } else { setPreviewUrl(value); } }, [value]); const handleAreaClick = () => { inputRef.current?.click(); }; return ( <>
{previewUrl ? ( <> Selected {uploading && (
)} ) : ( {placeholder} )}
); }; export default ImageUploader;