| | import { Box, Stack, Typography, IconButton, Tooltip } from '@mui/material'; |
| | import CloseIcon from '@mui/icons-material/Close'; |
| | import type { Message } from '@/types/agent'; |
| |
|
| | interface UserMessageProps { |
| | message: Message; |
| | |
| | isLastTurn?: boolean; |
| | |
| | onUndoTurn?: () => void; |
| | |
| | isProcessing?: boolean; |
| | } |
| |
|
| | export default function UserMessage({ |
| | message, |
| | isLastTurn = false, |
| | onUndoTurn, |
| | isProcessing = false, |
| | }: UserMessageProps) { |
| | const showUndo = isLastTurn && !isProcessing && !!onUndoTurn; |
| |
|
| | return ( |
| | <Stack |
| | direction="row" |
| | spacing={1.5} |
| | justifyContent="flex-end" |
| | alignItems="flex-start" |
| | sx={{ |
| | // Show the undo button when hovering the entire row |
| | '& .undo-btn': { |
| | opacity: 0, |
| | transition: 'opacity 0.15s ease', |
| | }, |
| | '&:hover .undo-btn': { |
| | opacity: 1, |
| | }, |
| | }} |
| | > |
| | {/* Undo button — visible on hover, left of the bubble */} |
| | {showUndo && ( |
| | <Box className="undo-btn" sx={{ display: 'flex', alignItems: 'center', mt: 0.75 }}> |
| | <Tooltip title="Remove this turn" placement="left"> |
| | <IconButton |
| | onClick={onUndoTurn} |
| | size="small" |
| | sx={{ |
| | width: 24, |
| | height: 24, |
| | color: 'var(--muted-text)', |
| | '&:hover': { |
| | color: 'var(--accent-red)', |
| | bgcolor: 'rgba(244,67,54,0.08)', |
| | }, |
| | }} |
| | > |
| | <CloseIcon sx={{ fontSize: 14 }} /> |
| | </IconButton> |
| | </Tooltip> |
| | </Box> |
| | )} |
| | |
| | <Box |
| | sx={{ |
| | maxWidth: { xs: '88%', md: '72%' }, |
| | bgcolor: 'var(--surface)', |
| | borderRadius: 1.5, |
| | borderTopRightRadius: 4, |
| | px: { xs: 1.5, md: 2.5 }, |
| | py: 1.5, |
| | border: '1px solid var(--border)', |
| | }} |
| | > |
| | <Typography |
| | variant="body1" |
| | sx={{ |
| | fontSize: '0.925rem', |
| | lineHeight: 1.65, |
| | color: 'var(--text)', |
| | whiteSpace: 'pre-wrap', |
| | wordBreak: 'break-word', |
| | }} |
| | > |
| | {message.content} |
| | </Typography> |
| | |
| | <Typography |
| | variant="caption" |
| | sx={{ |
| | display: 'block', |
| | textAlign: 'right', |
| | mt: 1, |
| | fontSize: '0.68rem', |
| | color: 'var(--muted-text)', |
| | opacity: 0.7, |
| | }} |
| | > |
| | {new Date(message.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} |
| | </Typography> |
| | </Box> |
| | </Stack> |
| | ); |
| | } |
| |
|