This commit is contained in:
seb
2026-10-08 21:19:15 +02:00
parent 7f988c9d63
commit f91c50ef69

View File

@@ -13,9 +13,9 @@ import chatAutomat, { selectPendingAskUser, selectHasPendingAsk } from '../../au
import { import {
CHAT_BUSY, CHAT_BUSY,
CHAT_FAB_BUSY, CHAT_FAB_BUSY,
CHAT_FAB_PENDING, CHAT_FAB_SHADOW_BUSY, CHAT_FAB_PENDING, CHAT_FAB_SHADOW_BUSY,
CHAT_FAB_SHADOW_IDLE, CHAT_FAB_SHADOW_IDLE,
CHAT_FAB_SHADOW_PENDING, RED, CHAT_FAB_SHADOW_PENDING, RED,
RED_GLOW, RED_GLOW,
WHITE, WHITE,
} from '../../colors'; } from '../../colors';
@@ -59,18 +59,12 @@ export default class ChatFab extends PureComponent {
const { isOpen, conversationState, streamPhase, isSending, hasPendingAsk, pendingAsk } = this.state; const { isOpen, conversationState, streamPhase, isSending, hasPendingAsk, pendingAsk } = this.state;
const isBusy = conversationState === 'busy' || streamPhase === 'thinking' || streamPhase === 'working' || isSending; const isBusy = conversationState === 'busy' || streamPhase === 'thinking' || streamPhase === 'working' || isSending;
let tooltipTitle = 'KI-Chat öffnen';
let ariaLabel = 'KI-Chat'; let ariaLabel = 'KI-Chat';
if (isOpen) { if (isOpen) {
tooltipTitle = 'KI-Chat schließen';
ariaLabel = 'KI-Chat schließen'; ariaLabel = 'KI-Chat schließen';
} else if (hasPendingAsk) { } else if (hasPendingAsk) {
tooltipTitle = pendingAsk?.question
? `Antwort erforderlich: „${pendingAsk.question}“`
: 'Antwort erforderlich: Das Modell wartet auf Ihre Eingabe';
ariaLabel = 'KI-Chat: Antwort erforderlich'; ariaLabel = 'KI-Chat: Antwort erforderlich';
} else if (isBusy) { } else if (isBusy) {
tooltipTitle = 'Modell antwortet gerade…';
ariaLabel = 'KI-Chat: Modell antwortet'; ariaLabel = 'KI-Chat: Modell antwortet';
} }
@@ -143,77 +137,75 @@ export default class ChatFab extends PureComponent {
/> />
)} )}
<Tooltip title={tooltipTitle} placement="right" arrow> <Badge
<Badge badgeContent={hasPendingAsk ? '?' : undefined}
badgeContent={hasPendingAsk ? '?' : undefined} color={hasPendingAsk ? 'error' : isBusy ? 'warning' : 'default'}
color={hasPendingAsk ? 'error' : isBusy ? 'warning' : 'default'} variant={hasPendingAsk ? 'standard' : 'dot'}
variant={hasPendingAsk ? 'standard' : 'dot'} invisible={!hasPendingAsk && !isBusy}
invisible={!hasPendingAsk && !isBusy} overlap="circular"
overlap="circular" anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }} sx={{
sx={{ '& .MuiBadge-badge': hasPendingAsk
'& .MuiBadge-badge': hasPendingAsk ? {
? { bgcolor: RED,
bgcolor: RED, color: WHITE,
color: WHITE, fontWeight: 900,
fontWeight: 900, fontSize: '0.85rem',
fontSize: '0.85rem', minWidth: 22,
minWidth: 22, height: 22,
height: 22, borderRadius: '50%',
borderRadius: '50%', boxShadow: `0 2px 10px ${RED_GLOW}`,
boxShadow: `0 2px 10px ${RED_GLOW}`, animation: 'badgePop 1.5s ease infinite',
animation: 'badgePop 1.5s ease infinite', '@keyframes badgePop': {
'@keyframes badgePop': { '0%, 100%': { transform: 'scale(1)' },
'0%, 100%': { transform: 'scale(1)' }, '50%': { transform: 'scale(1.2)' },
'50%': { transform: 'scale(1.2)' }, },
}, }
} : undefined,
: undefined, }}
}} >
> <Fab
<Fab color="primary"
color="primary" aria-label={ariaLabel}
aria-label={ariaLabel} onClick={this.handleClick}
onClick={this.handleClick} sx={(theme) => ({
sx={(theme) => ({ width: 54,
width: 54, height: 54,
height: 54, boxShadow: hasPendingAsk
boxShadow: hasPendingAsk ? CHAT_FAB_SHADOW_PENDING
? CHAT_FAB_SHADOW_PENDING : isBusy
: isBusy
? CHAT_FAB_SHADOW_BUSY ? CHAT_FAB_SHADOW_BUSY
: CHAT_FAB_SHADOW_IDLE, : CHAT_FAB_SHADOW_IDLE,
background: hasPendingAsk background: hasPendingAsk
? CHAT_FAB_PENDING ? CHAT_FAB_PENDING
: isBusy : isBusy
? CHAT_FAB_BUSY ? CHAT_FAB_BUSY
: `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 100%)`, : `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 100%)`,
})} })}
> >
{isOpen ? ( {isOpen ? (
<CloseRoundedIcon sx={{ fontSize: 24 }} /> <CloseRoundedIcon sx={{ fontSize: 24 }} />
) : hasPendingAsk ? ( ) : hasPendingAsk ? (
<HelpOutlineRoundedIcon <HelpOutlineRoundedIcon
sx={{ sx={{
fontSize: 26, fontSize: 26,
animation: 'fabWiggle 2s ease infinite', animation: 'fabWiggle 2s ease infinite',
'@keyframes fabWiggle': { '@keyframes fabWiggle': {
'0%, 100%': { transform: 'rotate(0deg)' }, '0%, 100%': { transform: 'rotate(0deg)' },
'15%': { transform: 'rotate(-12deg)' }, '15%': { transform: 'rotate(-12deg)' },
'30%': { transform: 'rotate(12deg)' }, '30%': { transform: 'rotate(12deg)' },
'45%': { transform: 'rotate(-8deg)' }, '45%': { transform: 'rotate(-8deg)' },
'60%': { transform: 'rotate(0deg)' }, '60%': { transform: 'rotate(0deg)' },
}, },
}} }}
/> />
) : isBusy ? ( ) : isBusy ? (
<AutoAwesomeRoundedIcon sx={{ fontSize: 24 }} /> <AutoAwesomeRoundedIcon sx={{ fontSize: 24 }} />
) : ( ) : (
<ChatRoundedIcon sx={{ fontSize: 24 }} /> <ChatRoundedIcon sx={{ fontSize: 24 }} />
)} )}
</Fab> </Fab>
</Badge> </Badge>
</Tooltip>
</Box> </Box>
</Box> </Box>
); );