fix: infinite loops in KnowledgeBaseButton and MentionModelsButton (#10118)

This commit is contained in:
one 2025-09-12 09:30:47 +08:00 committed by GitHub
parent e093ae72da
commit d68aafea15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 16 additions and 22 deletions

View File

@ -61,7 +61,7 @@ export const QuickPanelProvider: React.FC<React.PropsWithChildren> = ({ children
const close = useCallback(
(action?: QuickPanelCloseAction, searchText?: string) => {
setIsVisible(false)
onClose?.({ symbol, action, triggerInfo, searchText, item: {} as QuickPanelListItem, multiple: false })
onClose?.({ action, searchText, item: {} as QuickPanelListItem, context: this })
clearTimer.current = setTimeout(() => {
setList([])
@ -73,7 +73,7 @@ export const QuickPanelProvider: React.FC<React.PropsWithChildren> = ({ children
setTriggerInfo(undefined)
}, 200)
},
[onClose, symbol, triggerInfo]
[onClose]
)
useEffect(() => {

View File

@ -8,13 +8,10 @@ export type QuickPanelTriggerInfo = {
}
export type QuickPanelCallBackOptions = {
symbol: string
context: QuickPanelContextType
action: QuickPanelCloseAction
item: QuickPanelListItem
searchText?: string
/** 是否处于多选状态 */
multiple?: boolean
triggerInfo?: QuickPanelTriggerInfo
}
export type QuickPanelOpenOptions = {

View File

@ -222,11 +222,10 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
// 创建更新后的item对象用于回调
const updatedItem = { ...item, isSelected: newSelectedState }
const quickPanelCallBackOptions: QuickPanelCallBackOptions = {
symbol: ctx.symbol,
context: ctx,
action,
item: updatedItem,
searchText: searchText,
multiple: ctx.multiple
searchText: searchText
}
ctx.beforeAction?.(quickPanelCallBackOptions)
@ -236,11 +235,10 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
}
const quickPanelCallBackOptions: QuickPanelCallBackOptions = {
symbol: ctx.symbol,
context: ctx,
action,
item,
searchText: searchText,
multiple: ctx.multiple
searchText: searchText
}
ctx.beforeAction?.(quickPanelCallBackOptions)

View File

@ -64,14 +64,14 @@ const KnowledgeBaseButton: FC<Props> = ({ ref, selectedBases, onSelect, disabled
description: t('settings.input.clear.knowledge_base'),
icon: <CircleX />,
isSelected: false,
action: () => {
action: ({ context: ctx }) => {
onSelect([])
quickPanel.close()
ctx.close()
}
})
return items
}, [knowledgeState.bases, t, selectedBases, handleBaseSelect, navigate, onSelect, quickPanel])
}, [knowledgeState.bases, t, selectedBases, handleBaseSelect, navigate, onSelect])
const openQuickPanel = useCallback(() => {
quickPanel.open({

View File

@ -202,7 +202,7 @@ const MentionModelsButton: FC<Props> = ({
icon: <CircleX />,
alwaysVisible: true,
isSelected: false,
action: () => {
action: ({ context: ctx }) => {
onClearMentionModels()
// 只有输入触发时才需要删除 @ 与搜索文本(未知搜索词,按光标就近删除)
@ -214,7 +214,7 @@ const MentionModelsButton: FC<Props> = ({
})
}
quickPanel.close()
ctx.close()
}
})
@ -227,7 +227,6 @@ const MentionModelsButton: FC<Props> = ({
mentionedModels,
onMentionModel,
navigate,
quickPanel,
onClearMentionModels,
setText,
removeAtSymbolAndText
@ -249,20 +248,20 @@ const MentionModelsButton: FC<Props> = ({
afterAction({ item }) {
item.isSelected = !item.isSelected
},
onClose({ action, triggerInfo: closeTriggerInfo, searchText }) {
onClose({ action, searchText, context: ctx }) {
// ESC关闭时的处理删除 @ 和搜索文本
if (action === 'esc') {
// 只有在输入触发且有模型选择动作时才删除@字符和搜索文本
if (
hasModelActionRef.current &&
closeTriggerInfo?.type === 'input' &&
closeTriggerInfo?.position !== undefined
ctx.triggerInfo?.type === 'input' &&
ctx.triggerInfo?.position !== undefined
) {
// 基于当前光标 + 搜索词精确定位并删除position 仅作兜底
setText((currentText) => {
const textArea = document.querySelector('.inputbar textarea') as HTMLTextAreaElement | null
const caret = textArea ? (textArea.selectionStart ?? currentText.length) : currentText.length
return removeAtSymbolAndText(currentText, caret, searchText || '', closeTriggerInfo.position!)
return removeAtSymbolAndText(currentText, caret, searchText || '', ctx.triggerInfo?.position!)
})
}
}