Merge branch 'main' of github.com:CherryHQ/cherry-studio

This commit is contained in:
fullex 2025-09-14 23:57:57 +08:00
commit 95ed17aa69
2 changed files with 50 additions and 30 deletions

View File

@ -341,11 +341,12 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
scrollTriggerRef.current = 'none'
}, [index])
// 处理键盘事件(折叠时不拦截全局键盘)
// 处理键盘事件:
// - 可见且未折叠时:拦截 Enter 及其组合键(纯 Enter 选择项;带修饰键仅拦截不处理)。
// - 软隐藏/折叠时:不拦截 Enter允许输入框处理用于发送消息等
// - 不可见时:不拦截,输入框按常规处理。
useEffect(() => {
const hasSearchTextFlag = searchText.replace(/^[/@]/, '').length > 0
const isCollapsed = hasSearchTextFlag && list.length === 0
if (!ctx.isVisible || isCollapsed) return
if (!ctx.isVisible) return
const handleKeyDown = (e: KeyboardEvent) => {
if (isMac ? e.metaKey : e.ctrlKey) {
@ -438,9 +439,24 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
break
case 'Enter':
case 'NumpadEnter':
case 'NumpadEnter': {
if (isComposing.current) return
// 折叠/软隐藏时不拦截,让输入框处理(用于发送消息)
const hasSearch = searchText.replace(/^[/@]/, '').length > 0
const nonPinnedCount = list.filter((i) => !i.alwaysVisible).length
const isCollapsed = hasSearch && nonPinnedCount === 0
if (isCollapsed) return
// 面板可见且未折叠时:拦截所有 Enter 变体;
// 纯 Enter 选择项,带修饰键仅拦截不处理
if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) {
e.preventDefault()
e.stopPropagation()
setIsMouseOver(false)
break
}
if (list?.[index]) {
e.preventDefault()
e.stopPropagation()
@ -451,6 +467,7 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
handleClose('enter_empty')
}
break
}
case 'Escape':
e.stopPropagation()
handleClose('esc')

View File

@ -406,37 +406,40 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
//other keys should be ignored
const isEnterPressed = event.key === 'Enter' && !event.nativeEvent.isComposing
if (isEnterPressed) {
if (quickPanel.isVisible) return event.preventDefault()
// 1) 优先判断是否为“发送”(当前仅支持纯 Enter 发送;其余 Enter 组合键均换行)
if (isSendMessageKeyPressed(event, sendMessageShortcut)) {
sendMessage()
return event.preventDefault()
} else {
//shift+enter's default behavior is to add a new line, ignore it
if (!event.shiftKey) {
event.preventDefault()
}
const textArea = textareaRef.current?.resizableTextArea?.textArea
if (textArea) {
const start = textArea.selectionStart
const end = textArea.selectionEnd
const text = textArea.value
const newText = text.substring(0, start) + '\n' + text.substring(end)
// 2) 不再基于 quickPanel.isVisible 主动拦截。
// 纯 Enter 的处理权交由 QuickPanel 的全局捕获(其只在纯 Enter 时拦截),
// 其它带修饰键的 Enter 则由输入框处理为换行。
// update text by setState, not directly modify textarea.value
setText(newText)
if (event.shiftKey) {
return
}
// set cursor position in the next render cycle
setTimeoutTimer(
'handleKeyDown',
() => {
textArea.selectionStart = textArea.selectionEnd = start + 1
onInput() // trigger resizeTextArea
},
0
)
}
}
event.preventDefault()
const textArea = textareaRef.current?.resizableTextArea?.textArea
if (textArea) {
const start = textArea.selectionStart
const end = textArea.selectionEnd
const text = textArea.value
const newText = text.substring(0, start) + '\n' + text.substring(end)
// update text by setState, not directly modify textarea.value
setText(newText)
// set cursor position in the next render cycle
setTimeoutTimer(
'handleKeyDown',
() => {
textArea.selectionStart = textArea.selectionEnd = start + 1
onInput() // trigger resizeTextArea
},
0
)
}
}