1- import React , { useState , useMemo , useRef , forwardRef , useImperativeHandle , useCallback } from 'react'
1+ import React , {
2+ useState ,
3+ useMemo ,
4+ useRef ,
5+ forwardRef ,
6+ useImperativeHandle ,
7+ useCallback
8+ } from 'react'
29import { usePagesStore } from '../../../stores/pagesStore'
310import { useTabsStore } from '../../../stores/tabsStore'
411import { useUIStore } from '../../../stores/uiStore'
@@ -65,14 +72,20 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref)
6572 } , [ chat ?. messages ] )
6673
6774 // 处理分支切换(所有消息都使用兄弟分支切换)
68- const handleSwitchBranch = useCallback ( ( messageId : string , branchIndex : number ) => {
69- const newPath = messageTree . switchToSiblingBranch ( messageId , branchIndex )
70- updateCurrentPath ( chatId , newPath )
71- } , [ messageTree , updateCurrentPath , chatId ] )
75+ const handleSwitchBranch = useCallback (
76+ ( messageId : string , branchIndex : number ) => {
77+ const newPath = messageTree . switchToSiblingBranch ( messageId , branchIndex )
78+ updateCurrentPath ( chatId , newPath )
79+ } ,
80+ [ messageTree , updateCurrentPath , chatId ]
81+ )
7282
73- const handleToggleMessageCollapse = useCallback ( ( messageId : string ) => {
74- toggleMessageCollapse ( chatId , messageId )
75- } , [ toggleMessageCollapse , chatId ] )
83+ const handleToggleMessageCollapse = useCallback (
84+ ( messageId : string ) => {
85+ toggleMessageCollapse ( chatId , messageId )
86+ } ,
87+ [ toggleMessageCollapse , chatId ]
88+ )
7689
7790 const handleCollapseAll = useCallback ( ( ) => {
7891 collapseAllMessages (
@@ -94,92 +107,101 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref)
94107 setMessageTreeCollapsed ( ! messageTreeCollapsed )
95108 } , [ messageTreeCollapsed ] )
96109
97- const handleMessageTreeNodeSelect = useCallback ( ( messageId : string ) => {
98- if ( ! chat ?. messages ) return
110+ const handleMessageTreeNodeSelect = useCallback (
111+ ( messageId : string ) => {
112+ if ( ! chat ?. messages ) return
99113
100- // 设置选中的消息ID,用于滚动
101- setSelectedMessageId ( messageId )
114+ // 设置选中的消息ID,用于滚动
115+ setSelectedMessageId ( messageId )
102116
103- const messageMap = new Map < string , ChatMessage > ( )
104- chat . messages . forEach ( ( msg ) => {
105- messageMap . set ( msg . id , msg )
106- } )
117+ const messageMap = new Map < string , ChatMessage > ( )
118+ chat . messages . forEach ( ( msg ) => {
119+ messageMap . set ( msg . id , msg )
120+ } )
107121
108- // 构建从根节点到选中节点的路径
109- const pathToSelected : string [ ] = [ ]
110- let currentMsg = messageMap . get ( messageId )
111- while ( currentMsg ) {
112- pathToSelected . unshift ( currentMsg . id )
113- if ( currentMsg . parentId ) {
114- currentMsg = messageMap . get ( currentMsg . parentId )
115- } else {
116- break
122+ // 构建从根节点到选中节点的路径
123+ const pathToSelected : string [ ] = [ ]
124+ let currentMsg = messageMap . get ( messageId )
125+ while ( currentMsg ) {
126+ pathToSelected . unshift ( currentMsg . id )
127+ if ( currentMsg . parentId ) {
128+ currentMsg = messageMap . get ( currentMsg . parentId )
129+ } else {
130+ break
131+ }
117132 }
118- }
119133
120- // 如果选中的节点在当前路径中,需要保持到叶子节点的完整路径
121- if ( chat . currentPath && chat . currentPath . includes ( messageId ) ) {
122- // 找到选中节点在当前路径中的位置
123- const selectedIndex = chat . currentPath . findIndex ( id => id === messageId )
124- if ( selectedIndex !== - 1 ) {
125- // 从根节点到选中节点的路径 + 选中节点之后的原路径
126- const afterSelected = chat . currentPath . slice ( selectedIndex + 1 )
127- const newPath = [ ...pathToSelected , ...afterSelected ]
128- updateCurrentPath ( chatId , newPath )
129- return
134+ // 如果选中的节点在当前路径中,需要保持到叶子节点的完整路径
135+ if ( chat . currentPath && chat . currentPath . includes ( messageId ) ) {
136+ // 找到选中节点在当前路径中的位置
137+ const selectedIndex = chat . currentPath . findIndex ( ( id ) => id === messageId )
138+ if ( selectedIndex !== - 1 ) {
139+ // 从根节点到选中节点的路径 + 选中节点之后的原路径
140+ const afterSelected = chat . currentPath . slice ( selectedIndex + 1 )
141+ const newPath = [ ...pathToSelected , ...afterSelected ]
142+ updateCurrentPath ( chatId , newPath )
143+ return
144+ }
130145 }
131- }
132146
133- // 如果不在当前路径中,则需要延续到第一个子节点的路径
134- let extendedPath = [ ...pathToSelected ]
135- let lastNode = messageMap . get ( messageId )
136-
137- // 如果该节点有子节点,默认选择第一个子节点并延续路径
138- while ( lastNode && lastNode . children && lastNode . children . length > 0 ) {
139- const firstChild = messageMap . get ( lastNode . children [ 0 ] )
140- if ( firstChild ) {
141- extendedPath . push ( firstChild . id )
142- lastNode = firstChild
143- } else {
144- break
147+ // 如果不在当前路径中,则需要延续到第一个子节点的路径
148+ let extendedPath = [ ...pathToSelected ]
149+ let lastNode = messageMap . get ( messageId )
150+
151+ // 如果该节点有子节点,默认选择第一个子节点并延续路径
152+ while ( lastNode && lastNode . children && lastNode . children . length > 0 ) {
153+ const firstChild = messageMap . get ( lastNode . children [ 0 ] )
154+ if ( firstChild ) {
155+ extendedPath . push ( firstChild . id )
156+ lastNode = firstChild
157+ } else {
158+ break
159+ }
145160 }
146- }
147161
148- // 更新当前路径
149- updateCurrentPath ( chatId , extendedPath )
150- } , [ chat ?. messages , chat ?. currentPath , updateCurrentPath , chatId ] )
162+ // 更新当前路径
163+ updateCurrentPath ( chatId , extendedPath )
164+ } ,
165+ [ chat ?. messages , chat ?. currentPath , updateCurrentPath , chatId ]
166+ )
151167
152- const handleMessageTreePathChange = useCallback ( ( path : string [ ] ) => {
153- // 更新当前路径
154- updateCurrentPath ( chatId , path )
155- } , [ updateCurrentPath , chatId ] )
168+ const handleMessageTreePathChange = useCallback (
169+ ( path : string [ ] ) => {
170+ // 更新当前路径
171+ updateCurrentPath ( chatId , path )
172+ } ,
173+ [ updateCurrentPath , chatId ]
174+ )
156175
157176 const handleMessageTreeWidthChange = useCallback ( ( width : number ) => {
158177 setMessageTreeWidth ( width )
159178 localStorage . setItem ( 'messageTreeWidth' , width . toString ( ) )
160179 } , [ ] )
161180
162- const handleAutoQuestionChange = useCallback ( ( enabled : boolean , mode : 'ai' | 'preset' , listId ?: string ) => {
163- console . log ( 'ChatWindow handleAutoQuestionChange:' , {
164- enabled,
165- mode,
166- listId,
167- currentEnabled : autoQuestionEnabled ,
168- currentMode : autoQuestionMode ,
169- currentListId : autoQuestionListId
170- } )
181+ const handleAutoQuestionChange = useCallback (
182+ ( enabled : boolean , mode : 'ai' | 'preset' , listId ?: string ) => {
183+ console . log ( 'ChatWindow handleAutoQuestionChange:' , {
184+ enabled,
185+ mode,
186+ listId,
187+ currentEnabled : autoQuestionEnabled ,
188+ currentMode : autoQuestionMode ,
189+ currentListId : autoQuestionListId
190+ } )
171191
172- setAutoQuestionEnabled ( enabled )
173- setAutoQuestionMode ( mode )
174- if ( listId ) {
175- setAutoQuestionListId ( listId )
176- } else if ( mode === 'preset' && ! listId && settings . promptLists ?. length > 0 ) {
177- // 如果选择预设模式但没有指定listId,使用默认的
178- const defaultListId = settings . defaultPromptListId || settings . promptLists [ 0 ] . id
179- setAutoQuestionListId ( defaultListId )
180- console . log ( 'ChatWindow 自动设置 defaultListId:' , defaultListId )
181- }
182- } , [ settings . promptLists , settings . defaultPromptListId ] )
192+ setAutoQuestionEnabled ( enabled )
193+ setAutoQuestionMode ( mode )
194+ if ( listId ) {
195+ setAutoQuestionListId ( listId )
196+ } else if ( mode === 'preset' && ! listId && settings . promptLists ?. length > 0 ) {
197+ // 如果选择预设模式但没有指定listId,使用默认的
198+ const defaultListId = settings . defaultPromptListId || settings . promptLists [ 0 ] . id
199+ setAutoQuestionListId ( defaultListId )
200+ console . log ( 'ChatWindow 自动设置 defaultListId:' , defaultListId )
201+ }
202+ } ,
203+ [ settings . promptLists , settings . defaultPromptListId ]
204+ )
183205
184206 if ( ! chat ) {
185207 return < div className = "chat-window-error" > 聊天不存在</ div >
0 commit comments