Skip to content

Commit 110c8ba

Browse files
committed
fix: Handle multiple dragged tabs correctly in ChatTextArea
1 parent dba7112 commit 110c8ba

File tree

1 file changed

+40
-18
lines changed

1 file changed

+40
-18
lines changed

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -756,28 +756,50 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
756756
}
757757
})
758758

759+
// --- 必须严格修改此 useEffect 以处理多个插入 --- (根据规划重写)
759760
useEffect(() => {
760-
if (pendingInsertions.length === 0 || !textAreaRef.current) {
761-
return
762-
}
763-
764-
const path = pendingInsertions[0]
765-
const currentTextArea = textAreaRef.current
766-
const currentValue = currentTextArea.value
767-
const currentCursorPos =
768-
intendedCursorPosition ??
769-
(currentTextArea.selectionStart >= 0 ? currentTextArea.selectionStart : currentValue.length)
770-
771-
const mentionTextToInsert = path + " "
772-
const { newValue, mentionIndex } = insertMention(currentValue, currentCursorPos, mentionTextToInsert)
773-
const newCursorPosition = mentionIndex + mentionTextToInsert.length // 声明移到 useEffect 内部
761+
// 确保 textAreaRef.current 存在且 pendingInsertions 有内容
762+
if (pendingInsertions.length > 0 && textAreaRef.current) {
763+
const currentTextArea = textAreaRef.current // 引用当前文本区域
764+
// 将所有待插入路径用空格连接成一个字符串
765+
const textToInsert = pendingInsertions.join(" ")
766+
// 获取当前光标位置,若无则取输入值末尾
767+
const currentCursorPos = currentTextArea.selectionStart ?? inputValue.length
768+
// 确定插入起始位置:优先使用记录的拖放初始位置,否则使用当前光标位置
769+
const startPos = intendedCursorPosition ?? currentCursorPos
770+
771+
// 构建插入后的新输入值
772+
const newValue =
773+
inputValue.substring(0, startPos) + // 插入点之前的部分
774+
textToInsert + // 要插入的所有路径字符串
775+
" " + // 在所有路径后追加一个空格,以便继续输入
776+
inputValue.substring(startPos) // 插入点之后的部分
777+
778+
// 调用回调函数更新父组件或全局状态中的输入值
779+
// 注意:这里直接调用 setInputValue,因为它是 props 传入的 state setter
780+
setInputValue(newValue)
781+
// 一次性清空待插入项数组
782+
setPendingInsertions([])
774783

775-
setInputValue(newValue)
784+
// 计算插入后的新光标位置(位于插入内容和末尾空格之后)
785+
const newCursorPos = startPos + textToInsert.length + 1 // +1 是因为加了空格
776786

777-
setIntendedCursorPosition(newCursorPosition)
787+
// 使用 requestAnimationFrame 确保在 DOM 更新后设置光标和焦点
788+
requestAnimationFrame(() => {
789+
if (textAreaRef.current) {
790+
textAreaRef.current.selectionStart = newCursorPos
791+
textAreaRef.current.selectionEnd = newCursorPos
792+
// 确保文本区域获得焦点,以便用户可以立即输入
793+
textAreaRef.current.focus()
794+
}
795+
})
778796

779-
setPendingInsertions((prev) => prev.slice(1))
780-
}, [pendingInsertions, setInputValue, intendedCursorPosition])
797+
// 重置记录的初始光标位置
798+
setIntendedCursorPosition(null)
799+
}
800+
// 依赖项数组:当这些值变化时,此 effect 会重新运行
801+
// 需要包含所有在 effect 内部使用的、可能变化的外部变量/状态/回调
802+
}, [pendingInsertions, inputValue, setInputValue, intendedCursorPosition, setIntendedCursorPosition]) // 确保依赖项完整
781803

782804
const placeholderBottomText = `\n(${t("chat:addContext")}${shouldDisableImages ? `, ${t("chat:dragFiles")}` : `, ${t("chat:dragFilesImages")}`})`
783805

0 commit comments

Comments
 (0)