From d68aafea15dcb8643627dc99971ca026cf7625b6 Mon Sep 17 00:00:00 2001 From: one Date: Fri, 12 Sep 2025 09:30:47 +0800 Subject: [PATCH] fix: infinite loops in KnowledgeBaseButton and MentionModelsButton (#10118) --- src/renderer/src/components/QuickPanel/provider.tsx | 4 ++-- src/renderer/src/components/QuickPanel/types.ts | 5 +---- src/renderer/src/components/QuickPanel/view.tsx | 10 ++++------ .../src/pages/home/Inputbar/KnowledgeBaseButton.tsx | 6 +++--- .../src/pages/home/Inputbar/MentionModelsButton.tsx | 13 ++++++------- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/renderer/src/components/QuickPanel/provider.tsx b/src/renderer/src/components/QuickPanel/provider.tsx index 85224e7a39..57eae70ef2 100644 --- a/src/renderer/src/components/QuickPanel/provider.tsx +++ b/src/renderer/src/components/QuickPanel/provider.tsx @@ -61,7 +61,7 @@ export const QuickPanelProvider: React.FC = ({ 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 = ({ children setTriggerInfo(undefined) }, 200) }, - [onClose, symbol, triggerInfo] + [onClose] ) useEffect(() => { diff --git a/src/renderer/src/components/QuickPanel/types.ts b/src/renderer/src/components/QuickPanel/types.ts index 030eb6f1f4..97e072dea0 100644 --- a/src/renderer/src/components/QuickPanel/types.ts +++ b/src/renderer/src/components/QuickPanel/types.ts @@ -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 = { diff --git a/src/renderer/src/components/QuickPanel/view.tsx b/src/renderer/src/components/QuickPanel/view.tsx index 08878b8478..30955f96f3 100644 --- a/src/renderer/src/components/QuickPanel/view.tsx +++ b/src/renderer/src/components/QuickPanel/view.tsx @@ -222,11 +222,10 @@ export const QuickPanelView: React.FC = ({ 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 = ({ setInputText }) => { } const quickPanelCallBackOptions: QuickPanelCallBackOptions = { - symbol: ctx.symbol, + context: ctx, action, item, - searchText: searchText, - multiple: ctx.multiple + searchText: searchText } ctx.beforeAction?.(quickPanelCallBackOptions) diff --git a/src/renderer/src/pages/home/Inputbar/KnowledgeBaseButton.tsx b/src/renderer/src/pages/home/Inputbar/KnowledgeBaseButton.tsx index d183114658..bdb1a45353 100644 --- a/src/renderer/src/pages/home/Inputbar/KnowledgeBaseButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/KnowledgeBaseButton.tsx @@ -64,14 +64,14 @@ const KnowledgeBaseButton: FC = ({ ref, selectedBases, onSelect, disabled description: t('settings.input.clear.knowledge_base'), icon: , 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({ diff --git a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx index 26d94f250d..b252de981d 100644 --- a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx @@ -202,7 +202,7 @@ const MentionModelsButton: FC = ({ icon: , alwaysVisible: true, isSelected: false, - action: () => { + action: ({ context: ctx }) => { onClearMentionModels() // 只有输入触发时才需要删除 @ 与搜索文本(未知搜索词,按光标就近删除) @@ -214,7 +214,7 @@ const MentionModelsButton: FC = ({ }) } - quickPanel.close() + ctx.close() } }) @@ -227,7 +227,6 @@ const MentionModelsButton: FC = ({ mentionedModels, onMentionModel, navigate, - quickPanel, onClearMentionModels, setText, removeAtSymbolAndText @@ -249,20 +248,20 @@ const MentionModelsButton: FC = ({ 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!) }) } }