Просмотр исходного кода

fix(chat): 修复 AI 会话工作流模式下拉无法选中和流式气泡宽度问题

- chat-panel.tsx: 工作流模式 dropdown 通过 createPortal 渲染到 body,不在 trigger ref 子树内。mousedown 外部点击检测只检查了 trigger,选中下拉选项时立即关闭导致 onClick 丢失,aiWorkflowMode 永远停留在 standard。新增 workflowModeDropdownRef,handleMouseDown 同时检查 trigger 和 dropdown 容器,并在 listbox div 上挂载 ref。
- chat-message.tsx: StreamingMessage 气泡宽度从 max-w-[80%] 改为 flex-1,跟随 AI 会话面板宽度,不再随内容长度变化。
Mochocyang 2 месяцев назад
Родитель
Сommit
1fb1ce8932
2 измененных файлов с 6 добавлено и 2 удалено
  1. 1 1
      src/components/chat/chat-message.tsx
  2. 5 1
      src/components/chat/chat-panel.tsx

+ 1 - 1
src/components/chat/chat-message.tsx

@@ -705,7 +705,7 @@ export function StreamingMessage({ content }: StreamingMessageProps) {
       <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground">
         <Bot className="h-4 w-4" />
       </div>
-      <div className="max-w-[80%] rounded-lg border bg-background px-3 py-2 text-sm text-foreground">
+      <div className="flex-1 rounded-lg border bg-background px-3 py-2 text-sm text-foreground">
         {isThinking ? (
           <StreamingWorkflowBlock content={thinking} />
         ) : (

+ 5 - 1
src/components/chat/chat-panel.tsx

@@ -614,6 +614,7 @@ export function ChatPanel() {
   const [workflowModeDropdownOpen, setWorkflowModeDropdownOpen] = useState(false)
   const workflowModeTriggerRef = useRef<HTMLButtonElement>(null)
   const [workflowModeDropdownStyle, setWorkflowModeDropdownStyle] = useState<{ left: number; top: number; width: number } | null>(null)
+  const workflowModeDropdownRef = useRef<HTMLDivElement | null>(null)
   const planExecuteEnabled = useWikiStore((s) => s.planExecuteEnabled)
   const setPlanExecuteEnabled = useWikiStore((s) => s.setPlanExecuteEnabled)
   const [isSavingChapter, setIsSavingChapter] = useState(false)
@@ -715,7 +716,9 @@ export function ChatPanel() {
   useEffect(() => {
     if (!workflowModeDropdownOpen) return
     const handleMouseDown = (event: MouseEvent) => {
-      if (workflowModeTriggerRef.current?.contains(event.target as Node)) return
+      const target = event.target as Node
+      if (workflowModeTriggerRef.current?.contains(target)) return
+      if (workflowModeDropdownRef.current?.contains(target)) return
       setWorkflowModeDropdownOpen(false)
     }
     const handleKeyDown = (event: KeyboardEvent) => {
@@ -1850,6 +1853,7 @@ export function ChatPanel() {
                               onClick={() => setWorkflowModeDropdownOpen(false)}
                             />
                             <div
+                              ref={workflowModeDropdownRef}
                               role="listbox"
                               className="fixed rounded-md border bg-popover p-1 shadow-md"
                               style={{