import { useState, useRef, useEffect } from 'react'; import { Box, Paper, Typography, Button, LinearProgress, CircularProgress, Alert, Chip, Collapse, IconButton, Tooltip, Fade, Avatar } from '@mui/material'; import { useTheme, alpha } from '@mui/material/styles'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; import ThumbDownIcon from '@mui/icons-material/ThumbDown'; import ThumbsUpDownIcon from '@mui/icons-material/ThumbsUpDown'; import RefreshIcon from '@mui/icons-material/Refresh'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import PsychologyIcon from '@mui/icons-material/Psychology'; import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import AssignmentIcon from '@mui/icons-material/Assignment'; import SmartToyIcon from '@mui/icons-material/SmartToy'; import { useTranslation } from 'react-i18next'; import ReactMarkdown from 'react-markdown'; import 'github-markdown-css/github-markdown-light.css'; import { blindTestStyles } from '@/styles/blindTest'; function AnswerBox({ title, modelLabel, answer, streaming, showThinking, setShowThinking, scrollRef, styles, theme }) { const { t } = useTranslation(); const isLeft = modelLabel === 'A'; const avatarColor = isLeft ? 'primary.main' : 'secondary.main'; return ( {modelLabel} {title} {streaming && } {answer?.duration > 0 && !streaming && ( )} {answer?.error ? ( {answer.error} ) : ( {/* 思维链渲染 */} {answer?.thinking && ( setShowThinking(!showThinking)} > {answer.isThinking ? ( ) : ( )} {t('playground.reasoningProcess', '推理过程')} {showThinking ? : } {answer.thinking} )} {answer?.content ? (
{answer.content}
) : streaming ? ( {t('blindTest.generatingAnswers', '正在生成回答...')} ) : null}
)}
); } export default function BlindTestInProgress({ task, currentQuestion, leftAnswer, rightAnswer, streamingA, streamingB, answersLoading, voting, onVote, onReload }) { const { t } = useTranslation(); const theme = useTheme(); const styles = blindTestStyles(theme); const [showThinkingLeft, setShowThinkingLeft] = useState(true); const [showThinkingRight, setShowThinkingRight] = useState(true); // 自动滚动引用 const leftScrollRef = useRef(null); const rightScrollRef = useRef(null); // 处理自动滚动 useEffect(() => { if (streamingA && leftScrollRef.current) { leftScrollRef.current.scrollTop = leftScrollRef.current.scrollHeight; } }, [leftAnswer?.content, leftAnswer?.thinking, streamingA]); useEffect(() => { if (streamingB && rightScrollRef.current) { rightScrollRef.current.scrollTop = rightScrollRef.current.scrollHeight; } }, [rightAnswer?.content, rightAnswer?.thinking, streamingB]); const progress = task ? (task.completedCount / task.totalCount) * 100 : 0; if (answersLoading && !currentQuestion) { return ( {t('blindTest.generatingAnswers', '正在准备题目...')} ); } if (!currentQuestion) { return ( ); } return ( {/* 顶部进度和问题 */} {t('blindTest.progress', '进度')} {task.completedCount + 1}/{task.totalCount} {currentQuestion.question} {/* 回答区域 */} {/* 底部投票区域 */} {t('blindTest.referenceAnswer', '参考答案')} {currentQuestion.answer} ) : ( t('blindTest.noReferenceAnswer', '暂无参考答案') ) } arrow placement="top" TransitionComponent={Fade} TransitionProps={{ timeout: 600 }} componentsProps={{ tooltip: { sx: { bgcolor: theme.palette.mode === 'dark' ? 'grey.900' : 'background.paper', color: 'text.primary', boxShadow: theme.shadows[8], border: `1px solid ${theme.palette.divider}`, p: 0, '& .MuiTooltip-arrow': { color: theme.palette.mode === 'dark' ? 'grey.900' : 'background.paper', '&::before': { border: `1px solid ${theme.palette.divider}` } } } } }} > ); }