feat(web): 重构组件样式并添加确认对话框组件
- 优化组件视觉风格: 使用渐变色、阴影和圆角增强现代感 - 添加 ConfirmDialog 组件和 useConfirm hook 用于确认操作 - 改进聊天界面: 添加滚动到底部按钮、斜杠命令自动弹出 - 统一组件间距和颜色方案,提升 UI 一致性
This commit is contained in:
@@ -60,19 +60,21 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti
|
||||
<div className={cn('flex gap-3 mb-5 group/msg', isUser ? 'flex-row-reverse' : 'flex-row')}>
|
||||
{/* Avatar */}
|
||||
<div className={cn(
|
||||
'w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 text-xs',
|
||||
isUser ? 'bg-indigo-600 text-white' : 'bg-zinc-100 text-zinc-500'
|
||||
'w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 text-xs',
|
||||
isUser
|
||||
? 'bg-gradient-to-br from-indigo-500 to-indigo-600 text-white shadow-sm'
|
||||
: 'bg-zinc-100 text-zinc-500'
|
||||
)}>
|
||||
{isUser ? <User size={13} /> : <Bot size={13} />}
|
||||
{isUser ? <User size={14} /> : <Bot size={14} />}
|
||||
</div>
|
||||
|
||||
{/* Body */}
|
||||
<div className={cn('flex-1 max-w-[78%]', isUser && 'flex flex-col items-end')}>
|
||||
{/* Thinking indicator */}
|
||||
{state === 'thinking' && !message.content && !message.reasoningContent && (
|
||||
<div className="rounded-2xl px-3.5 py-2.5 bg-zinc-50 border border-zinc-100 rounded-tl-md">
|
||||
<div className="rounded-2xl px-4 py-3 bg-gradient-to-br from-indigo-50 to-zinc-50 border border-indigo-100/50 rounded-tl-sm">
|
||||
<div className="flex items-center gap-2 text-zinc-400 text-sm">
|
||||
<Brain size={14} className="animate-pulse" />
|
||||
<Brain size={14} className="animate-pulse text-indigo-400" />
|
||||
<span>深度思考中...</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,7 +98,7 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti
|
||||
)}
|
||||
</button>
|
||||
{(reasoningOpen || state !== 'done') && (
|
||||
<div className="mt-1 px-3 py-2 rounded-lg bg-indigo-50/50 border border-indigo-100 text-xs text-zinc-500 leading-relaxed max-h-60 overflow-y-auto whitespace-pre-wrap">
|
||||
<div className="mt-1 px-3 py-2.5 rounded-xl bg-gradient-to-br from-indigo-50/80 to-violet-50/40 border border-indigo-100/50 text-xs text-zinc-500 leading-relaxed max-h-60 overflow-y-auto whitespace-pre-wrap">
|
||||
{message.reasoningContent}
|
||||
</div>
|
||||
)}
|
||||
@@ -106,16 +108,16 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti
|
||||
{/* Main content bubble */}
|
||||
{!(message.content === '(调用工具)' && state === 'done' && message.reasoningContent) && (
|
||||
<div className={cn(
|
||||
'rounded-2xl px-3.5 py-2.5 text-sm leading-relaxed',
|
||||
'rounded-2xl px-4 py-2.5 text-sm leading-relaxed',
|
||||
isUser
|
||||
? 'bg-indigo-600 text-white rounded-tr-md'
|
||||
: 'bg-zinc-50 text-zinc-700 border border-zinc-100 rounded-tl-md'
|
||||
? 'bg-gradient-to-br from-indigo-500 to-indigo-600 text-white rounded-tr-sm shadow-sm'
|
||||
: 'bg-zinc-50/80 text-zinc-700 border border-zinc-100 rounded-tl-sm'
|
||||
)}>
|
||||
{state === 'streaming' && !message.content ? (
|
||||
<div className="flex items-center gap-1 text-zinc-400">
|
||||
<span className="inline-block w-1.5 h-1.5 bg-zinc-300 rounded-full animate-pulse" />
|
||||
<span className="inline-block w-1.5 h-1.5 bg-zinc-300 rounded-full animate-pulse [animation-delay:100ms]" />
|
||||
<span className="inline-block w-1.5 h-1.5 bg-zinc-300 rounded-full animate-pulse [animation-delay:200ms]" />
|
||||
<div className="flex items-center gap-1.5 text-zinc-400">
|
||||
<span className="inline-block w-1.5 h-1.5 bg-indigo-300 rounded-full animate-pulse" />
|
||||
<span className="inline-block w-1.5 h-1.5 bg-indigo-300 rounded-full animate-pulse [animation-delay:150ms]" />
|
||||
<span className="inline-block w-1.5 h-1.5 bg-indigo-300 rounded-full animate-pulse [animation-delay:300ms]" />
|
||||
</div>
|
||||
) : isUser ? (
|
||||
<p className="whitespace-pre-wrap">{message.content}</p>
|
||||
@@ -125,27 +127,27 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Actions - visible on hover or when done */}
|
||||
{/* Actions */}
|
||||
{showActions && (
|
||||
<div className="flex gap-0.5 mt-1 opacity-0 group-hover/msg:opacity-100 transition-opacity px-1">
|
||||
<div className="flex gap-0.5 mt-1 opacity-0 group-hover/msg:opacity-100 transition-opacity duration-200 px-1">
|
||||
<button onClick={handleCopy}
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded-md text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
<Copy size={10} />复制
|
||||
</button>
|
||||
<button onClick={() => onQuote?.(message.content)}
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded-md text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
<Quote size={10} />引用
|
||||
</button>
|
||||
<button onClick={handleDelete}
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-zinc-400 hover:text-red-500 hover:bg-red-50 transition-colors">
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded-md text-[10px] text-zinc-400 hover:text-red-500 hover:bg-red-50 transition-colors">
|
||||
<Trash2 size={10} />删除
|
||||
</button>
|
||||
<button onClick={() => onRegenerate?.(message.id)}
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded-md text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
<RefreshCw size={10} />重新生成
|
||||
</button>
|
||||
<button onClick={() => onContinue?.()}
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
className="flex items-center gap-1 px-1.5 py-0.5 rounded-md text-[10px] text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors">
|
||||
<ArrowRight size={10} />继续
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user