import React, { useEffect, useMemo, useState } from 'react' import { createPortal } from 'react-dom' import { Loader2, X, Image as ImageIcon, Clock, CheckCircle, XCircle } from 'lucide-react' import { useBatchImageDecryptStore } from '../stores/batchImageDecryptStore' import { useBatchTranscribeStore } from '../stores/batchTranscribeStore' import '../styles/batchTranscribe.scss' export const BatchImageDecryptGlobal: React.FC = () => { const { isBatchDecrypting, progress, showToast, showResultToast, result, sessionName, startTime, setShowToast, setShowResultToast } = useBatchImageDecryptStore() const voiceToastOccupied = useBatchTranscribeStore( state => state.isBatchTranscribing && state.showToast ) const [eta, setEta] = useState('') useEffect(() => { if (!isBatchDecrypting || !startTime || progress.current === 0) { setEta('') return } const timer = setInterval(() => { const elapsed = Date.now() - startTime if (elapsed <= 0) return const rate = progress.current / elapsed const remain = progress.total - progress.current if (remain <= 0 || rate <= 0) { setEta('') return } const seconds = Math.ceil((remain / rate) / 1000) if (seconds < 60) { setEta(`${seconds}秒`) } else { const m = Math.floor(seconds / 60) const s = seconds % 60 setEta(`${m}分${s}秒`) } }, 1000) return () => clearInterval(timer) }, [isBatchDecrypting, progress.current, progress.total, startTime]) useEffect(() => { if (!showResultToast) return const timer = window.setTimeout(() => setShowResultToast(false), 6000) return () => window.clearTimeout(timer) }, [showResultToast, setShowResultToast]) const toastBottom = useMemo(() => (voiceToastOccupied ? 148 : 24), [voiceToastOccupied]) return ( <> {showToast && isBatchDecrypting && createPortal(