From 0fb33b9f5787e893623e2f91b8670cc5a76118ad Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Fri, 8 May 2026 00:41:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E9=87=8D=E6=9E=84=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=A0=B7=E5=BC=8F=E5=B9=B6=E6=B7=BB=E5=8A=A0=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E5=AF=B9=E8=AF=9D=E6=A1=86=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优化组件视觉风格: 使用渐变色、阴影和圆角增强现代感 - 添加 ConfirmDialog 组件和 useConfirm hook 用于确认操作 - 改进聊天界面: 添加滚动到底部按钮、斜杠命令自动弹出 - 统一组件间距和颜色方案,提升 UI 一致性 --- .../src/components/accounts/AccountCard.tsx | 20 ++--- .../components/assets/AssetProjectGroup.tsx | 18 ++--- web/client/src/components/chat/ChatInput.tsx | 14 +++- .../src/components/chat/ChatMessage.tsx | 42 ++++++----- web/client/src/components/chat/ChatView.tsx | 44 ++++++++--- .../src/components/chat/PipelineProgress.tsx | 16 ++-- .../src/components/layout/AppLayout.tsx | 2 +- .../src/components/layout/MiddlePanel.tsx | 38 +++++----- web/client/src/components/layout/Sidebar.tsx | 11 +-- web/client/src/components/ui/confirm.tsx | 74 +++++++++++++++++++ web/client/src/hooks/useConfirm.ts | 43 +++++++++++ web/client/src/index.css | 25 ++++--- 12 files changed, 254 insertions(+), 93 deletions(-) create mode 100644 web/client/src/components/ui/confirm.tsx create mode 100644 web/client/src/hooks/useConfirm.ts diff --git a/web/client/src/components/accounts/AccountCard.tsx b/web/client/src/components/accounts/AccountCard.tsx index 84d1d9b..fb7c158 100644 --- a/web/client/src/components/accounts/AccountCard.tsx +++ b/web/client/src/components/accounts/AccountCard.tsx @@ -1,4 +1,4 @@ -import { Video, Image, Square } from 'lucide-react'; +import { Video, Image } from 'lucide-react'; import type { Account } from '@/types'; const MODEL_LABELS: Record = { @@ -23,16 +23,16 @@ export function AccountCard({ account, isSelected, onClick }: Props) { return ( -
- +
+ {asset.type === 'image' ? 'IMG' : 'VID'} #{asset.shot_index ?? '?'}
diff --git a/web/client/src/components/chat/ChatInput.tsx b/web/client/src/components/chat/ChatInput.tsx index c27859c..a0e5c14 100644 --- a/web/client/src/components/chat/ChatInput.tsx +++ b/web/client/src/components/chat/ChatInput.tsx @@ -1,5 +1,5 @@ -import { useState, useRef } from 'react'; -import { Send, Terminal, Image, Play, FileText, ArrowUp } from 'lucide-react'; +import { useState, useRef, useEffect } from 'react'; +import { Terminal, Image, Play, FileText, ArrowUp } from 'lucide-react'; const SLASH_COMMANDS = [ { cmd: '/run', desc: '执行 pipeline 阶段', icon: Play }, @@ -19,6 +19,16 @@ export function ChatInput({ onSend, disabled }: { onSend: (content: string) => v ? SLASH_COMMANDS.filter((c) => c.cmd.startsWith(input.split(' ')[0])) : []; + // Auto-show/hide slash command menu + useEffect(() => { + if (input.startsWith('/') && matchingCmds.length > 0) { + setShowCmds(true); + setCmdIdx(0); + } else { + setShowCmds(false); + } + }, [input, matchingCmds.length]); + const handleSend = () => { if (!input.trim() || disabled) return; onSend(input.trim()); diff --git a/web/client/src/components/chat/ChatMessage.tsx b/web/client/src/components/chat/ChatMessage.tsx index b04c1e7..822e31d 100644 --- a/web/client/src/components/chat/ChatMessage.tsx +++ b/web/client/src/components/chat/ChatMessage.tsx @@ -60,19 +60,21 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti
{/* Avatar */}
- {isUser ? : } + {isUser ? : }
{/* Body */}
{/* Thinking indicator */} {state === 'thinking' && !message.content && !message.reasoningContent && ( -
+
- + 深度思考中...
@@ -96,7 +98,7 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti )} {(reasoningOpen || state !== 'done') && ( -
+
{message.reasoningContent}
)} @@ -106,16 +108,16 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti {/* Main content bubble */} {!(message.content === '(调用工具)' && state === 'done' && message.reasoningContent) && (
{state === 'streaming' && !message.content ? ( -
- - - +
+ + +
) : isUser ? (

{message.content}

@@ -125,27 +127,27 @@ export function ChatMessage({ message, isLast, isThinking, onRegenerate, onConti
)} - {/* Actions - visible on hover or when done */} + {/* Actions */} {showActions && ( -
+
diff --git a/web/client/src/components/chat/ChatView.tsx b/web/client/src/components/chat/ChatView.tsx index 1c68116..73e0313 100644 --- a/web/client/src/components/chat/ChatView.tsx +++ b/web/client/src/components/chat/ChatView.tsx @@ -6,7 +6,7 @@ import { ChatMessage } from './ChatMessage'; import { ChatInput } from './ChatInput'; import { PipelineProgress } from './PipelineProgress'; import { Button } from '@/components/ui/button'; -import { RefreshCw, Loader2, StopCircle, X, MessageCircle } from 'lucide-react'; +import { RefreshCw, Loader2, StopCircle, X, MessageCircle, ArrowDown } from 'lucide-react'; import { api } from '@/lib/api'; import type { Account, Message } from '@/types'; @@ -19,6 +19,7 @@ export function ChatView() { const [accounts, setAccounts] = useState([]); const [quote, setQuote] = useState(null); const [pendingMessage, setPendingMessage] = useState(null); + const [showScrollBtn, setShowScrollBtn] = useState(false); const creatingRef = useRef(false); const scrollRef = useRef(null); const userScrolledUp = useRef(false); @@ -54,6 +55,7 @@ export function ChatView() { const onScroll = () => { const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 80; userScrolledUp.current = !atBottom; + setShowScrollBtn(!atBottom); }; el.addEventListener('scroll', onScroll, { passive: true }); return () => el.removeEventListener('scroll', onScroll); @@ -62,6 +64,7 @@ export function ChatView() { // Reset scroll state on conversation switch useEffect(() => { userScrolledUp.current = false; + setShowScrollBtn(false); }, [conversationId]); // After navigating to a new conversation, send the pending message once history is loaded @@ -137,9 +140,12 @@ export function ChatView() { if (!conversationId) { const recentConvs = conversations.slice(0, 5); return ( -
+
+
+ +

开始新对话

输入消息开始创作,对话将自动创建

@@ -150,7 +156,7 @@ export function ChatView() { handleSearch(e.target.value)} />
))} {conversations.length === 0 && ( -
- -

暂无对话

-

点击上方「新对话」开始

+
+ +

暂无对话

+

点击上方「新对话」开始

)} diff --git a/web/client/src/components/layout/Sidebar.tsx b/web/client/src/components/layout/Sidebar.tsx index a1e7581..4a2b09a 100644 --- a/web/client/src/components/layout/Sidebar.tsx +++ b/web/client/src/components/layout/Sidebar.tsx @@ -11,21 +11,22 @@ const navItems = [ export function Sidebar() { return ( -